if (szSmall == 1 && szBig == 8 && !signd) {
return unop(Iop_32Uto64, unop(Iop_8Uto32, src));
}
+ if (szSmall == 1 && szBig == 8 && signd) {
+ return unop(Iop_32Sto64, unop(Iop_8Sto32, src));
+ }
if (szSmall == 2 && szBig == 8 && !signd) {
return unop(Iop_32Uto64, unop(Iop_16Uto32, src));
}
+ if (szSmall == 2 && szBig == 8 && signd) {
+ return unop(Iop_32Sto64, unop(Iop_16Sto32, src));
+ }
vpanic("doScalarWidening(amd64)");
}
return extend_s_32to64( v );
}
+/* Get a 64-bit value out of the insn stream. */
+static ULong getDisp64 ( ULong delta )
+{
+ UInt v = 0;
+ v |= guest_code[delta+7]; v <<= 8;
+ v |= guest_code[delta+6]; v <<= 8;
+ v |= guest_code[delta+5]; v <<= 8;
+ v |= guest_code[delta+4]; v <<= 8;
+ v |= guest_code[delta+3]; v <<= 8;
+ v |= guest_code[delta+2]; v <<= 8;
+ v |= guest_code[delta+1]; v <<= 8;
+ v |= guest_code[delta+0];
+ return v;
+}
+
/* Note: because AMD64 doesn't allow 64-bit literals, it is an error
if this is called with size==8. Should not happen. */
static ULong getSDisp ( Int size, ULong delta )
return unop(Iop_64to32, e);
if (src_ty == Ity_I64 && dst_ty == Ity_I16)
return unop(Iop_32to16, unop(Iop_64to32, e));
+ if (src_ty == Ity_I64 && dst_ty == Ity_I8)
+ return unop(Iop_32to8, unop(Iop_64to32, e));
vex_printf("\nsrc, dst tys are: ");
ppIRType(src_ty);
return grp2_names[opc_aux];
}
-//.. static HChar* nameGrp4 ( Int opc_aux )
-//.. {
-//.. static HChar* grp4_names[8]
-//.. = { "inc", "dec", "???", "???", "???", "???", "???", "???" };
-//.. if (opc_aux < 0 || opc_aux > 1) vpanic("nameGrp4(x86)");
-//.. return grp4_names[opc_aux];
-//.. }
+static HChar* nameGrp4 ( Int opc_aux )
+{
+ static HChar* grp4_names[8]
+ = { "inc", "dec", "???", "???", "???", "???", "???", "???" };
+ if (opc_aux < 0 || opc_aux > 1) vpanic("nameGrp4(amd64)");
+ return grp4_names[opc_aux];
+}
static HChar* nameGrp5 ( Int opc_aux )
{
ULong d = getSDisp32(delta);
DIS(buf, "%s0x%llx()", sorbTxt(pfx), d);
*len = 6;
- vpanic("disAMode(x86):untested amode: 8");
return disAMode_copy2tmp(
handleSegOverride(pfx, mkU64(d)));
}
/* RIP + disp32. */
case 0x05:
- vassert(0);
return 5;
case 0x04: {
static
void codegen_XOR_reg_with_itself ( Prefix pfx, Int size, Int ge_reg )
{
- vassert(0);
-#if 0
+ /* ge_reg is both the G and E reg (they are the same). Hence we can
+ use either the R or E extension bits to show the name as they
+ should be identical. Hmm, let's stay sane ... */
+
IRType ty = szToITy(size);
+ /* stay sane */
+ vassert(getRexR(pfx) == getRexB(pfx));
/* reg := 0 */
- putIReg(size, ge_reg, mkU(ty,0));
+ putIRegR(pfx, size, ge_reg, mkU(ty,0));
/* Flags: C,A,O=0, Z=1, S=0, P=1 */
- stmt( IRStmt_Put( OFFB_CC_OP, mkU32(X86G_CC_OP_COPY) ));
- stmt( IRStmt_Put( OFFB_CC_DEP1, mkU32(X86G_CC_MASK_Z|X86G_CC_MASK_P) ));
- stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) ));
- DIP("xor%c %s, %s\n", nameISize(size),
- nameIReg(size,ge_reg), nameIReg(size,ge_reg) );
-#endif
+ stmt( IRStmt_Put( OFFB_CC_OP, mkU64(AMD64G_CC_OP_COPY) ));
+ stmt( IRStmt_Put( OFFB_CC_DEP1, mkU64(AMD64G_CC_MASK_Z|AMD64G_CC_MASK_P) ));
+ stmt( IRStmt_Put( OFFB_CC_DEP2, mkU64(0) ));
+ DIP("xorZ%c %s, %s\n", nameISize(size),
+ nameIRegR(pfx,size,ge_reg),
+ nameIRegR(pfx,size,ge_reg) );
}
putIRegB(pfx, size, eregOfRM(rm), mkexpr(dst1));
} else
if (addSubCarry && op8 == Iop_Sub8) {
- vassert(0); /* awaiting test case */
helper_SBB( size, dst1, dst0, src );
putIRegB(pfx, size, eregOfRM(rm), mkexpr(dst1));
} else {
}
-/* Generate code to divide ArchRegs RDX:RAX / EDX:EAX / DX:AX / AX by the 32 /
- 16 / 8 bit quantity in the given IRTemp. */
+/* Generate code to divide ArchRegs RDX:RAX / EDX:EAX / DX:AX / AX by
+ the 64 / 32 / 16 / 8 bit quantity in the given IRTemp. */
static
void codegen_div ( Int sz, IRTemp t, Bool signed_divide )
{
- IROp op = signed_divide ? Iop_DivModS64to32 : Iop_DivModU64to32;
- IRTemp src64 = newTemp(Ity_I64);
- IRTemp dst64 = newTemp(Ity_I64);
- switch (sz) {
- case 4:
- assign( src64, binop(Iop_32HLto64,
- getIRegR(PFX_EMPTY,4,R_RDX),
- getIRegR(PFX_EMPTY,4,R_RAX)) );
- assign( dst64, binop(op, mkexpr(src64), mkexpr(t)) );
- putIRegR( PFX_EMPTY, 4, R_RAX, unop(Iop_64to32,mkexpr(dst64)) );
- putIRegR( PFX_EMPTY, 4, R_RDX, unop(Iop_64HIto32,mkexpr(dst64)) );
- break;
+ /* special-case the 64-bit case */
+ if (sz == 8) {
+ IROp op = signed_divide ? Iop_DivModS128to64
+ : Iop_DivModU128to64;
+ IRTemp src128 = newTemp(Ity_V128);
+ IRTemp dst128 = newTemp(Ity_V128);
+ assign( src128, binop(Iop_64HLto128,
+ getIRegR(PFX_EMPTY,8,R_RDX),
+ getIRegR(PFX_EMPTY,8,R_RAX)) );
+ assign( dst128, binop(op, mkexpr(src128), mkexpr(t)) );
+ putIRegR( PFX_EMPTY, 8, R_RAX, unop(Iop_128to64,mkexpr(dst128)) );
+ putIRegR( PFX_EMPTY, 8, R_RDX, unop(Iop_128HIto64,mkexpr(dst128)) );
+ } else {
+ IROp op = signed_divide ? Iop_DivModS64to32
+ : Iop_DivModU64to32;
+ IRTemp src64 = newTemp(Ity_I64);
+ IRTemp dst64 = newTemp(Ity_I64);
+ switch (sz) {
+ case 4:
+ assign( src64, binop(Iop_32HLto64,
+ getIRegR(PFX_EMPTY,4,R_RDX),
+ getIRegR(PFX_EMPTY,4,R_RAX)) );
+ assign( dst64, binop(op, mkexpr(src64), mkexpr(t)) );
+ putIRegR( PFX_EMPTY, 4, R_RAX, unop(Iop_64to32,mkexpr(dst64)) );
+ putIRegR( PFX_EMPTY, 4, R_RDX, unop(Iop_64HIto32,mkexpr(dst64)) );
+ break;
//.. case 2: {
//.. IROp widen3264 = signed_divide ? Iop_32Sto64 : Iop_32Uto64;
//.. IROp widen1632 = signed_divide ? Iop_16Sto32 : Iop_16Uto32;
//.. unop(Iop_64HIto32,mkexpr(dst64)))) );
//.. break;
//.. }
- default: vpanic("codegen_div(amd64)");
+ default: vpanic("codegen_div(amd64)");
+ }
}
}
dst1 = newTemp(ty);
assign(dst1, binop(mkSizedOp(ty,Iop_And8),
getIRegB(pfx,sz,eregOfRM(modrm)),
- mkU(ty,d64)));
+ mkU(ty, d64 & mkSizeMask(sz))));
setFlags_DEP1( Iop_And8, dst1, ty );
DIP("test%c $0x%llx, %s\n",
nameISize(sz), d64,
//.. assign(src, getIReg(sz,eregOfRM(modrm)));
//.. codegen_mulL_A_D ( sz, True, src, nameIReg(sz,eregOfRM(modrm)) );
//.. break;
-//.. case 6: /* DIV */
-//.. delta++;
-//.. assign( t1, getIReg(sz, eregOfRM(modrm)) );
-//.. codegen_div ( sz, t1, False );
-//.. DIP("div%c %s\n", nameISize(sz), nameIReg(sz, eregOfRM(modrm)));
-//.. break;
+ case 6: /* DIV */
+ delta++;
+ assign( t1, getIRegB(pfx, sz, eregOfRM(modrm)) );
+ codegen_div ( sz, t1, False );
+ DIP("div%c %s\n", nameISize(sz),
+ nameIRegB(pfx, sz, eregOfRM(modrm)));
+ break;
case 7: /* IDIV */
delta++;
assign( t1, getIRegB(pfx, sz, eregOfRM(modrm)) );
delta += len;
assign(t1, loadLE(ty,mkexpr(addr)));
switch (gregOfRM(modrm)) {
-//.. case 0: { /* TEST */
-//.. d32 = getUDisp(sz, delta); delta += sz;
-//.. dst1 = newTemp(ty);
-//.. assign(dst1, binop(mkSizedOp(ty,Iop_And8),
-//.. mkexpr(t1), mkU(ty,d32)));
-//.. setFlags_DEP1( Iop_And8, dst1, ty );
-//.. DIP("test%c $0x%x, %s\n", nameISize(sz), d32, dis_buf);
-//.. break;
-//.. }
+ case 0: { /* TEST */
+ d64 = getSDisp(imin(4,sz), delta);
+ delta += imin(4,sz);
+ dst1 = newTemp(ty);
+ assign(dst1, binop(mkSizedOp(ty,Iop_And8),
+ mkexpr(t1),
+ mkU(ty, d64 & mkSizeMask(sz))));
+ setFlags_DEP1( Iop_And8, dst1, ty );
+ DIP("test%c $%lld, %s\n", nameISize(sz), d64, dis_buf);
+ break;
+ }
//.. /* probably OK, but awaiting test case */
//.. case 2: /* NOT */
//.. storeLE( mkexpr(addr), unop(mkSizedOp(ty,Iop_Not8), mkexpr(t1)));
}
-//.. /* Group 4 extended opcodes. */
-//.. static
-//.. UInt dis_Grp4 ( UChar sorb, UInt delta )
-//.. {
-//.. Int alen;
-//.. UChar modrm;
-//.. HChar dis_buf[50];
-//.. IRType ty = Ity_I8;
-//.. IRTemp t1 = newTemp(ty);
-//.. IRTemp t2 = newTemp(ty);
-//..
-//.. modrm = getUChar(delta);
-//.. if (epartIsReg(modrm)) {
-//.. assign(t1, getIReg(1, eregOfRM(modrm)));
-//.. switch (gregOfRM(modrm)) {
+/* Group 4 extended opcodes. */
+static
+ULong dis_Grp4 ( Prefix pfx, ULong delta )
+{
+ Int alen;
+ UChar modrm;
+ HChar dis_buf[50];
+ IRType ty = Ity_I8;
+ IRTemp t1 = newTemp(ty);
+ IRTemp t2 = newTemp(ty);
+
+ modrm = getUChar(delta);
+ if (epartIsReg(modrm)) {
+ assign(t1, getIRegB(pfx, 1, eregOfRM(modrm)));
+ switch (gregOfRM(modrm)) {
//.. case 0: /* INC */
//.. assign(t2, binop(Iop_Add8, mkexpr(t1), mkU8(1)));
//.. putIReg(1, eregOfRM(modrm), mkexpr(t2));
//.. setFlags_INC_DEC( True, t2, ty );
//.. break;
-//.. case 1: /* DEC */
-//.. assign(t2, binop(Iop_Sub8, mkexpr(t1), mkU8(1)));
-//.. putIReg(1, eregOfRM(modrm), mkexpr(t2));
-//.. setFlags_INC_DEC( False, t2, ty );
-//.. break;
-//.. default:
-//.. vex_printf(
-//.. "unhandled Grp4(R) case %d\n", (UInt)gregOfRM(modrm));
-//.. vpanic("Grp4(x86,R)");
-//.. }
-//.. delta++;
-//.. DIP("%sb %s\n", nameGrp4(gregOfRM(modrm)),
-//.. nameIReg(1, eregOfRM(modrm)));
-//.. } else {
-//.. IRTemp addr = disAMode ( &alen, sorb, delta, dis_buf );
-//.. assign( t1, loadLE(ty, mkexpr(addr)) );
-//.. switch (gregOfRM(modrm)) {
+ case 1: /* DEC */
+ assign(t2, binop(Iop_Sub8, mkexpr(t1), mkU8(1)));
+ putIRegB(pfx, 1, eregOfRM(modrm), mkexpr(t2));
+ setFlags_INC_DEC( False, t2, ty );
+ break;
+ default:
+ vex_printf(
+ "unhandled Grp4(R) case %d\n", (UInt)gregOfRM(modrm));
+ vpanic("Grp4(amd64,R)");
+ }
+ delta++;
+ DIP("%sb %s\n", nameGrp4(gregOfRM(modrm)),
+ nameIRegB(pfx, 1, eregOfRM(modrm)));
+ } else {
+ IRTemp addr = disAMode ( &alen, pfx, delta, dis_buf );
+ assign( t1, loadLE(ty, mkexpr(addr)) );
+ switch (gregOfRM(modrm)) {
//.. case 0: /* INC */
//.. assign(t2, binop(Iop_Add8, mkexpr(t1), mkU8(1)));
//.. storeLE( mkexpr(addr), mkexpr(t2) );
//.. storeLE( mkexpr(addr), mkexpr(t2) );
//.. setFlags_INC_DEC( False, t2, ty );
//.. break;
-//.. default:
-//.. vex_printf(
-//.. "unhandled Grp4(M) case %d\n", (UInt)gregOfRM(modrm));
-//.. vpanic("Grp4(x86,M)");
-//.. }
-//.. delta += alen;
-//.. DIP("%sb %s\n", nameGrp4(gregOfRM(modrm)), dis_buf);
-//.. }
-//.. return delta;
-//.. }
+ default:
+ vex_printf(
+ "unhandled Grp4(M) case %d\n", (UInt)gregOfRM(modrm));
+ vpanic("Grp4(amd64,M)");
+ }
+ delta += alen;
+ DIP("%sb %s\n", nameGrp4(gregOfRM(modrm)), dis_buf);
+ }
+ return delta;
+}
/* Group 5 extended opcodes. */
IRType ty = szToITy(sz);
IRTemp t1 = newTemp(ty);
IRTemp t2 = IRTemp_INVALID;
+ IRTemp t3 = IRTemp_INVALID;
modrm = getUChar(delta);
if (epartIsReg(modrm)) {
putIRegB(pfx,sz,eregOfRM(modrm), mkexpr(t2));
break;
case 2: /* call Ev */
-vassert(0);
-#if 0
+ /* Ignore any sz value and operate as if sz==8. */
vassert(sz == 4);
- t2 = newTemp(Ity_I32);
- assign(t2, binop(Iop_Sub32, getIReg(4,R_ESP), mkU32(4)));
- putIReg(4, R_ESP, mkexpr(t2));
- storeLE( mkexpr(t2), mkU32(guest_eip_bbstart+delta+1));
- jmp_treg(Ijk_Call,t1);
+ sz = 8;
+ t3 = newTemp(Ity_I64);
+ assign(t3, getIRegB(pfx,sz,eregOfRM(modrm)));
+ t2 = newTemp(Ity_I64);
+ assign(t2, binop(Iop_Sub64, getIReg64(R_RSP), mkU64(8)));
+ putIReg64(R_RSP, mkexpr(t2));
+ storeLE( mkexpr(t2), mkU64(guest_rip_bbstart+delta+1));
+ jmp_treg(Ijk_Call,t3);
*whatNext = Dis_StopHere;
break;
-#endif
case 4: /* jmp Ev */
-vassert(0);
-#if 0
+ /* Ignore any sz value and operate as if sz==8. */
vassert(sz == 4);
- jmp_treg(Ijk_Boring,t1);
+ sz = 8;
+ t3 = newTemp(Ity_I64);
+ assign(t3, getIRegB(pfx,sz,eregOfRM(modrm)));
+ jmp_treg(Ijk_Boring,t3);
*whatNext = Dis_StopHere;
break;
-#endif
default:
vex_printf(
"unhandled Grp5(R) case %d\n", (Int)gregOfRM(modrm));
nameIRegB(pfx, sz, eregOfRM(modrm)));
} else {
addr = disAMode ( &len, pfx, delta, dis_buf );
- assign(t1, loadLE(ty,mkexpr(addr)));
+ if (gregOfRM(modrm) != 2 && gregOfRM(modrm) != 4)
+ assign(t1, loadLE(ty,mkexpr(addr)));
switch (gregOfRM(modrm)) {
case 0: /* INC */
t2 = newTemp(ty);
storeLE(mkexpr(addr),mkexpr(t2));
break;
case 2: /* call Ev */
-vassert(0);
-#if 0
+ /* Ignore any sz value and operate as if sz==8. */
vassert(sz == 4);
- t2 = newTemp(Ity_I32);
- assign(t2, binop(Iop_Sub32, getIReg(4,R_ESP), mkU32(4)));
- putIReg(4, R_ESP, mkexpr(t2));
- storeLE( mkexpr(t2), mkU32(guest_eip_bbstart+delta+len));
- jmp_treg(Ijk_Call,t1);
+ t3 = newTemp(Ity_I64);
+ assign(t3, loadLE(Ity_I64,mkexpr(addr)));
+ t2 = newTemp(Ity_I64);
+ assign(t2, binop(Iop_Sub64, getIReg64(R_RSP), mkU64(8)));
+ putIReg64(R_RSP, mkexpr(t2));
+ storeLE( mkexpr(t2), mkU64(guest_rip_bbstart+delta+len));
+ jmp_treg(Ijk_Call,t3);
*whatNext = Dis_StopHere;
break;
-#endif
case 4: /* JMP Ev */
-vassert(0);
-#if 0
+ /* Ignore any sz value and operate as if sz==8. */
vassert(sz == 4);
- jmp_treg(Ijk_Boring,t1);
+ t3 = newTemp(Ity_I64);
+ assign(t3, loadLE(Ity_I64,mkexpr(addr)));
+ jmp_treg(Ijk_Boring,t3);
*whatNext = Dis_StopHere;
break;
-#endif
case 6: /* PUSH Ev */
vassert(0);
#if 0
/* E refers to memory */
{
IRTemp addr = disAMode ( &len, pfx, delta0, dis_buf );
- vassert(0); /* awaiting test case */
assign( tmps, loadLE(ty, mkexpr(addr)) );
assign( tmpd, getIRegR(pfx, sz, gregOfRM(rm)) );
case 0xBD: /* MOV imm,eBP */
case 0xBE: /* MOV imm,eSI */
case 0xBF: /* MOV imm,eDI */
- d64 = getSDisp(imin(4,sz),delta);
- delta += imin(4,sz);
- putIRegB(pfx, sz, opc-0xB8,
- mkU(szToITy(sz), d64 & mkSizeMask(sz)));
- DIP("mov%c $%lld,%s\n", nameISize(sz), d64, nameIRegB(pfx,sz,opc-0xB8));
+ /* This is the one-and-only place where 64-bit literals are
+ allowed in the instruction stream. */
+ if (sz == 8) {
+ d64 = getDisp64(delta);
+ delta += sz;
+ putIRegB(pfx, sz, opc-0xB8,
+ mkU(szToITy(sz), d64));
+ DIP("movabsq $%lld,%s\n", d64,
+ nameIRegB(pfx,sz,opc-0xB8));
+ } else {
+ d64 = getSDisp(imin(4,sz),delta);
+ delta += imin(4,sz);
+ putIRegB(pfx, sz, opc-0xB8,
+ mkU(szToITy(sz), d64 & mkSizeMask(sz)));
+ DIP("mov%c $%lld,%s\n", nameISize(sz), d64,
+ nameIRegB(pfx,sz,opc-0xB8));
+ }
break;
case 0xC6: /* MOV Ib,Eb */
do_Mov_I_E:
modrm = getUChar(delta);
if (epartIsReg(modrm)) {
- vassert(0);
delta++; /* mod/rm byte */
d64 = getSDisp(imin(4,sz),delta);
delta += imin(4,sz);
//.. case 0x04: /* ADD Ib, AL */
//.. delta = dis_op_imm_A( 1, Iop_Add8, True, delta, "add" );
//.. break;
-//.. case 0x05: /* ADD Iv, eAX */
-//.. delta = dis_op_imm_A(sz, Iop_Add8, True, delta, "add" );
-//.. break;
-//..
+ case 0x05: /* ADD Iv, eAX */
+ delta = dis_op_imm_A(sz, Iop_Add8, True, delta, "add" );
+ break;
+
//.. case 0x0C: /* OR Ib, AL */
//.. delta = dis_op_imm_A( 1, Iop_Or8, True, delta, "or" );
//.. break;
-//.. case 0x0D: /* OR Iv, eAX */
-//.. delta = dis_op_imm_A( sz, Iop_Or8, True, delta, "or" );
-//.. break;
-//..
+ case 0x0D: /* OR Iv, eAX */
+ delta = dis_op_imm_A( sz, Iop_Or8, True, delta, "or" );
+ break;
+
//.. //-- case 0x14: /* ADC Ib, AL */
//.. //-- delta = dis_op_imm_A( 1, ADC, True, delta, "adc" );
//.. //-- break;
//.. case 0x2C: /* SUB Ib, AL */
//.. delta = dis_op_imm_A(1, Iop_Sub8, True, delta, "sub" );
//.. break;
-//.. case 0x2D: /* SUB Iv, eAX */
-//.. delta = dis_op_imm_A( sz, Iop_Sub8, True, delta, "sub" );
-//.. break;
-//..
+ case 0x2D: /* SUB Iv, eAX */
+ delta = dis_op_imm_A( sz, Iop_Sub8, True, delta, "sub" );
+ break;
+
//.. case 0x34: /* XOR Ib, AL */
//.. delta = dis_op_imm_A( 1, Iop_Xor8, True, delta, "xor" );
//.. break;
//.. case 0x35: /* XOR Iv, eAX */
//.. delta = dis_op_imm_A( sz, Iop_Xor8, True, delta, "xor" );
//.. break;
-//..
-//.. case 0x3C: /* CMP Ib, AL */
-//.. delta = dis_op_imm_A( 1, Iop_Sub8, False, delta, "cmp" );
-//.. break;
+
+ case 0x3C: /* CMP Ib, AL */
+ if (haveF2orF3(pfx)) goto decode_failure;
+ delta = dis_op_imm_A( 1, Iop_Sub8, False, delta, "cmp" );
+ break;
case 0x3D: /* CMP Iv, eAX */
if (haveF2orF3(pfx)) goto decode_failure;
delta = dis_op_imm_A( sz, Iop_Sub8, False, delta, "cmp" );
break;
case 0xA8: /* TEST Ib, AL */
+ if (haveF2orF3(pfx)) goto decode_failure;
delta = dis_op_imm_A( 1, Iop_And8, False, delta, "test" );
break;
case 0xA9: /* TEST Iv, eAX */
+ if (haveF2orF3(pfx)) goto decode_failure;
delta = dis_op_imm_A( sz, Iop_And8, False, delta, "test" );
break;
/* ------------------------ opl Ev, Gv ----------------- */
-//.. case 0x02: /* ADD Eb,Gb */
-//.. delta = dis_op2_E_G ( sorb, False, Iop_Add8, True, 1, delta, "add" );
-//.. break;
+ case 0x02: /* ADD Eb,Gb */
+ if (haveF2orF3(pfx)) goto decode_failure;
+ delta = dis_op2_E_G ( pfx, False, Iop_Add8, True, 1, delta, "add" );
+ break;
case 0x03: /* ADD Ev,Gv */
if (haveF2orF3(pfx)) goto decode_failure;
delta = dis_op2_E_G ( pfx, False, Iop_Add8, True, sz, delta, "add" );
break;
-//.. case 0x0A: /* OR Eb,Gb */
-//.. delta = dis_op2_E_G ( sorb, False, Iop_Or8, True, 1, delta, "or" );
-//.. break;
-//.. case 0x0B: /* OR Ev,Gv */
-//.. delta = dis_op2_E_G ( sorb, False, Iop_Or8, True, sz, delta, "or" );
-//.. break;
-//.. //--
+ case 0x0A: /* OR Eb,Gb */
+ delta = dis_op2_E_G ( pfx, False, Iop_Or8, True, 1, delta, "or" );
+ break;
+ case 0x0B: /* OR Ev,Gv */
+ delta = dis_op2_E_G ( pfx, False, Iop_Or8, True, sz, delta, "or" );
+ break;
+//--
//.. //-- case 0x12: /* ADC Eb,Gb */
//.. //-- delta = dis_op2_E_G ( sorb, True, ADC, True, 1, delta, "adc" );
//.. //-- break;
//.. case 0x1B: /* SBB Ev,Gv */
//.. delta = dis_op2_E_G ( sorb, True, Iop_Sub8, True, sz, delta, "sbb" );
//.. break;
-//..
-//.. case 0x22: /* AND Eb,Gb */
-//.. delta = dis_op2_E_G ( sorb, False, Iop_And8, True, 1, delta, "and" );
-//.. break;
-//.. case 0x23: /* AND Ev,Gv */
-//.. delta = dis_op2_E_G ( sorb, False, Iop_And8, True, sz, delta, "and" );
-//.. break;
-//..
-//.. case 0x2A: /* SUB Eb,Gb */
-//.. delta = dis_op2_E_G ( sorb, False, Iop_Sub8, True, 1, delta, "sub" );
-//.. break;
+
+ case 0x22: /* AND Eb,Gb */
+ if (haveF2orF3(pfx)) goto decode_failure;
+ delta = dis_op2_E_G ( pfx, False, Iop_And8, True, 1, delta, "and" );
+ break;
+ case 0x23: /* AND Ev,Gv */
+ if (haveF2orF3(pfx)) goto decode_failure;
+ delta = dis_op2_E_G ( pfx, False, Iop_And8, True, sz, delta, "and" );
+ break;
+
+ case 0x2A: /* SUB Eb,Gb */
+ if (haveF2orF3(pfx)) goto decode_failure;
+ delta = dis_op2_E_G ( pfx, False, Iop_Sub8, True, 1, delta, "sub" );
+ break;
case 0x2B: /* SUB Ev,Gv */
+ if (haveF2orF3(pfx)) goto decode_failure;
delta = dis_op2_E_G ( pfx, False, Iop_Sub8, True, sz, delta, "sub" );
break;
-//.. case 0x32: /* XOR Eb,Gb */
-//.. delta = dis_op2_E_G ( sorb, False, Iop_Xor8, True, 1, delta, "xor" );
-//.. break;
-//.. case 0x33: /* XOR Ev,Gv */
-//.. delta = dis_op2_E_G ( sorb, False, Iop_Xor8, True, sz, delta, "xor" );
-//.. break;
-//..
+ case 0x32: /* XOR Eb,Gb */
+ if (haveF2orF3(pfx)) goto decode_failure;
+ delta = dis_op2_E_G ( pfx, False, Iop_Xor8, True, 1, delta, "xor" );
+ break;
+ case 0x33: /* XOR Ev,Gv */
+ if (haveF2orF3(pfx)) goto decode_failure;
+ delta = dis_op2_E_G ( pfx, False, Iop_Xor8, True, sz, delta, "xor" );
+ break;
+
//.. case 0x3A: /* CMP Eb,Gb */
//.. delta = dis_op2_E_G ( sorb, False, Iop_Sub8, False, 1, delta, "cmp" );
//.. break;
break;
case 0x84: /* TEST Eb,Gb */
+ if (haveF2orF3(pfx)) goto decode_failure;
delta = dis_op2_E_G ( pfx, False, Iop_And8, False, 1, delta, "test" );
break;
case 0x85: /* TEST Ev,Gv */
+ if (haveF2orF3(pfx)) goto decode_failure;
delta = dis_op2_E_G ( pfx, False, Iop_And8, False, sz, delta, "test" );
break;
delta = dis_op2_G_E ( pfx, False, Iop_Add8, True, sz, delta, "add" );
break;
-//.. case 0x08: /* OR Gb,Eb */
-//.. delta = dis_op2_G_E ( sorb, False, Iop_Or8, True, 1, delta, "or" );
-//.. break;
+ case 0x08: /* OR Gb,Eb */
+ if (haveF2orF3(pfx)) goto decode_failure;
+ delta = dis_op2_G_E ( pfx, False, Iop_Or8, True, 1, delta, "or" );
+ break;
case 0x09: /* OR Gv,Ev */
if (haveF2orF3(pfx)) goto decode_failure;
delta = dis_op2_G_E ( pfx, False, Iop_Or8, True, sz, delta, "or" );
//.. case 0x18: /* SBB Gb,Eb */
//.. delta = dis_op2_G_E ( sorb, True, Iop_Sub8, True, 1, delta, "sbb" );
//.. break;
-//.. case 0x19: /* SBB Gv,Ev */
-//.. delta = dis_op2_G_E ( sorb, True, Iop_Sub8, True, sz, delta, "sbb" );
-//.. break;
-//..
+ case 0x19: /* SBB Gv,Ev */
+ delta = dis_op2_G_E ( pfx, True, Iop_Sub8, True, sz, delta, "sbb" );
+ break;
+
//.. case 0x20: /* AND Gb,Eb */
//.. delta = dis_op2_G_E ( sorb, False, Iop_And8, True, 1, delta, "and" );
//.. break;
if (haveF2orF3(pfx)) goto decode_failure;
delta = dis_op2_G_E ( pfx, False, Iop_And8, True, sz, delta, "and" );
break;
-//..
-//.. case 0x28: /* SUB Gb,Eb */
-//.. delta = dis_op2_G_E ( sorb, False, Iop_Sub8, True, 1, delta, "sub" );
-//.. break;
+
+ case 0x28: /* SUB Gb,Eb */
+ if (haveF2orF3(pfx)) goto decode_failure;
+ delta = dis_op2_G_E ( pfx, False, Iop_Sub8, True, 1, delta, "sub" );
+ break;
case 0x29: /* SUB Gv,Ev */
+ if (haveF2orF3(pfx)) goto decode_failure;
delta = dis_op2_G_E ( pfx, False, Iop_Sub8, True, sz, delta, "sub" );
break;
//.. delta = dis_op2_G_E ( sorb, False, Iop_Xor8, True, 1, delta, "xor" );
//.. break;
case 0x31: /* XOR Gv,Ev */
+ if (haveF2orF3(pfx)) goto decode_failure;
delta = dis_op2_G_E ( pfx, False, Iop_Xor8, True, sz, delta, "xor" );
break;
case 0x5E: /* POP eSI */
case 0x5F: /* POP eDI */
case 0x5C: /* POP eSP */
+ if (haveF2orF3(pfx)) goto decode_failure;
vassert(sz == 2 || sz == 4 || sz == 8);
if (sz == 4)
sz = 8; /* there is no encoding for 32-bit pop in 64-bit mode */
/* This is the Right Way, in that the value to be pushed is
established before %rsp is changed, so that pushq %rsp
correctly pushes the old value. */
+ if (haveF2orF3(pfx)) goto decode_failure;
vassert(sz == 2 || sz == 4 || sz == 8);
if (sz == 4)
sz = 8; /* there is no encoding for 32-bit push in 64-bit mode */
break;
/* ------------------------ (Grp2 extensions) ---------- */
-#if 0
+
case 0xC0: /* Grp2 Ib,Eb */
modrm = getUChar(delta);
am_sz = lengthAMode(pfx,delta);
delta = dis_Grp2 ( pfx, delta, modrm, am_sz, d_sz, sz,
mkU8(d64 & 0xFF), NULL );
break;
-#endif
+
case 0xC1: /* Grp2 Ib,Ev */
modrm = getUChar(delta);
am_sz = lengthAMode(pfx,delta);
mkU8(d64 & 0xFF), NULL );
break;
-//.. case 0xD0: /* Grp2 1,Eb */
-//.. modrm = getUChar(delta);
-//.. am_sz = lengthAMode(delta);
-//.. d_sz = 0;
-//.. d32 = 1;
-//.. sz = 1;
-//.. delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz,
-//.. mkU8(d32), NULL );
-//.. break;
+ case 0xD0: /* Grp2 1,Eb */
+ modrm = getUChar(delta);
+ am_sz = lengthAMode(pfx,delta);
+ d_sz = 0;
+ d64 = 1;
+ sz = 1;
+ delta = dis_Grp2 ( pfx, delta, modrm, am_sz, d_sz, sz,
+ mkU8(d64), NULL );
+ break;
case 0xD1: /* Grp2 1,Ev */
modrm = getUChar(delta);
delta = dis_Grp3 ( pfx, sz, delta );
break;
-//.. /* ------------------------ (Grp4 extensions) ---------- */
-//..
-//.. case 0xFE: /* Grp4 Eb */
-//.. delta = dis_Grp4 ( sorb, delta );
-//.. break;
+ /* ------------------------ (Grp4 extensions) ---------- */
+
+ case 0xFE: /* Grp4 Eb */
+ delta = dis_Grp4 ( pfx, delta );
+ break;
/* ------------------------ (Grp5 extensions) ---------- */
delta = dis_movx_E_G ( pfx, delta, 2, sz, False );
break;
-//.. case 0xBE: /* MOVSXb Eb,Gv */
-//.. delta = dis_movx_E_G ( sorb, delta, 1, 4, True );
-//.. break;
-//.. case 0xBF: /* MOVSXw Ew,Gv */
-//.. delta = dis_movx_E_G ( sorb, delta, 2, 4, True );
-//.. break;
-//..
+ case 0xBE: /* MOVSXb Eb,Gv */
+ if (sz != 4 && sz != 8)
+ goto decode_failure;
+ delta = dis_movx_E_G ( pfx, delta, 1, sz, True );
+ break;
+ case 0xBF: /* MOVSXw Ew,Gv */
+ if (sz != 4 && sz != 8)
+ goto decode_failure;
+ delta = dis_movx_E_G ( pfx, delta, 2, sz, True );
+ break;
+
//.. //-- /* =-=-=-=-=-=-=-=-=-=-= MOVNTI -=-=-=-=-=-=-=-=-= */
//.. //--
//.. //-- case 0xC3: /* MOVNTI Gv,Ev */