summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-09-17 15:49:30 -0700
committerH. Peter Anvin <hpa@zytor.com>2007-09-17 15:49:30 -0700
commit7eb4a387939955c1c0b41fbc8b1216419082321f (patch)
tree74cb142c9ba6f8cd82a07679e8f447dd726c6b7d
parent3a7edd73a35ee09ee3cbf783f4d7b7148884603a (diff)
downloadnasm-7eb4a387939955c1c0b41fbc8b1216419082321f.tar.gz
nasm-7eb4a387939955c1c0b41fbc8b1216419082321f.tar.bz2
nasm-7eb4a387939955c1c0b41fbc8b1216419082321f.zip
Initial support for four arguments per instruction
For SSE5, we will need to support four arguments per instruction.
-rw-r--r--assemble.c245
-rw-r--r--disasm.c54
-rw-r--r--insns.dat162
-rw-r--r--insns.h18
-rw-r--r--insns.pl69
-rw-r--r--nasm.h3
6 files changed, 310 insertions, 241 deletions
diff --git a/assemble.c b/assemble.c
index 5452271..7dc2b25 100644
--- a/assemble.c
+++ b/assemble.c
@@ -12,39 +12,36 @@
* (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)) {
diff --git a/disasm.c b/disasm.c
index 0452c29..cfe8693 100644
--- 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)
diff --git a/insns.dat b/insns.dat
index 422109e..1595ba6 100644
--- 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
--- 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 */
diff --git a/insns.pl b/insns.pl
index 421f16a..e596b48 100644
--- 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
--- 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) */