@@ -110,7 +110,7 @@ static uint8_t opcode_table[256] = {
/* 0x80 - 0x87 */
ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM,
ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM,
- ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
+ ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
/* 0x88 - 0x8F */
ByteOp|DstMem|SrcReg|ModRM|Mov, DstMem|SrcReg|ModRM|Mov,
@@ -169,8 +169,7 @@ static uint8_t opcode_table[256] = {
DstEax|SrcImplicit, DstEax|SrcImplicit, ImplicitOps, ImplicitOps,
/* 0xF0 - 0xF7 */
0, ImplicitOps, 0, 0,
- ImplicitOps, ImplicitOps,
- ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM,
+ ImplicitOps, ImplicitOps, ByteOp|ModRM, ModRM,
/* 0xF8 - 0xFF */
ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
ImplicitOps, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM
@@ -1651,9 +1650,6 @@ x86_emulate(
}
}
- /* Lock prefix is allowed only on RMW instructions. */
- generate_exception_if((d & Mov) && lock_prefix, EXC_UD, -1);
-
/* ModRM and SIB bytes. */
if ( d & ModRM )
{
@@ -1729,13 +1725,17 @@ x86_emulate(
switch ( modrm_reg & 7 )
{
case 0 ... 1: /* test */
- d = (d & ~SrcMask) | SrcImm;
+ d |= DstMem | SrcImm;
+ break;
+ case 2: /* not */
+ case 3: /* neg */
+ d |= DstMem;
break;
case 4: /* mul */
case 5: /* imul */
case 6: /* div */
case 7: /* idiv */
- d = (d & (ByteOp | ModRM)) | DstEax | SrcMem;
+ d |= DstEax | SrcMem;
break;
}
break;
@@ -1983,8 +1983,9 @@ x86_emulate(
*/
generate_exception_if(
lock_prefix &&
- ((b < 0x20) || (b > 0x23)) && /* MOV CRn/DRn */
- (b != 0xc7), /* CMPXCHG{8,16}B */
+ (ext != ext_0f ||
+ (((b < 0x20) || (b > 0x23)) && /* MOV CRn/DRn */
+ (b != 0xc7))), /* CMPXCHG{8,16}B */
EXC_UD, -1);
dst.type = OP_NONE;
break;
@@ -2062,6 +2063,8 @@ x86_emulate(
goto done;
dst.orig_val = dst.val;
}
+ else /* Lock prefix is allowed only on RMW instructions. */
+ generate_exception_if(lock_prefix, EXC_UD, -1);
break;
}
@@ -2111,6 +2114,7 @@ x86_emulate(
break;
case 0x38 ... 0x3d: cmp: /* cmp */
+ generate_exception_if(lock_prefix, EXC_UD, -1);
emulate_2op_SrcV("cmp", src, dst, _regs.eflags);
dst.type = OP_NONE;
break;
@@ -3545,6 +3549,7 @@ x86_emulate(
unsigned long u[2], v;
case 0 ... 1: /* test */
+ generate_exception_if(lock_prefix, EXC_UD, -1);
goto test;
case 2: /* not */
dst.val = ~dst.val;
@@ -4507,6 +4512,7 @@ x86_emulate(
case 0xad: /* shrd %%cl,r,r/m */ {
uint8_t shift, width = dst.bytes << 3;
+ generate_exception_if(lock_prefix, EXC_UD, -1);
if ( b & 1 )
shift = _regs.ecx;
else