{
const struct itemplate *temp;
enum match_result m, merr;
+ int32_t xsizeflags[MAX_OPERANDS];
+ bool opsizemissing = false;
+ int i;
+
+ for (i = 0; i < instruction->operands; i++)
+ xsizeflags[i] = instruction->oprs[i].type & SIZE_MASK;
merr = MERR_INVALOP;
m = MOK_GOOD;
else
m = MERR_INVALOP;
+ } else if (m == MERR_OPSIZEMISSING &&
+ (temp->flags & IF_SMASK) != IF_SX) {
+ /*
+ * Missing operand size and a candidate for fuzzy matching...
+ */
+ for (i = 0; i < temp->operands; i++)
+ xsizeflags[i] |= temp->opd[i] & SIZE_MASK;
+
+ opsizemissing = true;
}
if (m > merr)
merr = m;
if (merr == MOK_GOOD)
- break;
+ goto done;
+ }
+
+ /* No match, but see if we can get a fuzzy operand size match... */
+ if (!opsizemissing)
+ goto done;
+
+ for (i = 0; i < instruction->operands; i++) {
+ /* This tests if xsizeflags[i] has more than one bit set */
+ if ((xsizeflags[i] & (xsizeflags[i]-1)))
+ goto done; /* No luck */
+
+ instruction->oprs[i].type |= xsizeflags[i]; /* Set the size */
+ }
+
+ /* Try matching again... */
+ for (temp = nasm_instructions[instruction->opcode];
+ temp->opcode != I_none; temp++) {
+ m = matches(temp, instruction, bits);
+ if (m == MOK_JUMP) {
+ if (jmp_match(segment, offset, bits, instruction, temp->code))
+ m = MOK_GOOD;
+ else
+ m = MERR_INVALOP;
+ }
+ if (m > merr)
+ merr = m;
+ if (merr == MOK_GOOD)
+ goto done;
}
+done:
*tempp = temp;
return merr;
}
} else if (itemp->opd[i] & ~type ||
((itemp->opd[i] & SIZE_MASK) &&
((itemp->opd[i] ^ type) & SIZE_MASK))) {
- if ((itemp->opd[i] & ~type & ~SIZE_MASK) ||
- (type & SIZE_MASK))
+ if ((itemp->opd[i] & ~type & ~SIZE_MASK) || (type & SIZE_MASK))
return MERR_INVALOP;
else
return MERR_OPSIZEMISSING;
#define IF_SQ 0x00000010UL /* unsized operands can't be non-qword */
#define IF_SO 0x00000014UL /* unsized operands can't be non-oword */
#define IF_SY 0x00000018UL /* unsized operands can't be non-yword */
-#define IF_SZ 0x0000001CUL /* unsized operands must match the bitsize */
-#define IF_SMASK 0x0000001CUL /* mask for unsized argument size */
-#define IF_AR0 0x00000020UL /* SB, SW, SD applies to argument 0 */
-#define IF_AR1 0x00000040UL /* SB, SW, SD applies to argument 1 */
-#define IF_AR2 0x00000060UL /* SB, SW, SD applies to argument 2 */
-#define IF_AR3 0x00000080UL /* SB, SW, SD applies to argument 3 */
-#define IF_ARMASK 0x000000E0UL /* mask for unsized argument spec */
-#define IF_ARSHFT 5 /* LSB in IF_ARMASK */
-#define IF_PRIV 0x00000100UL /* it's a privileged instruction */
-#define IF_SMM 0x00000200UL /* it's only valid in SMM */
-#define IF_PROT 0x00000400UL /* it's protected mode only */
+#define IF_SZ 0x00000038UL /* unsized operands must match the bitsize */
+#define IF_SX 0x0000003CUL /* unsized operands not allowed */
+#define IF_SMASK 0x0000003CUL /* mask for unsized argument size */
+#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_AR3 0x00000100UL /* SB, SW, SD applies to argument 3 */
+#define IF_AR4 0x00000140UL /* SB, SW, SD applies to argument 4 */
+#define IF_ARMASK 0x000001C0UL /* mask for unsized argument spec */
+#define IF_ARSHFT 6 /* LSB in IF_ARMASK */
+/* The next 3 bits aren't actually used for anything */
+#define IF_PRIV 0x00000000UL /* it's a privileged instruction */
+#define IF_SMM 0x00000000UL /* it's only valid in SMM */
+#define IF_PROT 0x00000000UL /* it's protected mode only */
#define IF_NOLONG 0x00000800UL /* it's not available in long mode */
#define IF_UNDOC 0x00001000UL /* it's an undocumented instruction */
#define IF_FPU 0x00002000UL /* it's an FPU instruction */