Initial support for four arguments per instruction
authorH. Peter Anvin <hpa@zytor.com>
Mon, 17 Sep 2007 22:49:30 +0000 (15:49 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Mon, 17 Sep 2007 22:49:30 +0000 (15:49 -0700)
For SSE5, we will need to support four arguments per instruction.

assemble.c
disasm.c
insns.dat
insns.h
insns.pl
nasm.h

index 5452271..7dc2b25 100644 (file)
  *                 (POP is never used for CS) depending on operand 0
  * \5, \7        - the second byte of POP/PUSH codes for FS, GS, depending
  *                 on operand 0
- * \10, \11, \12 - a literal byte follows in the code stream, to be added
- *                 to the register value of operand 0, 1 or 2
- * \17           - encodes the literal byte 0. (Some compilers don't take
- *                 kindly to a zero byte in the _middle_ of a compile time
- *                 string constant, so I had to put this hack in.)
- * \14, \15, \16 - a signed byte immediate operand, from operand 0, 1 or 2
- * \20, \21, \22 - a byte immediate operand, from operand 0, 1 or 2
- * \24, \25, \26 - an unsigned byte immediate operand, from operand 0, 1 or 2
- * \30, \31, \32 - a word immediate operand, from operand 0, 1 or 2
- * \34, \35, \36 - select between \3[012] and \4[012] depending on 16/32 bit
+ * \10..\13      - a literal byte follows in the code stream, to be added
+ *                 to the register value of operand 0..3
+ * \14..\17      - a signed byte immediate operand, from operand 0..3
+ * \20..\23      - a byte immediate operand, from operand 0..3
+ * \24..\27      - an unsigned byte immediate operand, from operand 0..3
+ * \30..\33      - a word immediate operand, from operand 0..3
+ * \34..\37      - select between \3[0-3] and \4[0-3] depending on 16/32 bit
  *                 assembly mode or the operand-size override on the operand
- * \37           - a word constant, from the _segment_ part of operand 0
- * \40, \41, \42 - a long immediate operand, from operand 0, 1 or 2
- * \44, \45, \46 - select between \3[012], \4[012] and \5[456]
+ * \40..\43      - a long immediate operand, from operand 0..3
+ * \44..\47      - select between \3[0-3], \4[0-3] and \5[4-7]
  *                depending on assembly mode or the address-size override
  *                on the operand.
- * \50, \51, \52 - a byte relative operand, from operand 0, 1 or 2
- * \54, \55, \56 - a qword immediate operand, from operand 0, 1 or 2
- * \60, \61, \62 - a word relative operand, from operand 0, 1 or 2
- * \64, \65, \66 - select between \6[012] and \7[012] depending on 16/32 bit
+ * \50..\53      - a byte relative operand, from operand 0..3
+ * \54..\57      - a qword immediate operand, from operand 0..3
+ * \60..\63      - a word relative operand, from operand 0..3
+ * \64..\67      - select between \6[0-3] and \7[0-3] depending on 16/32 bit
  *                 assembly mode or the operand-size override on the operand
- * \70, \71, \72 - a long relative operand, from operand 0, 1 or 2
+ * \70..\73      - a long relative operand, from operand 0..3
+ * \74..\77       - a word constant, from the _segment_ part of operand 0..3
  * \1ab          - a ModRM, calculated on EA in operand a, with the spare
  *                 field the register value of operand b.
- * \130,\131,\132 - an immediate word or signed byte for operand 0, 1, or 2
- * \133,\134,\135 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
+ * \140..\143    - an immediate word or signed byte for operand 0..3
+ * \144..\147    - or 2 (s-field) into next opcode byte if operand 0..3
  *                 is a signed byte rather than a word.
- * \140,\141,\142 - an immediate dword or signed byte for operand 0, 1, or 2
- * \143,\144,\145 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
+ * \150..\153     - an immediate dword or signed byte for operand 0..3
+ * \154..\157     - or 2 (s-field) into next opcode byte if operand 0..3
  *                 is a signed byte rather than a dword.
- * \150,\151,\152 - an immediate qword or signed byte for operand 0, 1, or 2
- * \153,\154,\155 - or 2 (s-field) into next opcode byte if operand 0, 1, or 2
- *                 is a signed byte rather than a qword.
+ * \170          - encodes the literal byte 0. (Some compilers don't take
+ *                 kindly to a zero byte in the _middle_ of a compile time
+ *                 string constant, so I had to put this hack in.)
  * \2ab          - a ModRM, calculated on EA in operand a, with the spare
  *                 field equal to digit b.
  * \30x          - might be an 0x67 byte, depending on the address size of
@@ -730,73 +727,79 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
         case 010:
         case 011:
         case 012:
+       case 013:
            ins->rex |=
                op_rexflags(&ins->oprs[c - 010], REX_B|REX_H|REX_P|REX_W);
             codes++, length++;
             break;
-        case 017:
-            length++;
-            break;
         case 014:
         case 015:
         case 016:
+       case 017:
             length++;
             break;
         case 020:
         case 021:
         case 022:
+       case 023:
             length++;
             break;
         case 024:
         case 025:
         case 026:
+       case 027:
             length++;
             break;
         case 030:
         case 031:
         case 032:
+       case 033:
             length += 2;
             break;
         case 034:
         case 035:
         case 036:
+       case 037:
             if (ins->oprs[c - 034].type & (BITS16 | BITS32 | BITS64))
                 length += (ins->oprs[c - 034].type & BITS16) ? 2 : 4;
             else
                 length += (bits == 16) ? 2 : 4;
             break;
-        case 037:
-            length += 2;
-            break;
         case 040:
         case 041:
         case 042:
+       case 043:
             length += 4;
             break;
         case 044:
         case 045:
         case 046:
+       case 047:
             length += ((ins->oprs[c - 044].addr_size ?
                         ins->oprs[c - 044].addr_size : bits) >> 3);
             break;
         case 050:
         case 051:
         case 052:
+       case 053:
             length++;
             break;
         case 054:
         case 055:
         case 056:
+       case 057:
             length += 8; /* MOV reg64/imm */
             break;
         case 060:
         case 061:
         case 062:
+       case 063:
             length += 2;
             break;
         case 064:
         case 065:
         case 066:
+       case 067:
             if (ins->oprs[c - 064].type & (BITS16 | BITS32 | BITS64))
                 length += (ins->oprs[c - 064].type & BITS16) ? 2 : 4;
             else
@@ -805,33 +808,48 @@ static int32_t calcsize(int32_t segment, int32_t offset, int bits,
         case 070:
         case 071:
         case 072:
+       case 073:
             length += 4;
             break;
-        case 0130:
-        case 0131:
-        case 0132:
-            length += is_sbyte(ins, c - 0130, 16) ? 1 : 2;
-            break;
-        case 0133:
-        case 0134:
-        case 0135:
-            codes += 2;
-            length++;
+        case 074:
+        case 075:
+        case 076:
+        case 077:
+            length += 2;
             break;
         case 0140:
         case 0141:
         case 0142:
-            length += is_sbyte(ins, c - 0140, 32) ? 1 : 4;
+       case 0143:
+            length += is_sbyte(ins, c - 0140, 16) ? 1 : 2;
             break;
-        case 0143:
         case 0144:
         case 0145:
+        case 0146:
+        case 0147:
+            codes += 2;
+            length++;
+            break;
+        case 0150:
+        case 0151:
+        case 0152:
+        case 0153:
+            length += is_sbyte(ins, c - 0150, 32) ? 1 : 4;
+            break;
+        case 0154:
+        case 0155:
+        case 0156:
+        case 0157:
             codes += 2;
             length++;
             break;
+        case 0170:
+            length++;
+            break;
         case 0300:
         case 0301:
         case 0302:         
+        case 0303:         
             length += chsize(&ins->oprs[c - 0300], bits);
             break;
         case 0310:
@@ -1020,21 +1038,17 @@ static void gencode(int32_t segment, int32_t offset, int bits,
         case 010:
         case 011:
         case 012:
+       case 013:
            EMIT_REX();
             bytes[0] = *codes++ + ((regval(&ins->oprs[c - 010])) & 7);
             out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
             offset += 1;
             break;
 
-        case 017:
-            bytes[0] = 0;
-            out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
-            offset += 1;
-            break;
-
         case 014:
         case 015:
         case 016:
+       case 017:
             if (ins->oprs[c - 014].offset < -128
                 || ins->oprs[c - 014].offset > 127) {
                 errfunc(ERR_WARNING, "signed byte value exceeds bounds");
@@ -1055,6 +1069,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
         case 020:
         case 021:
         case 022:
+       case 023:
             if (ins->oprs[c - 020].offset < -256
                 || ins->oprs[c - 020].offset > 255) {
                 errfunc(ERR_WARNING, "byte value exceeds bounds");
@@ -1074,6 +1089,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
         case 024:
         case 025:
         case 026:
+       case 027:
             if (ins->oprs[c - 024].offset < 0
                 || ins->oprs[c - 024].offset > 255)
                 errfunc(ERR_WARNING, "unsigned byte value exceeds bounds");
@@ -1092,6 +1108,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
         case 030:
         case 031:
         case 032:
+       case 033:
             if (ins->oprs[c - 030].segment == NO_SEG &&
                 ins->oprs[c - 030].wrt == NO_SEG &&
                 (ins->oprs[c - 030].offset < -65536L ||
@@ -1107,6 +1124,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
         case 034:
         case 035:
         case 036:
+       case 037:
             if (ins->oprs[c - 034].type & (BITS16 | BITS32))
                 size = (ins->oprs[c - 034].type & BITS16) ? 2 : 4;
             else
@@ -1119,20 +1137,10 @@ static void gencode(int32_t segment, int32_t offset, int bits,
             offset += size;
             break;
 
-        case 037:
-            if (ins->oprs[0].segment == NO_SEG)
-                errfunc(ERR_NONFATAL, "value referenced by FAR is not"
-                        " relocatable");
-            data = 0L;
-            out(offset, segment, &data, OUT_ADDRESS + 2,
-                outfmt->segbase(1 + ins->oprs[0].segment),
-                ins->oprs[0].wrt);
-            offset += 2;
-            break;
-
         case 040:
         case 041:
         case 042:
+       case 043:
             data = ins->oprs[c - 040].offset;
             out(offset, segment, &data, OUT_ADDRESS + 4,
                 ins->oprs[c - 040].segment, ins->oprs[c - 040].wrt);
@@ -1142,6 +1150,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
         case 044:
         case 045:
         case 046:
+       case 047:
             data = ins->oprs[c - 044].offset;
             size = ((ins->oprs[c - 044].addr_size ?
                      ins->oprs[c - 044].addr_size : bits) >> 3);
@@ -1155,6 +1164,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
         case 050:
         case 051:
         case 052:
+       case 053:
             if (ins->oprs[c - 050].segment != segment)
                 errfunc(ERR_NONFATAL,
                         "short relative jump outside segment");
@@ -1169,6 +1179,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
         case 054:
         case 055:
         case 056:
+       case 057:
             data = (int64_t)ins->oprs[c - 054].offset;
             out(offset, segment, &data, OUT_ADDRESS + 8,
                 ins->oprs[c - 054].segment, ins->oprs[c - 054].wrt);
@@ -1178,6 +1189,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
         case 060:
         case 061:
         case 062:
+       case 063:
             if (ins->oprs[c - 060].segment != segment) {
                 data = ins->oprs[c - 060].offset;
                 out(offset, segment, &data,
@@ -1194,6 +1206,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
         case 064:
         case 065:
         case 066:
+       case 067:
             if (ins->oprs[c - 064].type & (BITS16 | BITS32 | BITS64))
                 size = (ins->oprs[c - 064].type & BITS16) ? 2 : 4;
             else
@@ -1214,6 +1227,7 @@ static void gencode(int32_t segment, int32_t offset, int bits,
         case 070:
         case 071:
         case 072:
+       case 073:
             if (ins->oprs[c - 070].segment != segment) {
                 data = ins->oprs[c - 070].offset;
                 out(offset, segment, &data,
@@ -1227,70 +1241,95 @@ static void gencode(int32_t segment, int32_t offset, int bits,
             offset += 4;
             break;
 
-        case 0130:
-        case 0131:
-        case 0132:
-            data = ins->oprs[c - 0130].offset;
-            if (is_sbyte(ins, c - 0130, 16)) {
+        case 074:
+        case 075:
+        case 076:
+        case 077:
+            if (ins->oprs[c - 074].segment == NO_SEG)
+                errfunc(ERR_NONFATAL, "value referenced by FAR is not"
+                        " relocatable");
+            data = 0L;
+            out(offset, segment, &data, OUT_ADDRESS + 2,
+                outfmt->segbase(1 + ins->oprs[c - 074].segment),
+                ins->oprs[c - 074].wrt);
+            offset += 2;
+            break;
+
+        case 0140:
+        case 0141:
+        case 0142:
+       case 0143:
+            data = ins->oprs[c - 0140].offset;
+            if (is_sbyte(ins, c - 0140, 16)) {
                 bytes[0] = data;
                 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
                     NO_SEG);
                 offset++;
             } else {
-                if (ins->oprs[c - 0130].segment == NO_SEG &&
-                    ins->oprs[c - 0130].wrt == NO_SEG &&
+                if (ins->oprs[c - 0140].segment == NO_SEG &&
+                    ins->oprs[c - 0140].wrt == NO_SEG &&
                     (data < -65536L || data > 65535L)) {
                     errfunc(ERR_WARNING, "word value exceeds bounds");
                 }
                 out(offset, segment, &data, OUT_ADDRESS + 2,
-                    ins->oprs[c - 0130].segment, ins->oprs[c - 0130].wrt);
+                    ins->oprs[c - 0140].segment, ins->oprs[c - 0130].wrt);
                 offset += 2;
             }
             break;
 
-        case 0133:
-        case 0134:
-        case 0135:
+        case 0144:
+        case 0145:
+        case 0146:
+       case 0147:
            EMIT_REX();
             codes++;
             bytes[0] = *codes++;
-            if (is_sbyte(ins, c - 0133, 16))
+            if (is_sbyte(ins, c - 0144, 16))
                 bytes[0] |= 2;  /* s-bit */
             out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
             offset++;
             break;
 
-        case 0140:
-        case 0141:
-        case 0142:
-            data = ins->oprs[c - 0140].offset;
-            if (is_sbyte(ins, c - 0140, 32)) {
+        case 0150:
+        case 0151:
+        case 0152:
+       case 0153:
+            data = ins->oprs[c - 0150].offset;
+            if (is_sbyte(ins, c - 0150, 32)) {
                 bytes[0] = data;
                 out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
                     NO_SEG);
                 offset++;
             } else {
                 out(offset, segment, &data, OUT_ADDRESS + 4,
-                    ins->oprs[c - 0140].segment, ins->oprs[c - 0140].wrt);
+                    ins->oprs[c - 0150].segment, ins->oprs[c - 0140].wrt);
                 offset += 4;
             }
             break;
 
-        case 0143:
-        case 0144:
-        case 0145:
+        case 0154:
+        case 0155:
+        case 0156:
+       case 0157:
            EMIT_REX();
             codes++;
             bytes[0] = *codes++;
-            if (is_sbyte(ins, c - 0143, 32))
+            if (is_sbyte(ins, c - 0154, 32))
                 bytes[0] |= 2;  /* s-bit */
             out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
             offset++;
             break;
 
+        case 0170:
+            bytes[0] = 0;
+            out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
+            offset += 1;
+            break;
+
         case 0300:
         case 0301:
         case 0302:
+        case 0303:
             if (chsize(&ins->oprs[c - 0300], bits)) {
                 *bytes = 0x67;
                 out(offset, segment, bytes,
@@ -1537,7 +1576,7 @@ static int rexflags(int val, int32_t flags, int mask)
 
 static int matches(const struct itemplate *itemp, insn * instruction, int bits)
 {
-    int i, size[3], asize, oprs, ret;
+    int i, size[MAX_OPERANDS], asize, oprs, ret;
 
     ret = 100;
 
@@ -1579,7 +1618,7 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
      * Check operand sizes
      */
     if (itemp->flags & IF_ARMASK) {
-        size[0] = size[1] = size[2] = 0;
+       memset(size, 0, sizeof size);
 
         switch (itemp->flags & IF_ARMASK) {
         case IF_AR0:
@@ -1591,34 +1630,54 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
         case IF_AR2:
             i = 2;
             break;
+#if 0 /* Need to reorganize instruction flags to fit IF_AR3 */
+       case IF_AR3:
+           i = 3;
+           break;
+#endif
         default:
             break;              /* Shouldn't happen */
         }
-        if (itemp->flags & IF_SB) {
+       switch (itemp->flags & IF_SMASK) {
+       case IF_SB:
             size[i] = BITS8;
-        } else if (itemp->flags & IF_SW) {
+           break;
+       case IF_SW:
             size[i] = BITS16;
-        } else if (itemp->flags & IF_SD) {
+           break;
+       case IF_SD:
             size[i] = BITS32;
-        } else if (itemp->flags & IF_SQ) {
+           break;
+       case IF_SQ:
             size[i] = BITS64;
+           break;
+       default:
+           break;
         }
     } else {
         asize = 0;
-        if (itemp->flags & IF_SB) {
+       switch (itemp->flags & IF_SMASK) {
+       case IF_SB:
             asize = BITS8;
             oprs = itemp->operands;
-        } else if (itemp->flags & IF_SW) {
+           break;
+       case IF_SW:
             asize = BITS16;
             oprs = itemp->operands;
-        } else if (itemp->flags & IF_SD) {
+           break;
+       case IF_SD:
             asize = BITS32;
             oprs = itemp->operands;
-        } else if (itemp->flags & IF_SQ) {
+           break;
+       case IF_SQ:
             asize = BITS64;
             oprs = itemp->operands;
+           break;
+       default:
+           break;
         }
-        size[0] = size[1] = size[2] = asize;
+       for (i = 0; i < MAX_OPERANDS; i++)
+           size[i] = asize;
     }
     
     if (itemp->flags & (IF_SM | IF_SM2)) {
index 0452c29..cfe8693 100644 (file)
--- a/disasm.c
+++ b/disasm.c
@@ -341,12 +341,12 @@ static int matches(const struct itemplate *t, uint8_t *data,
     uint8_t lock = prefix->lock;
     int osize = prefix->osize;
     int asize = prefix->asize;
+    int i;
 
-    ins->oprs[0].segment = ins->oprs[1].segment =
-       ins->oprs[2].segment =
-       ins->oprs[0].addr_size = ins->oprs[1].addr_size =
-       ins->oprs[2].addr_size = (segsize == 64 ? SEG_64BIT :
-                                 segsize == 32 ? SEG_32BIT : 0);
+    for (i = 0; i < MAX_OPERANDS; i++) {
+       ins->oprs[i].segment = ins->oprs[i].addr_size =
+           (segsize == 64 ? SEG_64BIT : segsize == 32 ? SEG_32BIT : 0);
+    }
     ins->condition = -1;
     ins->rex = prefix->rex;
 
@@ -419,7 +419,7 @@ static int matches(const struct itemplate *t, uint8_t *data,
             default:
                 return FALSE;
             }
-       } else if (c >= 010 && c <= 012) {
+       } else if (c >= 010 && c <= 013) {
             int t = *r++, d = *data++;
             if (d < t || d > t + 7)
                 return FALSE;
@@ -428,20 +428,17 @@ static int matches(const struct itemplate *t, uint8_t *data,
                    (ins->rex & REX_B ? 8 : 0);
                 ins->oprs[c - 010].segment |= SEG_RMREG;
             }
-        } else if (c == 017) {
-            if (*data++)
-                return FALSE;
-       } else if (c >= 014 && c <= 016) {
+       } else if (c >= 014 && c <= 017) {
             ins->oprs[c - 014].offset = (int8_t)*data++;
             ins->oprs[c - 014].segment |= SEG_SIGNED;
-        } else if (c >= 020 && c <= 022) {
+        } else if (c >= 020 && c <= 023) {
             ins->oprs[c - 020].offset = *data++;
-       } else if (c >= 024 && c <= 026) {
+       } else if (c >= 024 && c <= 027) {
             ins->oprs[c - 024].offset = *data++;
-       } else if (c >= 030 && c <= 032) {
+       } else if (c >= 030 && c <= 033) {
             ins->oprs[c - 030].offset = getu16(data);
            data += 2;
-        } else if (c >= 034 && c <= 036) {
+        } else if (c >= 034 && c <= 037) {
            if (osize == 32) {
                ins->oprs[c - 034].offset = getu32(data);
                data += 4;
@@ -451,10 +448,10 @@ static int matches(const struct itemplate *t, uint8_t *data,
            }
             if (segsize != asize)
                 ins->oprs[c - 034].addr_size = asize;
-        } else if (c >= 040 && c <= 042) {
+        } else if (c >= 040 && c <= 043) {
             ins->oprs[c - 040].offset = getu32(data);
            data += 4;
-        } else if (c >= 044 && c <= 046) {
+        } else if (c >= 044 && c <= 047) {
            switch (asize) {
            case 16:
                ins->oprs[c - 044].offset = getu16(data);
@@ -471,18 +468,18 @@ static int matches(const struct itemplate *t, uint8_t *data,
            }
             if (segsize != asize)
                 ins->oprs[c - 044].addr_size = asize;
-        } else if (c >= 050 && c <= 052) {
+        } else if (c >= 050 && c <= 053) {
             ins->oprs[c - 050].offset = gets8(data++);
             ins->oprs[c - 050].segment |= SEG_RELATIVE;
-        } else if (c >= 054 && c <= 056) {
+        } else if (c >= 054 && c <= 057) {
            ins->oprs[c - 054].offset = getu64(data);
            data += 8;
-       } else if (c >= 060 && c <= 062) {
+       } else if (c >= 060 && c <= 063) {
             ins->oprs[c - 060].offset = gets16(data);
            data += 2;
             ins->oprs[c - 060].segment |= SEG_RELATIVE;
             ins->oprs[c - 060].segment &= ~SEG_32BIT;
-        } else if (c >= 064 && c <= 066) {
+        } else if (c >= 064 && c <= 067) {
            if (osize == 16) {
                ins->oprs[c - 064].offset = getu16(data);
                data += 2;
@@ -498,30 +495,33 @@ static int matches(const struct itemplate *t, uint8_t *data,
                     (ins->oprs[c - 064].type & ~SIZE_MASK)
                     | ((osize == 16) ? BITS16 : BITS32);
             }
-        } else if (c >= 070 && c <= 072) {
+        } else if (c >= 070 && c <= 073) {
             ins->oprs[c - 070].offset = getu32(data);
            data += 4;
             ins->oprs[c - 070].segment |= SEG_32BIT | SEG_RELATIVE;
-        } else if (c >= 0100 && c < 0130) {
+        } else if (c >= 0100 && c < 0140) {
             int modrm = *data++;
             ins->oprs[c & 07].basereg = ((modrm >> 3)&7)+
                (ins->rex & REX_R ? 8 : 0);
             ins->oprs[c & 07].segment |= SEG_RMREG;
             data = do_ea(data, modrm, asize, segsize,
                          &ins->oprs[(c >> 3) & 07], ins->rex);
-        } else if (c >= 0130 && c <= 0132) {
-            ins->oprs[c - 0130].offset = getu16(data);
+        } else if (c >= 0140 && c <= 0143) {
+            ins->oprs[c - 0140].offset = getu16(data);
            data += 2;
-        } else if (c >= 0140 && c <= 0142) {
-           ins->oprs[c - 0140].offset = getu32(data);
+        } else if (c >= 0150 && c <= 0153) {
+           ins->oprs[c - 0150].offset = getu32(data);
            data += 4;
+        } else if (c == 0170) {
+            if (*data++)
+                return FALSE;
         } else if (c >= 0200 && c <= 0277) {
             int modrm = *data++;
             if (((modrm >> 3) & 07) != (c & 07))
                 return FALSE;   /* spare field doesn't match up */
             data = do_ea(data, modrm, asize, segsize,
                          &ins->oprs[(c >> 3) & 07], ins->rex);
-        } else if (c >= 0300 && c <= 0302) {
+        } else if (c >= 0300 && c <= 0303) {
             a_used = TRUE;
         } else if (c == 0310) {
             if (asize != 16)
index 422109e..1595ba6 100644 (file)
--- a/insns.dat
+++ b/insns.dat
@@ -47,14 +47,14 @@ ADC       reg_eax,imm         \321\1\x15\41                 386,SM
 ADC       reg_rax,sbyte       \321\1\x83\202\15             X64,SM,ND
 ADC       reg_rax,imm         \321\1\x15\41                 X64,SM
 ADC       rm8,imm             \300\1\x80\202\21             8086,SM
-ADC       rm16,imm            \320\300\134\1\x81\202\131    8086,SM
-ADC       rm32,imm            \321\300\144\1\x81\202\141    386,SM
-ADC       rm64,imm            \324\300\144\1\x81\202\141    X64,SM
+ADC       rm16,imm            \320\300\145\1\x81\202\141    8086,SM
+ADC       rm32,imm            \321\300\155\1\x81\202\151    386,SM
+ADC       rm64,imm            \324\300\155\1\x81\202\151    X64,SM
 ADC       mem,imm8            \300\1\x80\202\21             8086,SM
-ADC       mem,imm16           \320\300\134\1\x81\202\131    8086,SM
-ADC       mem,imm32           \321\300\144\1\x81\202\141    386,SM
-ADD       mem,reg8            \300\17\101                   8086,SM
-ADD       reg8,reg8           \17\101                       8086
+ADC       mem,imm16           \320\300\145\1\x81\202\141    8086,SM
+ADC       mem,imm32           \321\300\155\1\x81\202\151    386,SM
+ADD       mem,reg8            \300\170\101                  8086,SM
+ADD       reg8,reg8           \170\101                      8086
 ADD       mem,reg16           \320\300\1\x01\101            8086,SM
 ADD       reg16,reg16         \320\1\x01\101                8086
 ADD       mem,reg32           \321\300\1\x01\101            386,SM
@@ -80,12 +80,12 @@ ADD       reg_eax,imm         \321\1\x05\41                 386,SM
 ADD       reg_rax,sbyte       \321\1\x83\200\15             X64,SM,ND
 ADD       reg_rax,imm         \323\1\x05\41                 X64,SM
 ADD       rm8,imm             \300\1\x80\200\21             8086,SM
-ADD       rm16,imm            \320\300\134\1\x81\200\131    8086,SM
-ADD       rm32,imm            \321\300\144\1\x81\200\141    386,SM
-ADD       rm64,imm            \324\300\144\1\x81\200\141    X64,SM
+ADD       rm16,imm            \320\300\145\1\x81\200\141    8086,SM
+ADD       rm32,imm            \321\300\155\1\x81\200\151    386,SM
+ADD       rm64,imm            \324\300\155\1\x81\200\151    X64,SM
 ADD       mem,imm8            \300\1\x80\200\21             8086,SM
-ADD       mem,imm16           \320\300\134\1\x81\200\131    8086,SM
-ADD       mem,imm32           \321\300\144\1\x81\200\141    386,SM
+ADD       mem,imm16           \320\300\145\1\x81\200\141    8086,SM
+ADD       mem,imm32           \321\300\155\1\x81\200\151    386,SM
 AND       mem,reg8            \300\1\x20\101                8086,SM
 AND       reg8,reg8           \1\x20\101                    8086
 AND       mem,reg16           \320\300\1\x21\101            8086,SM
@@ -113,12 +113,12 @@ AND       reg_eax,imm         \321\1\x25\41                 386,SM
 AND       reg_rax,sbyte       \321\1\x83\204\15             X64,SM,ND
 AND       reg_rax,imm         \324\1\x25\41                 X64,SM
 AND       rm8,imm             \300\1\x80\204\21             8086,SM
-AND       rm16,imm            \320\300\134\1\x81\204\131    8086,SM
-AND       rm32,imm            \321\300\144\1\x81\204\141    386,SM
-AND       rm64,imm            \324\300\144\1\x81\204\141    X64,SM
+AND       rm16,imm            \320\300\145\1\x81\204\141    8086,SM
+AND       rm32,imm            \321\300\155\1\x81\204\151    386,SM
+AND       rm64,imm            \324\300\155\1\x81\204\151    X64,SM
 AND       mem,imm8            \300\1\x80\204\21             8086,SM
-AND       mem,imm16           \320\300\134\1\x81\204\131    8086,SM
-AND       mem,imm32           \321\300\144\1\x81\204\141    386,SM
+AND       mem,imm16           \320\300\145\1\x81\204\141    8086,SM
+AND       mem,imm32           \321\300\155\1\x81\204\151    386,SM
 ARPL      mem,reg16           \300\1\x63\101                286,PROT,SM,NOLONG
 ARPL      reg16,reg16         \1\x63\101                    286,PROT,NOLONG
 BOUND     reg16,mem           \320\301\1\x62\110            186,NOLONG
@@ -175,13 +175,13 @@ BTS       rm32,imm            \321\300\2\x0F\xBA\205\25     386,SB
 BTS       rm64,imm            \324\300\2\x0F\xBA\205\25     X64,SB
 CALL      imm                 \322\1\xE8\64                 8086
 CALL      imm|near            \322\1\xE8\64                 8086
-CALL      imm|far             \322\1\x9A\34\37              8086,ND,NOLONG
+CALL      imm|far             \322\1\x9A\34\74              8086,ND,NOLONG
 CALL      imm16               \320\1\xE8\64                 8086
 CALL      imm16|near          \320\1\xE8\64                 8086
-CALL      imm16|far           \320\1\x9A\34\37              8086,ND,NOLONG
+CALL      imm16|far           \320\1\x9A\34\74              8086,ND,NOLONG
 CALL      imm32               \321\1\xE8\64                 386
 CALL      imm32|near          \321\1\xE8\64                 386
-CALL      imm32|far           \321\1\x9A\34\37              386,ND,NOLONG
+CALL      imm32|far           \321\1\x9A\34\74              386,ND,NOLONG
 CALL      imm:imm             \322\1\x9A\35\30              8086,NOLONG
 CALL      imm16:imm           \320\1\x9A\31\30              8086,NOLONG
 CALL      imm:imm16           \320\1\x9A\31\30              8086,NOLONG
@@ -238,12 +238,12 @@ CMP       reg_eax,imm         \321\1\x3D\41                 386,SM
 CMP       reg_rax,sbyte       \321\1\x83\207\15             X64,SM,ND
 CMP       reg_rax,imm         \321\1\x3D\41                 X64,SM
 CMP       rm8,imm             \300\1\x80\207\21             8086,SM
-CMP       rm16,imm            \320\300\134\1\x81\207\131    8086,SM
-CMP       rm32,imm            \321\300\144\1\x81\207\141    386,SM
-CMP       rm64,imm            \324\300\144\1\x81\207\141    X64,SM
+CMP       rm16,imm            \320\300\145\1\x81\207\141    8086,SM
+CMP       rm32,imm            \321\300\155\1\x81\207\151    386,SM
+CMP       rm64,imm            \324\300\155\1\x81\207\151    X64,SM
 CMP       mem,imm8            \300\1\x80\207\21             8086,SM
-CMP       mem,imm16           \320\300\134\1\x81\207\131    8086,SM
-CMP       mem,imm32           \321\300\144\1\x81\207\141    386,SM
+CMP       mem,imm16           \320\300\145\1\x81\207\141    8086,SM
+CMP       mem,imm32           \321\300\155\1\x81\207\151    386,SM
 CMPSB     void                \335\1\xA6                    8086
 CMPSD     void                \335\321\1\xA7                386
 CMPSQ     void                \335\324\1\xA7                X64
@@ -497,38 +497,38 @@ IMUL      reg64,reg64         \324\2\x0F\xAF\110            X64
 IMUL      reg16,mem,imm8      \320\301\1\x6B\110\16         186,SM
 IMUL      reg16,mem,sbyte     \320\301\1\x6B\110\16         186,SM,ND
 IMUL      reg16,mem,imm16     \320\301\1\x69\110\32         186,SM
-IMUL      reg16,mem,imm       \320\301\135\1\x69\110\132    186,SM,ND
+IMUL      reg16,mem,imm       \320\301\146\1\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,imm16   \320\1\x69\110\32             186
-IMUL      reg16,reg16,imm     \320\135\1\x69\110\132        186,SM,ND
+IMUL      reg16,reg16,imm     \320\146\1\x69\110\142        186,SM,ND
 IMUL      reg32,mem,imm8      \321\301\1\x6B\110\16         386,SM
 IMUL      reg32,mem,sbyte     \321\301\1\x6B\110\16         386,SM,ND
 IMUL      reg32,mem,imm32     \321\301\1\x69\110\42         386,SM
-IMUL      reg32,mem,imm       \321\301\145\1\x69\110\142    386,SM,ND
+IMUL      reg32,mem,imm       \321\301\156\1\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,imm32   \321\1\x69\110\42             386
-IMUL      reg32,reg32,imm     \321\145\1\x69\110\142        386,SM,ND
+IMUL      reg32,reg32,imm     \321\156\1\x69\110\152        386,SM,ND
 IMUL      reg64,mem,imm8      \324\301\1\x6B\110\16         X64,SM
 IMUL      reg64,mem,sbyte     \324\301\1\x6B\110\16         X64,SM,ND
 IMUL      reg64,mem,imm32     \324\301\1\x69\110\42         X64,SM
-IMUL      reg64,mem,imm       \324\301\145\1\x69\110\142    X64,SM,ND
+IMUL      reg64,mem,imm       \324\301\156\1\x69\110\152    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,imm32   \324\1\x69\110\42             X64
-IMUL      reg64,reg64,imm     \324\145\1\x69\110\142        X64,SM,ND
+IMUL      reg64,reg64,imm     \324\156\1\x69\110\152        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,imm16         \320\1\x69\100\31             186
-IMUL      reg16,imm           \320\134\1\x69\100\131        186,SM,ND
+IMUL      reg16,imm           \320\145\1\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,imm32         \321\1\x69\100\41             386
-IMUL      reg32,imm           \321\144\1\x69\100\141        386,SM,ND
+IMUL      reg32,imm           \321\155\1\x69\100\151        386,SM,ND
 IMUL      reg64,sbyte         \324\1\x6B\100\15             X64,SM,ND
 IMUL      reg64,imm32         \324\1\x69\100\41             X64
-IMUL      reg64,imm           \324\144\1\x69\100\141        X64,SM,ND
+IMUL      reg64,imm           \324\155\1\x69\100\151        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
@@ -564,13 +564,13 @@ JMP       imm|short           \1\xEB\50                     8086
 JMP       imm                 \371\1\xEB\50                 8086,ND
 JMP       imm                 \322\1\xE9\64                 8086
 JMP       imm|near            \322\1\xE9\64                 8086,ND
-JMP       imm|far             \322\1\xEA\34\37              8086,ND,NOLONG
+JMP       imm|far             \322\1\xEA\34\74              8086,ND,NOLONG
 JMP       imm16               \320\1\xE9\64                 8086
 JMP       imm16|near          \320\1\xE9\64                 8086,ND
-JMP       imm16|far           \320\1\xEA\34\37              8086,ND,NOLONG
+JMP       imm16|far           \320\1\xEA\34\74              8086,ND,NOLONG
 JMP       imm32               \321\1\xE9\64                 386
 JMP       imm32|near          \321\1\xE9\64                 386,ND
-JMP       imm32|far           \321\1\xEA\34\37              386,ND,NOLONG
+JMP       imm32|far           \321\1\xEA\34\74              386,ND,NOLONG
 JMP       imm:imm             \322\1\xEA\35\30              8086,NOLONG
 JMP       imm16:imm           \320\1\xEA\31\30              8086,NOLONG
 JMP       imm:imm16           \320\1\xEA\31\30              8086,NOLONG
@@ -618,9 +618,9 @@ LGDT      mem                 \300\2\x0F\x01\202            286,PRIV
 LGS       reg16,mem           \320\301\2\x0F\xB5\110        386
 LGS       reg32,mem           \321\301\2\x0F\xB5\110        386
 LIDT      mem                 \300\2\x0F\x01\203            286,PRIV
-LLDT      mem                 \300\1\x0F\17\202             286,PROT,PRIV
-LLDT      mem16               \300\1\x0F\17\202             286,PROT,PRIV
-LLDT      reg16               \1\x0F\17\202                 286,PROT,PRIV
+LLDT      mem                 \300\1\x0F\170\202            286,PROT,PRIV
+LLDT      mem16               \300\1\x0F\170\202            286,PROT,PRIV
+LLDT      reg16               \1\x0F\170\202                286,PROT,PRIV
 LMSW      mem                 \300\2\x0F\x01\206            286,PRIV
 LMSW      mem16               \300\2\x0F\x01\206            286,PRIV
 LMSW      reg16               \2\x0F\x01\206                286,PRIV
@@ -658,9 +658,9 @@ LSL       reg64,mem           \324\301\2\x0F\x03\110        X64,SM
 LSL       reg64,reg64         \324\2\x0F\x03\110            X64,PROT
 LSS       reg16,mem           \320\301\2\x0F\xB2\110        386
 LSS       reg32,mem           \321\301\2\x0F\xB2\110        386
-LTR       mem                 \300\1\x0F\17\203             286,PROT,PRIV
-LTR       mem16               \300\1\x0F\17\203             286,PROT,PRIV,NOLONG
-LTR       reg16               \1\x0F\17\203                 286,PROT,PRIV,NOLONG
+LTR       mem                 \300\1\x0F\170\203            286,PROT,PRIV
+LTR       mem16               \300\1\x0F\170\203            286,PROT,PRIV,NOLONG
+LTR       reg16               \1\x0F\170\203                286,PROT,PRIV,NOLONG
 MFENCE    void                \3\x0F\xAE\xF0                X64,AMD
 MONITOR   void               \3\x0F\x01\xC8                PRESCOTT
 MONITOR          reg_eax,reg_ecx,reg_edx      \3\x0F\x01\xC8       PRESCOTT,ND
@@ -788,12 +788,12 @@ OR        reg_eax,imm         \321\1\x0D\41                 386,SM
 OR        reg_rax,sbyte       \321\1\x83\201\15             X64,SM,ND
 OR        reg_rax,imm         \321\1\x0D\41                 X64,SM
 OR        rm8,imm             \300\1\x80\201\21             8086,SM
-OR        rm16,imm            \320\300\134\1\x81\201\131    8086,SM
-OR        rm32,imm            \321\300\144\1\x81\201\141    386,SM
-OR        rm64,imm            \324\300\144\1\x81\201\141    X64,SM
+OR        rm16,imm            \320\300\145\1\x81\201\141    8086,SM
+OR        rm32,imm            \321\300\155\1\x81\201\151    386,SM
+OR        rm64,imm            \324\300\155\1\x81\201\151    X64,SM
 OR        mem,imm8            \300\1\x80\201\21             8086,SM
-OR        mem,imm16           \320\300\134\1\x81\201\131    8086,SM
-OR        mem,imm32           \321\300\144\1\x81\201\141    386,SM
+OR        mem,imm16           \320\300\145\1\x81\201\141    8086,SM
+OR        mem,imm32           \321\300\155\1\x81\201\151    386,SM
 OUT       imm,reg_al          \1\xE6\24                     8086,SB
 OUT       imm,reg_ax          \320\1\xE7\24                 8086,SB
 OUT       imm,reg_eax         \321\1\xE7\24                 386,SB
@@ -987,9 +987,9 @@ 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\133\1\x68\130            186
-PUSH      imm32               \321\143\1\x68\140            386,NOLONG
-PUSH      imm64               \321\143\1\x68\140            X64
+PUSH      imm16               \320\144\1\x68\140            186
+PUSH      imm32               \321\154\1\x68\150            386,NOLONG
+PUSH      imm64               \321\154\1\x68\150            X64
 PUSH     imm                 \1\x68\34                     186
 PUSHA     void                \322\1\x60                    186,NOLONG
 PUSHAD    void                \321\1\x60                    386,NOLONG
@@ -1121,12 +1121,12 @@ SBB       reg_eax,imm         \321\1\x1D\41                 386,SM
 SBB       reg_rax,sbyte       \321\1\x83\203\15             X64,SM,ND
 SBB       reg_rax,imm         \321\1\x1D\41                 X64,SM
 SBB       rm8,imm             \300\1\x80\203\21             8086,SM
-SBB       rm16,imm            \320\300\134\1\x81\203\131    8086,SM
-SBB       rm32,imm            \321\300\144\1\x81\203\141    386,SM
-SBB       rm64,imm            \324\300\144\1\x81\203\141    X64,SM
+SBB       rm16,imm            \320\300\145\1\x81\203\141    8086,SM
+SBB       rm32,imm            \321\300\155\1\x81\203\151    386,SM
+SBB       rm64,imm            \324\300\155\1\x81\203\151    X64,SM
 SBB       mem,imm8            \300\1\x80\203\21             8086,SM
-SBB       mem,imm16           \320\300\134\1\x81\203\131    8086,SM
-SBB       mem,imm32           \321\300\144\1\x81\203\141    386,SM
+SBB       mem,imm16           \320\300\145\1\x81\203\141    8086,SM
+SBB       mem,imm32           \321\300\155\1\x81\203\151    386,SM
 SCASB     void                \335\1\xAE                    8086
 SCASD     void                \335\321\1\xAF                386
 SCASQ     void                \335\324\1\xAF                X64
@@ -1182,10 +1182,10 @@ SHRD      reg32,reg32,reg_cl  \321\2\x0F\xAD\101            386
 SHRD      mem,reg64,reg_cl    \300\324\2\x0F\xAD\101        X64,SM
 SHRD      reg64,reg64,reg_cl  \324\2\x0F\xAD\101            X64
 SIDT      mem                 \300\2\x0F\x01\201            286
-SLDT      mem                 \300\1\x0F\17\200             286
-SLDT      mem16               \300\1\x0F\17\200             286
-SLDT      reg16               \320\1\x0F\17\200             286
-SLDT      reg32               \321\1\x0F\17\200             386
+SLDT      mem                 \300\1\x0F\170\200            286
+SLDT      mem16               \300\1\x0F\170\200            286
+SLDT      reg16               \320\1\x0F\170\200            286
+SLDT      reg32               \321\1\x0F\170\200            386
 SKINIT    void                \3\x0F\x01\xDE                X64
 SMI       void                \1\xF1                        386,UNDOC
 SMINT     void                \2\x0F\x38                    P6,CYRIX
@@ -1203,11 +1203,11 @@ STOSB     void                \1\xAA                        8086
 STOSD     void                \321\1\xAB                    386
 STOSQ     void                \324\1\xAB                    X64
 STOSW     void                \320\1\xAB                    8086
-STR       mem                 \300\1\x0F\17\201             286,PROT
-STR       mem16               \300\1\x0F\17\201             286,PROT
-STR       reg16               \320\1\x0F\17\201             286,PROT
-STR       reg32               \321\1\x0F\17\201             386,PROT
-STR       reg64               \324\1\x0F\17\201             X64
+STR       mem                 \300\1\x0F\170\201            286,PROT
+STR       mem16               \300\1\x0F\170\201            286,PROT
+STR       reg16               \320\1\x0F\170\201            286,PROT
+STR       reg32               \321\1\x0F\170\201            386,PROT
+STR       reg64               \324\1\x0F\170\201            X64
 SUB       mem,reg8            \300\1\x28\101                8086,SM
 SUB       reg8,reg8           \1\x28\101                    8086
 SUB       mem,reg16           \320\300\1\x29\101            8086,SM
@@ -1235,12 +1235,12 @@ SUB       reg_eax,imm         \321\1\x2D\41                 386,SM
 SUB       reg_rax,sbyte       \321\1\x83\205\15             X64,SM,ND
 SUB       reg_rax,imm         \321\1\x2D\41                 X64,SM
 SUB       rm8,imm             \300\1\x80\205\21             8086,SM
-SUB       rm16,imm            \320\300\134\1\x81\205\131    8086,SM
-SUB       rm32,imm            \321\300\144\1\x81\205\141    386,SM
-SUB       rm64,imm            \324\300\144\1\x81\205\141    X64,SM
+SUB       rm16,imm            \320\300\145\1\x81\205\141    8086,SM
+SUB       rm32,imm            \321\300\155\1\x81\205\151    386,SM
+SUB       rm64,imm            \324\300\155\1\x81\205\151    X64,SM
 SUB       mem,imm8            \300\1\x80\205\21             8086,SM
-SUB       mem,imm16           \320\300\134\1\x81\205\131    8086,SM
-SUB       mem,imm32           \321\300\144\1\x81\205\141    386,SM
+SUB       mem,imm16           \320\300\145\1\x81\205\141    8086,SM
+SUB       mem,imm32           \321\300\155\1\x81\205\151    386,SM
 SVDC      mem80,reg_sreg      \300\2\x0F\x78\101            486,CYRIX,SMM
 SVLDT     mem80               \300\2\x0F\x7A\200            486,CYRIX,SMM
 SVTS      mem80               \300\2\x0F\x7C\200            486,CYRIX,SMM
@@ -1287,12 +1287,12 @@ UMOV      reg16,mem           \320\301\2\x0F\x13\110        386,UNDOC,SM
 UMOV      reg16,reg16         \320\2\x0F\x13\110            386,UNDOC
 UMOV      reg32,mem           \321\301\2\x0F\x13\110        386,UNDOC,SM
 UMOV      reg32,reg32         \321\2\x0F\x13\110            386,UNDOC
-VERR      mem                 \300\1\x0F\17\204             286,PROT
-VERR      mem16               \300\1\x0F\17\204             286,PROT
-VERR      reg16               \1\x0F\17\204                 286,PROT
-VERW      mem                 \300\1\x0F\17\205             286,PROT
-VERW      mem16               \300\1\x0F\17\205             286,PROT
-VERW      reg16               \1\x0F\17\205                 286,PROT
+VERR      mem                 \300\1\x0F\170\204            286,PROT
+VERR      mem16               \300\1\x0F\170\204            286,PROT
+VERR      reg16               \1\x0F\170\204                286,PROT
+VERW      mem                 \300\1\x0F\170\205            286,PROT
+VERW      mem16               \300\1\x0F\170\205            286,PROT
+VERW      reg16               \1\x0F\170\205                286,PROT
 WAIT      void                \1\x9B                        8086
 FWAIT     void                \1\x9B                        8086
 WBINVD    void                \2\x0F\x09                    486,PRIV
@@ -1360,12 +1360,12 @@ XOR       reg_eax,imm         \321\1\x35\41                 386,SM
 XOR       reg_rax,sbyte       \321\1\x83\206\15             X64,SM,ND
 XOR       reg_rax,imm         \321\1\x35\41                 X64,SM
 XOR       rm8,imm             \300\1\x80\206\21             8086,SM
-XOR       rm16,imm            \320\300\134\1\x81\206\131    8086,SM
-XOR       rm32,imm            \321\300\144\1\x81\206\141    386,SM
-XOR       rm64,imm            \324\300\144\1\x81\206\141    X64,SM
+XOR       rm16,imm            \320\300\145\1\x81\206\141    8086,SM
+XOR       rm32,imm            \321\300\155\1\x81\206\151    386,SM
+XOR       rm64,imm            \324\300\155\1\x81\206\151    X64,SM
 XOR       mem,imm8            \300\1\x80\206\21             8086,SM
-XOR       mem,imm16           \320\300\134\1\x81\206\131    8086,SM
-XOR       mem,imm32           \321\300\144\1\x81\206\141    386,SM
+XOR       mem,imm16           \320\300\145\1\x81\206\141    8086,SM
+XOR       mem,imm32           \321\300\155\1\x81\206\151    386,SM
 XSTORE    void                \3\x0F\xA7\xC0                P6,CYRIX
 CMOVcc    reg16,mem           \320\301\1\x0F\330\x40\110    P6,SM
 CMOVcc    reg16,reg16         \320\1\x0F\330\x40\110        P6
diff --git a/insns.h b/insns.h
index 4deccf9..21dfd93 100644 (file)
--- a/insns.h
+++ b/insns.h
@@ -9,7 +9,7 @@
 #ifndef NASM_INSNS_H
 #define NASM_INSNS_H
 
-#include "insnsi.h"             /* instruction opcode enum */
+#include "nasm.h"
 
 /* max length of any instruction, register name etc. */
 #if MAX_INSLEN > 9              /* MAX_INSLEN defined in insnsi.h */
@@ -21,7 +21,7 @@
 struct itemplate {
     enum opcode opcode;                /* the token, passed from "parser.c" */
     int operands;              /* number of operands */
-    int32_t opd[3];            /* bit flags for operand types */
+    int32_t opd[MAX_OPERANDS]; /* bit flags for operand types */
     const char *code;          /* the code it assembles to */
     uint32_t flags;            /* some flags */
 };
@@ -66,12 +66,14 @@ extern const struct itemplate * const * const itable[];
 #define IF_SM2    0x00000002UL  /* size match first two operands */
 #define IF_SB     0x00000004UL  /* unsized operands can't be non-byte */
 #define IF_SW     0x00000008UL  /* unsized operands can't be non-word */
-#define IF_SD     0x00000010UL  /* unsized operands can't be non-dword */
-#define IF_SQ     0x00000020UL  /* unsized operands can't be non-qword */
-#define IF_AR0   0x00000040UL  /* SB, SW, SD applies to argument 0 */
-#define IF_AR1   0x00000080UL  /* SB, SW, SD applies to argument 1 */
-#define IF_AR2   0x000000C0UL  /* SB, SW, SD applies to argument 2 */
-#define IF_ARMASK 0x000000C0UL  /* mask for unsized argument spec */
+#define IF_SD     0x0000000CUL  /* unsized operands can't be non-dword */
+#define IF_SQ     0x00000010UL  /* unsized operands can't be non-qword */
+#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_ARMASK 0x000000E0UL  /* mask for unsized argument spec */
 #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 */
index 421f16a..e596b48 100644 (file)
--- a/insns.pl
+++ b/insns.pl
@@ -203,45 +203,52 @@ if ( !defined($output) || $output eq 'n' ) {
 printf STDERR "Done: %d instructions\n", $insns;
 
 sub format {
-  local ($opcode, $operands, $codes, $flags) = @_;
-  local $num, $nd = 0;
+    my ($opcode, $operands, $codes, $flags) = @_;
+    my $num, $nd = 0;
 
-  return (undef, undef) if $operands eq "ignore";
-
-  # format the operands
-  $operands =~ s/:/|colon,/g;
-  $operands =~ s/mem(\d+)/mem|bits$1/g;
-  $operands =~ s/mem/memory/g;
-  $operands =~ s/memory_offs/mem_offs/g;
-  $operands =~ s/imm(\d+)/imm|bits$1/g;
-  $operands =~ s/imm/immediate/g;
-  $operands =~ s/rm(\d+)/rm_gpr|bits$1/g;
-  $operands =~ s/mmxrm/rm_mmx/g;
-  $operands =~ s/xmmrm/rm_xmm/g;
-  $num = 3;
-  $operands = '0,0,0', $num = 0 if $operands eq 'void';
-  $operands .= ',0', $num-- while $operands !~ /,.*,/;
-  $operands =~ tr/a-z/A-Z/;
-
-  # format the flags
-  $flags =~ s/,/|IF_/g;
-  $flags =~ s/(\|IF_ND|IF_ND\|)//, $nd = 1 if $flags =~ /IF_ND/;
-  $flags = "IF_" . $flags;
-
-  ("{I_$opcode, $num, {$operands}, \"$codes\", $flags},", $nd);
+    return (undef, undef) if $operands eq "ignore";
+    
+    # format the operands
+    $operands =~ s/:/|colon,/g;
+    $operands =~ s/mem(\d+)/mem|bits$1/g;
+    $operands =~ s/mem/memory/g;
+    $operands =~ s/memory_offs/mem_offs/g;
+    $operands =~ s/imm(\d+)/imm|bits$1/g;
+    $operands =~ s/imm/immediate/g;
+    $operands =~ s/rm(\d+)/rm_gpr|bits$1/g;
+    $operands =~ s/mmxrm/rm_mmx/g;
+    $operands =~ s/xmmrm/rm_xmm/g;
+    if ($operands eq 'void') {
+       @ops = ();
+    } else {
+       @ops = split(/\,/, $operands);
+    }
+    $num = scalar(@ops);
+    while (scalar(@ops) < 4) {
+       push(@ops, '0');
+    }
+    $operands = join(',', @ops);
+    $operands =~ tr/a-z/A-Z/;
+    
+    # format the flags
+    $flags =~ s/,/|IF_/g;
+    $flags =~ s/(\|IF_ND|IF_ND\|)//, $nd = 1 if $flags =~ /IF_ND/;
+    $flags = "IF_" . $flags;
+    
+    ("{I_$opcode, $num, {$operands}, \"$codes\", $flags},", $nd);
 }
 
 # Here we determine the range of possible starting bytes for a given
 # instruction. We need only consider the codes:
 # \1 \2 \3     mean literal bytes, of course
 # \4 \5 \6 \7  mean PUSH/POP of segment registers: special case
-# \10 \11 \12  mean byte plus register value
-# \17          means byte zero
+# \1[0123]     mean byte plus register value
+# \170         means byte zero
 # \330         means byte plus condition code
 # \0 or \340   mean give up and return empty set
 sub startbyte {
-  local ($codes) = @_;
-  local $word, @range;
+  my ($codes) = @_;
+  my $word, @range;
 
   while (1) {
     die "couldn't get code in '$codes'" if $codes !~ /^(\\[^\\]+)(\\.*)?$/;
@@ -251,8 +258,8 @@ sub startbyte {
     return (0xA1, 0xA9) if $word eq "\\5";
     return (0x06, 0x0E, 0x16, 0x1E) if $word eq "\\6";
     return (0xA0, 0xA8) if $word eq "\\7";
-    $start=hex $1, $r=8, last if $word =~ /^\\1[012]$/ && $codes =~/^\\x(..)/;
-    return (0) if $word eq "\\17";
+    $start=hex $1, $r=8, last if $word =~ /^\\1[0123]$/ && $codes =~/^\\x(..)/;
+    return (0) if $word eq "\\170";
     $start=hex $1, $r=16, last if $word =~ /^\\330$/ && $codes =~ /^\\x(..)/;
     return () if $word eq "\\0" || $word eq "\\340";
   }
diff --git a/nasm.h b/nasm.h
index 4ae93b6..7c5a1b7 100644 (file)
--- a/nasm.h
+++ b/nasm.h
@@ -607,6 +607,7 @@ typedef struct extop {          /* extended operand */
 } extop;
 
 #define MAXPREFIX 4
+#define MAX_OPERANDS 4
 
 typedef struct {                /* an instruction itself */
     char *label;              /* the label defined, or NULL */
@@ -616,7 +617,7 @@ typedef struct {                /* an instruction itself */
     enum ccode condition;       /* the condition code, if Jcc/SETcc */
     int operands;               /* how many operands? 0-3 
                                  * (more if db et al) */
-    operand oprs[3];            /* the operands, defined as above */
+    operand oprs[MAX_OPERANDS]; /* the operands, defined as above */
     extop *eops;                /* extended operands */
     int eops_float;             /* true if DD and floating */
     int32_t times;              /* repeat count (TIMES prefix) */