Correctly identify SBYTE in the optimizer
authorH. Peter Anvin <hpa@zytor.com>
Fri, 4 Apr 2008 20:34:53 +0000 (13:34 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Fri, 4 Apr 2008 20:34:53 +0000 (13:34 -0700)
Correctly identify SBYTE in the optimizer, *HOWEVER*, this change will
cause nuisance warnings to be issued; that will have to be fixed.

assemble.c
insns.dat
insns.h
nasm.h
parser.c

index 681af69..60fe369 100644 (file)
@@ -37,7 +37,7 @@
  *                 is a signed byte rather than a word.  Opcode byte follows.
  * \150..\153     - an immediate dword or signed byte for operand 0..3
  * \154..\157    - or 2 (s-field) into opcode byte if operand 0..3
- *                 is a signed byte rather than a word.  Opcode byte follows.
+ *                 is a signed byte rather than a dword.  Opcode byte follows.
  * \160..\163    - this instruction uses DREX rather than REX, with the
  *                OC0 field set to 0, and the dest field taken from
  *                 operand 0..3.
@@ -50,6 +50,9 @@
  * \171                 - placement of DREX suffix in the absence of an EA
  * \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
+ *                 is not equal to the truncated and sign-extended 32-bit
+ *                 operand; used for 32-bit immediates in 64-bit mode.
  * \310          - indicates fixed 16-bit address size, i.e. optional 0x67.
  * \311          - indicates fixed 32-bit address size, i.e. optional 0x67.
  * \312          - (disassembler only) marker on LOOP, LOOPxx instructions.
@@ -159,7 +162,8 @@ static void warn_overflow(int size, int64_t data)
        int64_t lim = ((int64_t)1 << (size*8))-1;
 
        if (data < ~lim || data > lim)
-           errfunc(ERR_WARNING | ERR_WARN_NOV, "%s data exceeds bounds", size_name(size));
+           errfunc(ERR_WARNING | ERR_WARN_NOV,
+                   "%s data exceeds bounds", size_name(size));
     }
 }
 /*
@@ -756,25 +760,55 @@ int64_t insn_size(int32_t segment, int64_t offset, int bits, uint32_t cp,
     return -1;                  /* didn't match any instruction */
 }
 
-/* check that  opn[op]  is a signed byte of size 16 or 32,
-                                       and return the signed value*/
-static int is_sbyte(insn * ins, int op, int size)
+static bool possible_sbyte(insn * ins, int op)
 {
-    int32_t v;
-    int ret;
-
-    ret = !(ins->forw_ref && ins->oprs[op].opflags) &&  /* dead in the water on forward reference or External */
+    return !(ins->forw_ref && ins->oprs[op].opflags) &&
         optimizing >= 0 &&
         !(ins->oprs[op].type & STRICT) &&
         ins->oprs[op].wrt == NO_SEG && ins->oprs[op].segment == NO_SEG;
+}
+
+/* check that opn[op]  is a signed byte of size 16 or 32 */
+static bool is_sbyte16(insn * ins, int op)
+{
+    int16_t v;
+
+    if (!possible_sbyte(ins, op))
+       return false;
 
     v = ins->oprs[op].offset;
-    if (size == 16)
-        v = (int16_t)v;    /* sign extend if 16 bits */
+    return v >= -128 && v <= 127;
+}
 
-    return ret && v >= -128L && v <= 127L;
+static bool is_sbyte32(insn * ins, int op)
+{
+    int32_t v;
+
+    if (!possible_sbyte(ins, op))
+       return false;
+
+    v = ins->oprs[op].offset;
+    return v >= -128 && v <= 127;
 }
 
+/* check that  opn[op]  is a signed byte of size 32; warn if this is not
+   the original value when extended to 64 bits */
+static bool is_sbyte64(insn * ins, int op)
+{
+    int64_t v64;
+    int32_t v32;
+
+    /* dead in the water on forward reference or External */
+    if (!possible_sbyte(ins, op))
+       return false;
+
+    v64 = ins->oprs[op].offset;
+    v32 = (int32_t)v64;
+
+    warn_overflow(32, v64);
+
+    return v32 >= -128 && v32 <= 127;
+}
 static int64_t calcsize(int32_t segment, int64_t offset, int bits,
                      insn * ins, const char *codes)
 {
@@ -902,7 +936,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
         case 0141:
         case 0142:
        case 0143:
-            length += is_sbyte(ins, c & 3, 16) ? 1 : 2;
+            length += is_sbyte16(ins, c & 3) ? 1 : 2;
             break;
         case 0144:
         case 0145:
@@ -915,7 +949,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
         case 0151:
         case 0152:
         case 0153:
-            length += is_sbyte(ins, c & 3, 32) ? 1 : 4;
+            length += is_sbyte32(ins, c & 3) ? 1 : 4;
             break;
         case 0154:
         case 0155:
@@ -945,6 +979,12 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
             break;
        case 0171:
            break;
+        case 0250:
+        case 0251:
+        case 0252:
+        case 0253:
+            length += is_sbyte64(ins, c & 3) ? 1 : 4;
+            break;
         case 0300:
         case 0301:
         case 0302:
@@ -1174,6 +1214,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
         case 015:
         case 016:
        case 017:
+           /* XXX: warns for legitimate optimizer actions */
             if (opx->offset < -128 || opx->offset > 127) {
                 errfunc(ERR_WARNING | ERR_WARN_NOV,
                        "signed byte value exceeds bounds");
@@ -1383,7 +1424,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
         case 0142:
        case 0143:
             data = opx->offset;
-            if (is_sbyte(ins, c & 3, 16)) {
+            if (is_sbyte16(ins, c & 3)) {
                 bytes[0] = data;
                 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
                     NO_SEG);
@@ -1404,7 +1445,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
        case 0147:
            EMIT_REX();
             bytes[0] = *codes++;
-            if (is_sbyte(ins, c & 3, 16))
+            if (is_sbyte16(ins, c & 3))
                 bytes[0] |= 2;  /* s-bit */
             out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
             offset++;
@@ -1415,7 +1456,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
         case 0152:
        case 0153:
             data = opx->offset;
-            if (is_sbyte(ins, c & 3, 32)) {
+            if (is_sbyte32(ins, c & 3)) {
                 bytes[0] = data;
                 out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
                     NO_SEG);
@@ -1433,7 +1474,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
        case 0157:
            EMIT_REX();
             bytes[0] = *codes++;
-            if (is_sbyte(ins, c & 3, 32))
+            if (is_sbyte32(ins, c & 3))
                 bytes[0] |= 2;  /* s-bit */
             out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
             offset++;
@@ -1466,6 +1507,24 @@ static void gencode(int32_t segment, int64_t offset, int bits,
            offset++;
            break;
 
+        case 0250:
+        case 0251:
+        case 0252:
+       case 0253:
+            data = opx->offset;
+           /* is_sbyte32() is right here, we have already warned */
+            if (is_sbyte32(ins, c & 3)) {
+                bytes[0] = data;
+                out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
+                    NO_SEG);
+                offset++;
+            } else {
+                out(offset, segment, &data, OUT_ADDRESS, 4,
+                    opx->segment, opx->wrt);
+                offset += 4;
+            }
+            break;
+
         case 0300:
         case 0301:
         case 0302:
@@ -1744,47 +1803,13 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
             return 0;
 
     /*
-     * Check that the operand flags all match up
-     */
-    for (i = 0; i < itemp->operands; i++) {
-       if (itemp->opd[i] & SAME_AS) {
-           int j = itemp->opd[i] & ~SAME_AS;
-           if (instruction->oprs[i].type != instruction->oprs[j].type ||
-               instruction->oprs[i].basereg != instruction->oprs[j].basereg)
-               return 0;
-       } else  if (itemp->opd[i] & ~instruction->oprs[i].type ||
-            ((itemp->opd[i] & SIZE_MASK) &&
-             ((itemp->opd[i] ^ instruction->oprs[i].type) & SIZE_MASK))) {
-            if ((itemp->opd[i] & ~instruction->oprs[i].type & ~SIZE_MASK) ||
-                (instruction->oprs[i].type & SIZE_MASK))
-                return 0;
-            else
-                return 1;
-        }
-    }
-
-    /*
-     * Check operand sizes
+     * Process size flags
      */
     if (itemp->flags & IF_ARMASK) {
        memset(size, 0, sizeof size);
 
-        switch (itemp->flags & IF_ARMASK) {
-        case IF_AR0:
-            i = 0;
-            break;
-        case IF_AR1:
-            i = 1;
-            break;
-        case IF_AR2:
-            i = 2;
-            break;
-       case IF_AR3:
-           i = 3;
-           break;
-        default:
-            break;              /* Shouldn't happen */
-        }
+       i = ((itemp->flags & IF_ARMASK) >> IF_ARSHFT) - 1;
+
        switch (itemp->flags & IF_SMASK) {
        case IF_SB:
             size[i] = BITS8;
@@ -1801,6 +1826,19 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
        case IF_SO:
            size[i] = BITS128;
            break;
+       case IF_SZ:
+           switch (bits) {
+           case 16:
+               size[i] = BITS16;
+               break;
+           case 32:
+               size[i] = BITS32;
+               break;
+           case 64:
+               size[i] = BITS64;
+               break;
+           }
+           break;
        default:
            break;
         }
@@ -1809,23 +1847,31 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
        switch (itemp->flags & IF_SMASK) {
        case IF_SB:
             asize = BITS8;
-            oprs = itemp->operands;
            break;
        case IF_SW:
             asize = BITS16;
-            oprs = itemp->operands;
            break;
        case IF_SD:
             asize = BITS32;
-            oprs = itemp->operands;
            break;
        case IF_SQ:
             asize = BITS64;
-            oprs = itemp->operands;
            break;
        case IF_SO:
             asize = BITS128;
-            oprs = itemp->operands;
+           break;
+       case IF_SZ:
+           switch (bits) {
+           case 16:
+               asize = BITS16;
+               break;
+           case 32:
+               asize = BITS32;
+               break;
+           case 64:
+               asize = BITS64;
+               break;
+           }
            break;
        default:
            break;
@@ -1834,6 +1880,33 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
            size[i] = asize;
     }
 
+    /*
+     * Check that the operand flags all match up
+     */
+    for (i = 0; i < itemp->operands; i++) {
+       int32_t type = instruction->oprs[i].type;
+       if (!(type & SIZE_MASK))
+           type |= size[i];
+           
+       if (itemp->opd[i] & SAME_AS) {
+           int j = itemp->opd[i] & ~SAME_AS;
+           if (type != instruction->oprs[j].type ||
+               instruction->oprs[i].basereg != instruction->oprs[j].basereg)
+               return 0;
+       } else if (itemp->opd[i] & ~type ||
+            ((itemp->opd[i] & SIZE_MASK) &&
+             ((itemp->opd[i] ^ type) & SIZE_MASK))) {
+            if ((itemp->opd[i] & ~type & ~SIZE_MASK) ||
+                (type & SIZE_MASK))
+                return 0;
+            else
+                return 1;
+        }
+    }
+
+    /*
+     * Check operand sizes
+     */
     if (itemp->flags & (IF_SM | IF_SM2)) {
         oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands);
         asize = 0;
index 457315e..2302703 100644 (file)
--- a/insns.dat
+++ b/insns.dat
@@ -59,16 +59,16 @@ ADC         rm16,imm8               \320\1\x83\202\15               8086
 ADC            rm32,imm8               \321\1\x83\202\15               386
 ADC            rm64,imm8               \324\1\x83\202\15               X64
 ADC            reg_al,imm              \1\x14\21                       8086,SM
-ADC            reg_ax,sbyte            \320\1\x83\202\15               8086,SM,ND
+ADC            reg_ax,sbyte16          \320\1\x83\202\15               8086,SM,ND
 ADC            reg_ax,imm              \320\1\x15\31                   8086,SM
-ADC            reg_eax,sbyte           \321\1\x83\202\15               386,SM,ND
+ADC            reg_eax,sbyte32         \321\1\x83\202\15               386,SM,ND
 ADC            reg_eax,imm             \321\1\x15\41                   386,SM
-ADC            reg_rax,sbyte           \324\1\x83\202\15               X64,SM,ND
+ADC            reg_rax,sbyte64         \324\1\x83\202\15               X64,SM,ND
 ADC            reg_rax,imm             \324\1\x15\41                   X64,SM
 ADC            rm8,imm                 \1\x80\202\21                   8086,SM
 ADC            rm16,imm                \320\145\x81\202\141            8086,SM
 ADC            rm32,imm                \321\155\x81\202\151            386,SM
-ADC            rm64,imm                \324\155\x81\202\151            X64,SM
+ADC            rm64,imm                \324\155\x81\202\251            X64,SM
 ADC            mem,imm8                \1\x80\202\21                   8086,SM
 ADC            mem,imm16               \320\145\x81\202\141            8086,SM
 ADC            mem,imm32               \321\155\x81\202\151            386,SM
@@ -92,16 +92,16 @@ ADD         rm16,imm8               \320\1\x83\200\15               8086
 ADD            rm32,imm8               \321\1\x83\200\15               386
 ADD            rm64,imm8               \324\1\x83\200\15               X64
 ADD            reg_al,imm              \1\x04\21                       8086,SM
-ADD            reg_ax,sbyte            \320\1\x83\200\15               8086,SM,ND
+ADD            reg_ax,sbyte16          \320\1\x83\200\15               8086,SM,ND
 ADD            reg_ax,imm              \320\1\x05\31                   8086,SM
-ADD            reg_eax,sbyte           \321\1\x83\200\15               386,SM,ND
+ADD            reg_eax,sbyte32         \321\1\x83\200\15               386,SM,ND
 ADD            reg_eax,imm             \321\1\x05\41                   386,SM
-ADD            reg_rax,sbyte           \324\1\x83\200\15               X64,SM,ND
+ADD            reg_rax,sbyte64         \324\1\x83\200\15               X64,SM,ND
 ADD            reg_rax,imm             \324\1\x05\41                   X64,SM
 ADD            rm8,imm                 \1\x80\200\21                   8086,SM
 ADD            rm16,imm                \320\145\x81\200\141            8086,SM
 ADD            rm32,imm                \321\155\x81\200\151            386,SM
-ADD            rm64,imm                \324\155\x81\200\151            X64,SM
+ADD            rm64,imm                \324\155\x81\200\251            X64,SM
 ADD            mem,imm8                \1\x80\200\21                   8086,SM
 ADD            mem,imm16               \320\145\x81\200\141            8086,SM
 ADD            mem,imm32               \321\155\x81\200\151            386,SM
@@ -125,16 +125,16 @@ AND               rm16,imm8               \320\1\x83\204\15               8086
 AND            rm32,imm8               \321\1\x83\204\15               386
 AND            rm64,imm8               \324\1\x83\204\15               X64
 AND            reg_al,imm              \1\x24\21                       8086,SM
-AND            reg_ax,sbyte            \320\1\x83\204\15               8086,SM,ND
+AND            reg_ax,sbyte16          \320\1\x83\204\15               8086,SM,ND
 AND            reg_ax,imm              \320\1\x25\31                   8086,SM
-AND            reg_eax,sbyte           \321\1\x83\204\15               386,SM,ND
+AND            reg_eax,sbyte32         \321\1\x83\204\15               386,SM,ND
 AND            reg_eax,imm             \321\1\x25\41                   386,SM
-AND            reg_rax,sbyte           \324\1\x83\204\15               X64,SM,ND
+AND            reg_rax,sbyte64         \324\1\x83\204\15               X64,SM,ND
 AND            reg_rax,imm             \324\1\x25\41                   X64,SM
 AND            rm8,imm                 \1\x80\204\21                   8086,SM
 AND            rm16,imm                \320\145\x81\204\141            8086,SM
 AND            rm32,imm                \321\155\x81\204\151            386,SM
-AND            rm64,imm                \324\155\x81\204\151            X64,SM
+AND            rm64,imm                \324\155\x81\204\251            X64,SM
 AND            mem,imm8                \1\x80\204\21                   8086,SM
 AND            mem,imm16               \320\145\x81\204\141            8086,SM
 AND            mem,imm32               \321\155\x81\204\151            386,SM
@@ -251,16 +251,16 @@ CMP               rm16,imm8               \320\1\x83\207\15               8086
 CMP            rm32,imm8               \321\1\x83\207\15               386
 CMP            rm64,imm8               \324\1\x83\207\15               X64
 CMP            reg_al,imm              \1\x3C\21                       8086,SM
-CMP            reg_ax,sbyte            \320\1\x83\207\15               8086,SM,ND
+CMP            reg_ax,sbyte16          \320\1\x83\207\15               8086,SM,ND
 CMP            reg_ax,imm              \320\1\x3D\31                   8086,SM
-CMP            reg_eax,sbyte           \321\1\x83\207\15               386,SM,ND
+CMP            reg_eax,sbyte32         \321\1\x83\207\15               386,SM,ND
 CMP            reg_eax,imm             \321\1\x3D\41                   386,SM
-CMP            reg_rax,sbyte           \324\1\x83\207\15               X64,SM,ND
+CMP            reg_rax,sbyte64         \324\1\x83\207\15               X64,SM,ND
 CMP            reg_rax,imm             \324\1\x3D\41                   X64,SM
 CMP            rm8,imm                 \1\x80\207\21                   8086,SM
 CMP            rm16,imm                \320\145\x81\207\141            8086,SM
 CMP            rm32,imm                \321\155\x81\207\151            386,SM
-CMP            rm64,imm                \324\155\x81\207\151            X64,SM
+CMP            rm64,imm                \324\155\x81\207\251            X64,SM
 CMP            mem,imm8                \1\x80\207\21                   8086,SM
 CMP            mem,imm16               \320\145\x81\207\141            8086,SM
 CMP            mem,imm32               \321\155\x81\207\151            386,SM
@@ -546,40 +546,40 @@ IMUL              reg32,reg32             \321\2\x0F\xAF\110              386
 IMUL           reg64,mem               \324\2\x0F\xAF\110              X64,SM
 IMUL           reg64,reg64             \324\2\x0F\xAF\110              X64
 IMUL           reg16,mem,imm8          \320\1\x6B\110\16               186,SM
-IMUL           reg16,mem,sbyte         \320\1\x6B\110\16               186,SM,ND
+IMUL           reg16,mem,sbyte16       \320\1\x6B\110\16               186,SM,ND
 IMUL           reg16,mem,imm16         \320\1\x69\110\32               186,SM
 IMUL           reg16,mem,imm           \320\146\x69\110\142            186,SM,ND
 IMUL           reg16,reg16,imm8        \320\1\x6B\110\16               186
-IMUL           reg16,reg16,sbyte       \320\1\x6B\110\16               186,SM,ND
+IMUL           reg16,reg16,sbyte32     \320\1\x6B\110\16               186,SM,ND
 IMUL           reg16,reg16,imm16       \320\1\x69\110\32               186
 IMUL           reg16,reg16,imm         \320\146\x69\110\142            186,SM,ND
 IMUL           reg32,mem,imm8          \321\1\x6B\110\16               386,SM
-IMUL           reg32,mem,sbyte         \321\1\x6B\110\16               386,SM,ND
+IMUL           reg32,mem,sbyte64       \321\1\x6B\110\16               386,SM,ND
 IMUL           reg32,mem,imm32         \321\1\x69\110\42               386,SM
 IMUL           reg32,mem,imm           \321\156\x69\110\152            386,SM,ND
 IMUL           reg32,reg32,imm8        \321\1\x6B\110\16               386
-IMUL           reg32,reg32,sbyte       \321\1\x6B\110\16               386,SM,ND
+IMUL           reg32,reg32,sbyte16     \321\1\x6B\110\16               386,SM,ND
 IMUL           reg32,reg32,imm32       \321\1\x69\110\42               386
 IMUL           reg32,reg32,imm         \321\156\x69\110\152            386,SM,ND
 IMUL           reg64,mem,imm8          \324\1\x6B\110\16               X64,SM
-IMUL           reg64,mem,sbyte         \324\1\x6B\110\16               X64,SM,ND
+IMUL           reg64,mem,sbyte32       \324\1\x6B\110\16               X64,SM,ND
 IMUL           reg64,mem,imm32         \324\1\x69\110\42               X64,SM
-IMUL           reg64,mem,imm           \324\156\x69\110\152            X64,SM,ND
+IMUL           reg64,mem,imm           \324\156\x69\110\252            X64,SM,ND
 IMUL           reg64,reg64,imm8        \324\1\x6B\110\16               X64
-IMUL           reg64,reg64,sbyte       \324\1\x6B\110\16               X64,SM,ND
+IMUL           reg64,reg64,sbyte64     \324\1\x6B\110\16               X64,SM,ND
 IMUL           reg64,reg64,imm32       \324\1\x69\110\42               X64
-IMUL           reg64,reg64,imm         \324\156\x69\110\152            X64,SM,ND
+IMUL           reg64,reg64,imm         \324\156\x69\110\252            X64,SM,ND
 IMUL           reg16,imm8              \320\1\x6B\100\15               186
-IMUL           reg16,sbyte             \320\1\x6B\100\15               186,SM,ND
+IMUL           reg16,sbyte16           \320\1\x6B\100\15               186,SM,ND
 IMUL           reg16,imm16             \320\1\x69\100\31               186
 IMUL           reg16,imm               \320\145\x69\100\141            186,SM,ND
 IMUL           reg32,imm8              \321\1\x6B\100\15               386
-IMUL           reg32,sbyte             \321\1\x6B\100\15               386,SM,ND
+IMUL           reg32,sbyte32           \321\1\x6B\100\15               386,SM,ND
 IMUL           reg32,imm32             \321\1\x69\100\41               386
 IMUL           reg32,imm               \321\155\x69\100\151            386,SM,ND
-IMUL           reg64,sbyte             \324\1\x6B\100\15               X64,SM,ND
+IMUL           reg64,sbyte64           \324\1\x6B\100\15               X64,SM,ND
 IMUL           reg64,imm32             \324\1\x69\100\41               X64
-IMUL           reg64,imm               \324\155\x69\100\151            X64,SM,ND
+IMUL           reg64,imm               \324\155\x69\100\251            X64,SM,ND
 IN             reg_al,imm              \1\xE4\25                       8086,SB
 IN             reg_ax,imm              \320\1\xE5\25                   8086,SB
 IN             reg_eax,imm             \321\1\xE5\25                   386,SB
@@ -849,16 +849,16 @@ OR                rm16,imm8               \320\1\x83\201\15               8086
 OR             rm32,imm8               \321\1\x83\201\15               386
 OR             rm64,imm8               \324\1\x83\201\15               X64
 OR             reg_al,imm              \1\x0C\21                       8086,SM
-OR             reg_ax,sbyte            \320\1\x83\201\15               8086,SM,ND
+OR             reg_ax,sbyte16          \320\1\x83\201\15               8086,SM,ND
 OR             reg_ax,imm              \320\1\x0D\31                   8086,SM
-OR             reg_eax,sbyte           \321\1\x83\201\15               386,SM,ND
+OR             reg_eax,sbyte32         \321\1\x83\201\15               386,SM,ND
 OR             reg_eax,imm             \321\1\x0D\41                   386,SM
-OR             reg_rax,sbyte           \324\1\x83\201\15               X64,SM,ND
+OR             reg_rax,sbyte64         \324\1\x83\201\15               X64,SM,ND
 OR             reg_rax,imm             \324\1\x0D\41                   X64,SM
 OR             rm8,imm                 \1\x80\201\21                   8086,SM
 OR             rm16,imm                \320\145\x81\201\141            8086,SM
 OR             rm32,imm                \321\155\x81\201\151            386,SM
-OR             rm64,imm                \324\155\x81\201\151            X64,SM
+OR             rm64,imm                \324\155\x81\201\251            X64,SM
 OR             mem,imm8                \1\x80\201\21                   8086,SM
 OR             mem,imm16               \320\145\x81\201\141            8086,SM
 OR             mem,imm32               \321\155\x81\201\151            386,SM
@@ -982,11 +982,10 @@ PUSH              reg_cs                  \6                              8086,NOLONG
 PUSH           reg_dess                \6                              8086,NOLONG
 PUSH           reg_fsgs                \1\x0F\7                        386
 PUSH           imm8                    \1\x6A\14                       186
-PUSH           sbyte                   \1\x6A\14                       186,ND
-PUSH           imm16                   \320\144\x68\140                186
-PUSH           imm32                   \321\154\x68\150                386,NOLONG
-PUSH           imm64                   \321\154\x68\150                X64
-PUSH           imm                     \1\x68\34                       186
+PUSH           imm16                   \320\144\x68\140                186,AR0,SZ
+PUSH           imm32                   \321\154\x68\150                386,NOLONG,AR0,SZ
+PUSH           imm32                   \321\154\x68\150                386,NOLONG,SD
+PUSH           imm64                   \323\154\x68\250                X64,AR0,SZ
 PUSHA          void                    \322\1\x60                      186,NOLONG
 PUSHAD         void                    \321\1\x60                      386,NOLONG
 PUSHAW         void                    \320\1\x60                      186,NOLONG
@@ -1105,16 +1104,16 @@ SBB             rm16,imm8               \320\1\x83\203\15               8086
 SBB            rm32,imm8               \321\1\x83\203\15               386
 SBB            rm64,imm8               \324\1\x83\203\15               X64
 SBB            reg_al,imm              \1\x1C\21                       8086,SM
-SBB            reg_ax,sbyte            \320\1\x83\203\15               8086,SM,ND
+SBB            reg_ax,sbyte16          \320\1\x83\203\15               8086,SM,ND
 SBB            reg_ax,imm              \320\1\x1D\31                   8086,SM
-SBB            reg_eax,sbyte           \321\1\x83\203\15               386,SM,ND
+SBB            reg_eax,sbyte32         \321\1\x83\203\15               386,SM,ND
 SBB            reg_eax,imm             \321\1\x1D\41                   386,SM
-SBB            reg_rax,sbyte           \324\1\x83\203\15               X64,SM,ND
+SBB            reg_rax,sbyte64         \324\1\x83\203\15               X64,SM,ND
 SBB            reg_rax,imm             \324\1\x1D\41                   X64,SM
 SBB            rm8,imm                 \1\x80\203\21                   8086,SM
 SBB            rm16,imm                \320\145\x81\203\141            8086,SM
 SBB            rm32,imm                \321\155\x81\203\151            386,SM
-SBB            rm64,imm                \324\155\x81\203\151            X64,SM
+SBB            rm64,imm                \324\155\x81\203\251            X64,SM
 SBB            mem,imm8                \1\x80\203\21                   8086,SM
 SBB            mem,imm16               \320\145\x81\203\141            8086,SM
 SBB            mem,imm32               \321\155\x81\203\151            386,SM
@@ -1219,16 +1218,16 @@ SUB             rm16,imm8               \320\1\x83\205\15               8086
 SUB            rm32,imm8               \321\1\x83\205\15               386
 SUB            rm64,imm8               \324\1\x83\205\15               X64
 SUB            reg_al,imm              \1\x2C\21                       8086,SM
-SUB            reg_ax,sbyte            \320\1\x83\205\15               8086,SM,ND
+SUB            reg_ax,sbyte16          \320\1\x83\205\15               8086,SM,ND
 SUB            reg_ax,imm              \320\1\x2D\31                   8086,SM
-SUB            reg_eax,sbyte           \321\1\x83\205\15               386,SM,ND
+SUB            reg_eax,sbyte32         \321\1\x83\205\15               386,SM,ND
 SUB            reg_eax,imm             \321\1\x2D\41                   386,SM
-SUB            reg_rax,sbyte           \324\1\x83\205\15               X64,SM,ND
+SUB            reg_rax,sbyte64         \324\1\x83\205\15               X64,SM,ND
 SUB            reg_rax,imm             \324\1\x2D\41                   X64,SM
 SUB            rm8,imm                 \1\x80\205\21                   8086,SM
 SUB            rm16,imm                \320\145\x81\205\141            8086,SM
 SUB            rm32,imm                \321\155\x81\205\151            386,SM
-SUB            rm64,imm                \324\155\x81\205\151            X64,SM
+SUB            rm64,imm                \324\155\x81\205\251            X64,SM
 SUB            mem,imm8                \1\x80\205\21                   8086,SM
 SUB            mem,imm16               \320\145\x81\205\141            8086,SM
 SUB            mem,imm32               \321\155\x81\205\151            386,SM
@@ -1348,16 +1347,16 @@ XOR             rm16,imm8               \320\1\x83\206\15               8086
 XOR            rm32,imm8               \321\1\x83\206\15               386
 XOR            rm64,imm8               \324\1\x83\206\15               X64
 XOR            reg_al,imm              \1\x34\21                       8086,SM
-XOR            reg_ax,sbyte            \320\1\x83\206\15               8086,SM,ND
+XOR            reg_ax,sbyte16          \320\1\x83\206\15               8086,SM,ND
 XOR            reg_ax,imm              \320\1\x35\31                   8086,SM
-XOR            reg_eax,sbyte           \321\1\x83\206\15               386,SM,ND
+XOR            reg_eax,sbyte32         \321\1\x83\206\15               386,SM,ND
 XOR            reg_eax,imm             \321\1\x35\41                   386,SM
-XOR            reg_rax,sbyte           \324\1\x83\206\15               X64,SM,ND
+XOR            reg_rax,sbyte64         \324\1\x83\206\15               X64,SM,ND
 XOR            reg_rax,imm             \324\1\x35\41                   X64,SM
 XOR            rm8,imm                 \1\x80\206\21                   8086,SM
 XOR            rm16,imm                \320\145\x81\206\141            8086,SM
 XOR            rm32,imm                \321\155\x81\206\151            386,SM
-XOR            rm64,imm                \324\155\x81\206\151            X64,SM
+XOR            rm64,imm                \324\155\x81\206\251            X64,SM
 XOR            mem,imm8                \1\x80\206\21                   8086,SM
 XOR            mem,imm16               \320\145\x81\206\141            8086,SM
 XOR            mem,imm32               \321\155\x81\206\151            386,SM
diff --git a/insns.h b/insns.h
index 3fefa45..49cc185 100644 (file)
--- a/insns.h
+++ b/insns.h
@@ -72,12 +72,14 @@ extern const struct disasm_index itable[256];
 #define IF_SD     0x0000000CUL  /* unsized operands can't be non-dword */
 #define IF_SQ     0x00000010UL  /* unsized operands can't be non-qword */
 #define IF_SO     0x00000014UL  /* unsized operands can't be non-oword */
+#define IF_SZ     0x00000018UL  /* unsized operands must match the bitsize */
 #define IF_SMASK  0x0000001CUL  /* mask for unsized argument size */
 #define IF_AR0   0x00000020UL  /* SB, SW, SD applies to argument 0 */
 #define IF_AR1   0x00000040UL  /* SB, SW, SD applies to argument 1 */
 #define IF_AR2   0x00000060UL  /* SB, SW, SD applies to argument 2 */
-#define IF_AR3   0x00000080UL  /* SB, SW, SD applies to argument 2 */
+#define IF_AR3   0x00000080UL  /* SB, SW, SD applies to argument 3 */
 #define IF_ARMASK 0x000000E0UL  /* mask for unsized argument spec */
+#define IF_ARSHFT 5            /* LSB in IF_ARMASK */
 #define IF_PRIV   0x00000100UL  /* it's a privileged instruction */
 #define IF_SMM    0x00000200UL  /* it's only valid in SMM */
 #define IF_PROT   0x00000400UL  /* it's protected mode only */
diff --git a/nasm.h b/nasm.h
index b2c1e93..2591b1c 100644 (file)
--- a/nasm.h
+++ b/nasm.h
@@ -428,7 +428,9 @@ enum {
  *
  * With IMMEDIATE:
  * 16: UNITY (1)
- * 17: BYTENESS (-128..127)
+ * 17: BYTENESS16 (-128..127)
+ * 18: BYTENESS32 (-128..127)
+ * 19: BYTENESS64 (-128..127)
  *
  * Bits 20-26: register classes
  * 20: REG_CDT (CRx, DRx, TRx)
@@ -539,7 +541,9 @@ typedef uint32_t opflags_t;
 
 /* special type of immediate operand */
 #define UNITY          0x00012000U   /* for shift/rotate instructions */
-#define SBYTE          0x00022000U   /* for op r16/32,immediate instrs. */
+#define SBYTE16                0x00022000U   /* for op r16,immediate instrs. */
+#define SBYTE32                0x00042000U   /* for op r32,immediate instrs. */
+#define SBYTE64                0x00082000U   /* for op r64,immediate instrs. */
 
 /* special flags */
 #define SAME_AS                0x40000000U
index 5983af5..9172fb1 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -797,9 +797,16 @@ restart_parse:
                         result->oprs[operand].type |= UNITY;
                     if (optimizing >= 0 &&
                         !(result->oprs[operand].type & STRICT)) {
-                        if (reloc_value(value) >= -128 &&
-                            reloc_value(value) <= 127)
-                            result->oprs[operand].type |= SBYTE;
+                       int64_t v64 = reloc_value(value);
+                       int32_t v32 = (int32_t)v64;
+                       int16_t v16 = (int16_t)v32;
+
+                       if (v64 >= -128 && v64 <= 127)
+                            result->oprs[operand].type |= SBYTE64;
+                       if (v32 >= -128 && v32 <= 127)
+                            result->oprs[operand].type |= SBYTE32;
+                       if (v16 >= -128 && v16 <= 127)
+                            result->oprs[operand].type |= SBYTE16;
                     }
                 }
             } else {            /* it's a register */