|
From: <sv...@va...> - 2005-08-12 23:04:51
|
Author: sewardj
Date: 2005-08-13 00:04:48 +0100 (Sat, 13 Aug 2005)
New Revision: 1331
Log:
Implement cmpxchg8b. Sheesh. What a total dog of an instruction.
Modified:
trunk/priv/guest-x86/toIR.c
trunk/priv/host-x86/isel.c
Modified: trunk/priv/guest-x86/toIR.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-x86/toIR.c 2005-08-10 18:22:54 UTC (rev 1330)
+++ trunk/priv/guest-x86/toIR.c 2005-08-12 23:04:48 UTC (rev 1331)
@@ -11709,10 +11709,72 @@
case 0xB1: /* CMPXCHG Gv,Ev */
delta =3D dis_cmpxchg_G_E ( sorb, sz, delta );
break;
-//-- case 0xC7: /* CMPXCHG8B Gv */
-//-- eip =3D dis_cmpxchg8b ( cb, sorb, eip );
-//-- break;
-//--=20
+
+ case 0xC7: { /* CMPXCHG8B Gv (0F C7 /1) */
+ IRTemp m64_old =3D newTemp(Ity_I64);
+ IRTemp m64_new =3D newTemp(Ity_I64);
+ IRTemp da_old =3D newTemp(Ity_I64);
+ IRTemp da_new =3D newTemp(Ity_I64);
+ IRTemp cb_old =3D newTemp(Ity_I64);
+ IRTemp flags_old =3D newTemp(Ity_I32);
+ IRTemp flags_new =3D newTemp(Ity_I32);
+ IRTemp cond =3D newTemp(Ity_I8);
+
+ /* Decode, and generate address. */
+ modrm =3D getIByte(delta);
+ if (epartIsReg(modrm)) goto decode_failure;
+ if (gregOfRM(modrm) !=3D 1) goto decode_failure;
+ addr =3D disAMode ( &alen, sorb, delta, dis_buf );
+ delta +=3D alen;
+
+ /* Fetch the old 64-bit values and compute the guard. */
+ assign( m64_old, loadLE(Ity_I64, mkexpr(addr) ));
+ assign( da_old, binop(Iop_32HLto64,=20
+ getIReg(4,R_EDX), getIReg(4,R_EAX)) );
+ assign( cb_old, binop(Iop_32HLto64,=20
+ getIReg(4,R_ECX), getIReg(4,R_EBX)) );
+
+ assign( cond,=20
+ unop(Iop_1Uto8,=20
+ binop(Iop_CmpEQ64, mkexpr(da_old), mkexpr(m64_old)=
)) );
+
+ /* Compute new %edx:%eax and m64 values, and put in place */
+ assign( da_new,=20
+ IRExpr_Mux0X(mkexpr(cond), mkexpr(m64_old), mkexpr(da_o=
ld)));
+ assign( m64_new,
+ IRExpr_Mux0X(mkexpr(cond), mkexpr(m64_old), mkexpr(cb_o=
ld)));
+
+ putIReg(4, R_EDX, unop(Iop_64HIto32, mkexpr(da_new)) );
+ putIReg(4, R_EAX, unop(Iop_64to32, mkexpr(da_new)) );
+ storeLE( mkexpr(addr), mkexpr(m64_new) );
+
+ /* Copy the guard into the Z flag and leave the others unchange=
d */
+ assign( flags_old, widenUto32(mk_x86g_calculate_eflags_all()));
+ assign(=20
+ flags_new,
+ binop(Iop_Or32,
+ binop(Iop_And32, mkexpr(flags_old),=20
+ mkU32(~X86G_CC_MASK_Z)),
+ binop(Iop_Shl32,=20
+ binop(Iop_And32,=20
+ unop(Iop_8Uto32, mkexpr(cond)), mkU32(1)),=
=20
+ mkU8(X86G_CC_SHIFT_Z)) ));
+
+ stmt( IRStmt_Put( OFFB_CC_OP, mkU32(X86G_CC_OP_COPY) ));
+ stmt( IRStmt_Put( OFFB_CC_DEP1, mkexpr(flags_new) ));
+ stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) ));
+ /* Set NDEP even though it isn't used. This makes
+ redundant-PUT elimination of previous stores to this field
+ work better. */
+ stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) ));
+
+ /* Sheesh. Aren't you glad it was me and not you that had to
+ write and validate all this grunge? */
+
+ DIP("cmpxchg8b %s\n", dis_buf);
+ break;
+ }
+
/* =3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- CPUID -=3D-=3D-=3D-=3D-=3D=
-=3D-=3D-=3D-=3D-=3D-=3D */
=20
case 0xA2: { /* CPUID */
Modified: trunk/priv/host-x86/isel.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/host-x86/isel.c 2005-08-10 18:22:54 UTC (rev 1330)
+++ trunk/priv/host-x86/isel.c 2005-08-12 23:04:48 UTC (rev 1331)
@@ -1721,7 +1721,8 @@
=20
/* CmpNE64 */
if (e->tag =3D=3D Iex_Binop=20
- && e->Iex.Binop.op =3D=3D Iop_CmpNE64) {
+ && (e->Iex.Binop.op =3D=3D Iop_CmpNE64
+ || e->Iex.Binop.op =3D=3D Iop_CmpEQ64)) {
HReg hi1, hi2, lo1, lo2;
HReg tHi =3D newVRegI(env);
HReg tLo =3D newVRegI(env);
@@ -1734,6 +1735,7 @@
addInstr(env, X86Instr_Alu32R(Xalu_OR,X86RMI_Reg(tHi), tLo));
switch (e->Iex.Binop.op) {
case Iop_CmpNE64: return Xcc_NZ;
+ case Iop_CmpEQ64: return Xcc_Z;
default: vpanic("iselCondCode(x86): CmpXX64");
}
}
|