summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-05-20 19:29:04 -0700
committerH. Peter Anvin <hpa@zytor.com>2008-05-20 19:29:04 -0700
commit52dc353868a9adba69df6bd72a30ab1eaff4388e (patch)
tree48153812545ca19cb44dad9f6b3f0b381f9fcacc
parent21513e822f64a79dfc651da7e94408d97d985db6 (diff)
downloadnasm-52dc353868a9adba69df6bd72a30ab1eaff4388e.tar.gz
nasm-52dc353868a9adba69df6bd72a30ab1eaff4388e.tar.bz2
nasm-52dc353868a9adba69df6bd72a30ab1eaff4388e.zip
Handle is4 bytes without meaningful information in the bottom bits
Support is4 bytes without meaningful information in the bottom bits. This is equivalent to /is4=0 for the assembler, but makes the bottom bits don't care for the disassembler.
-rw-r--r--assemble.c15
-rw-r--r--disasm.c10
-rw-r--r--insns.pl10
-rw-r--r--test/avx.asm10
4 files changed, 40 insertions, 5 deletions
diff --git a/assemble.c b/assemble.c
index 1d440ea..c5f8172 100644
--- a/assemble.c
+++ b/assemble.c
@@ -46,9 +46,11 @@
* operand 0..3.
* \171 - placement of DREX suffix in the absence of an EA
* \172\ab - the register number from operand a in bits 7..4, with
- * the 4-bit immediate from operand b in bits 0..3.
+ * the 4-bit immediate from operand b in bits 3..0.
* \173\xab - the register number from operand a in bits 7..4, with
- * the value b in bits 0..3.
+ * the value b in bits 3..0.
+ * \174\a - the register number from operand a in bits 7..4, and
+ * an arbitrary value in bits 3..0 (assembled as zero.)
* \2ab - a ModRM, calculated on EA in operand a, with the spare
* field equal to digit b.
* \250..\253 - same as \150..\153, except warn if the 64-bit operand
@@ -1006,6 +1008,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
break;
case 0172:
case 0173:
+ case 0174:
codes++;
length++;
break;
@@ -1611,6 +1614,14 @@ static void gencode(int32_t segment, int64_t offset, int bits,
offset++;
break;
+ case 0174:
+ c = *codes++;
+ opx = &ins->oprs[c];
+ bytes[0] = nasm_regvals[opx->basereg] << 4;
+ out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
+ offset++;
+ break;
+
case 0250:
case 0251:
case 0252:
diff --git a/disasm.c b/disasm.c
index 378596a..c3ae541 100644
--- a/disasm.c
+++ b/disasm.c
@@ -656,6 +656,16 @@ static int matches(const struct itemplate *t, uint8_t *data,
}
break;
+ case 0174:
+ {
+ uint8_t ximm = *data++;
+ c = *r++;
+
+ ins->oprs[c].basereg = ximm >> 4;
+ ins->oprs[c].segment |= SEG_RMREG;
+ }
+ break;
+
case4(0200):
case4(0204):
case4(0210):
diff --git a/insns.pl b/insns.pl
index 5b45d7e..8199732 100644
--- a/insns.pl
+++ b/insns.pl
@@ -687,10 +687,14 @@ sub byte_code_compile($) {
}
$prefix_ok = 0;
} elsif ($op eq '/is4') {
- if (!defined($oppos{'i'} || !defined($oppos{'s'}))) {
- die "$0: $line: $op without 'i' and 's' operands\n";
+ if (!defined($oppos{'s'})) {
+ die "$0: $line: $op without 's' operand\n";
+ }
+ if (defined($oppos{'i'})) {
+ push(@codes, 0172, ($oppos{'s'} << 3)+$oppos{'i'});
+ } else {
+ push(@codes, 0174, $oppos{'s'});
}
- push(@codes, 0172, ($oppos{'s'} << 3)+$oppos{'i'});
$prefix_ok = 0;
} elsif ($op =~ /^\/is4\=([0-9]+)$/) {
my $imm = $1;
diff --git a/test/avx.asm b/test/avx.asm
index 018135b..11d3f1e 100644
--- a/test/avx.asm
+++ b/test/avx.asm
@@ -1,4 +1,14 @@
bits 64
+ vblendvpd xmm2,xmm1,xmm0,xmm0
+ vblendvpd xmm2,xmm1,xmm0
+ vblendvpd ymm2,ymm1,ymm0,ymm0
+ vblendvpd ymm2,ymm1,ymm0
+
+ vcvtsi2sd xmm9,xmm10,ecx
+ vcvtsi2sd xmm9,xmm10,rcx
+ vcvtsi2sd xmm9,xmm10,dword [rdi]
+ vcvtsi2sd xmm9,xmm10,qword [rdi]
+
vpermil2ps xmm0,xmm1,[rdi],xmm3,0
vpermil2ps xmm0,xmm1,xmm2,[rdi],1
vpermil2ps ymm0,ymm1,ymm2,ymm3,2