Handle is4 bytes without meaningful information in the bottom bits
authorH. Peter Anvin <hpa@zytor.com>
Wed, 21 May 2008 02:29:04 +0000 (19:29 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Wed, 21 May 2008 02:29:04 +0000 (19:29 -0700)
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.

assemble.c
disasm.c
insns.pl
test/avx.asm

index 1d440ea..c5f8172 100644 (file)
  *                 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:
index 378596a..c3ae541 100644 (file)
--- 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):
index 5b45d7e..8199732 100644 (file)
--- 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;
index 018135b..11d3f1e 100644 (file)
@@ -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