|
From: <sv...@va...> - 2005-08-24 17:36:22
|
Author: sewardj
Date: 2005-08-24 18:36:20 +0100 (Wed, 24 Aug 2005)
New Revision: 1357
Log:
Merge r1352: amd64 BT{,R,S,C} Gv, Ev. Also fix bug in x86 version.
Modified:
branches/VEX_3_0_BRANCH/priv/guest-amd64/toIR.c
branches/VEX_3_0_BRANCH/priv/guest-x86/toIR.c
Modified: branches/VEX_3_0_BRANCH/priv/guest-amd64/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
--- branches/VEX_3_0_BRANCH/priv/guest-amd64/toIR.c 2005-08-24 17:31:24 U=
TC (rev 1356)
+++ branches/VEX_3_0_BRANCH/priv/guest-amd64/toIR.c 2005-08-24 17:36:20 U=
TC (rev 1357)
@@ -6478,153 +6478,156 @@
//.. if (amt_is_literal) delta++;
//.. return delta;
//.. }
-//..=20
-//..=20
-//.. /* Handle BT/BTS/BTR/BTC Gv, Ev. Apparently b-size is not
-//.. required. */
-//..=20
-//.. typedef enum { BtOpNone, BtOpSet, BtOpReset, BtOpComp } BtOp;
-//..=20
-//.. static Char* nameBtOp ( BtOp op )
-//.. {
-//.. switch (op) {
-//.. case BtOpNone: return "";
-//.. case BtOpSet: return "s";
-//.. case BtOpReset: return "r";
-//.. case BtOpComp: return "c";
-//.. default: vpanic("nameBtOp(x86)");
-//.. }
-//.. }
-//..=20
-//..=20
-//.. static
-//.. UInt dis_bt_G_E ( UChar sorb, Int sz, Long delta, BtOp op )
-//.. {
-//.. HChar dis_buf[50];
-//.. UChar modrm;
-//.. Int len;
-//.. IRTemp t_fetched, t_bitno0, t_bitno1, t_bitno2, t_addr0,=20
-//.. t_addr1, t_esp, t_mask;
-//..=20
-//.. vassert(sz =3D=3D 2 || sz =3D=3D 4);
-//..=20
-//.. t_fetched =3D t_bitno0 =3D t_bitno1 =3D t_bitno2=20
-//.. =3D t_addr0 =3D t_addr1 =3D t_esp =3D t_mask =3D IRTem=
p_INVALID;
-//..=20
-//.. t_fetched =3D newTemp(Ity_I8);
-//.. t_bitno0 =3D newTemp(Ity_I32);
-//.. t_bitno1 =3D newTemp(Ity_I32);
-//.. t_bitno2 =3D newTemp(Ity_I8);
-//.. t_addr1 =3D newTemp(Ity_I32);
-//.. modrm =3D getUChar(delta);
-//..=20
-//.. assign( t_bitno0, widenUto32(getIReg(sz, gregOfRM(modrm))) );
-//.. =20
-//.. if (epartIsReg(modrm)) {
-//.. delta++;
-//.. /* Get it onto the client's stack. */
-//.. t_esp =3D newTemp(Ity_I32);
-//.. t_addr0 =3D newTemp(Ity_I32);
-//..=20
-//.. assign( t_esp, binop(Iop_Sub32, getIReg(4, R_ESP), mkU32(sz))=
);
-//.. putIReg(4, R_ESP, mkexpr(t_esp));
-//..=20
-//.. storeLE( mkexpr(t_esp), getIReg(sz, eregOfRM(modrm)) );
-//..=20
-//.. /* Make t_addr0 point at it. */
-//.. assign( t_addr0, mkexpr(t_esp) );
-//..=20
-//.. /* Mask out upper bits of the shift amount, since we're doing=
a
-//.. reg. */
-//.. assign( t_bitno1, binop(Iop_And32,=20
-//.. mkexpr(t_bitno0),=20
-//.. mkU32(sz =3D=3D 4 ? 31 : 15)) );
-//..=20
-//.. } else {
-//.. t_addr0 =3D disAMode ( &len, sorb, delta, dis_buf );
-//.. delta +=3D len;
-//.. assign( t_bitno1, mkexpr(t_bitno0) );
-//.. }
-//.. =20
-//.. /* At this point: t_addr0 is the address being operated on. If =
it
-//.. was a reg, we will have pushed it onto the client's stack.
-//.. t_bitno1 is the bit number, suitably masked in the case of a
-//.. reg. */
-//.. =20
-//.. /* Now the main sequence. */
-//.. assign( t_addr1,=20
-//.. binop(Iop_Add32,=20
-//.. mkexpr(t_addr0),=20
-//.. binop(Iop_Sar32, mkexpr(t_bitno1), mkU8(3))) );
-//..=20
-//.. /* t_addr1 now holds effective address */
-//..=20
-//.. assign( t_bitno2,=20
-//.. unop(Iop_32to8,=20
-//.. binop(Iop_And32, mkexpr(t_bitno1), mkU32(7))) );
-//..=20
-//.. /* t_bitno2 contains offset of bit within byte */
-//..=20
-//.. if (op !=3D BtOpNone) {
-//.. t_mask =3D newTemp(Ity_I8);
-//.. assign( t_mask, binop(Iop_Shl8, mkU8(1), mkexpr(t_bitno2)) );
-//.. }
-//..=20
-//.. /* t_mask is now a suitable byte mask */
-//..=20
-//.. assign( t_fetched, loadLE(Ity_I8, mkexpr(t_addr1)) );
-//..=20
-//.. if (op !=3D BtOpNone) {
-//.. switch (op) {
-//.. case BtOpSet:=20
-//.. storeLE( mkexpr(t_addr1),=20
-//.. binop(Iop_Or8, mkexpr(t_fetched),=20
-//.. mkexpr(t_mask)) );
-//.. break;
-//.. case BtOpComp:=20
-//.. storeLE( mkexpr(t_addr1),=20
-//.. binop(Iop_Xor8, mkexpr(t_fetched),=20
-//.. mkexpr(t_mask)) );
-//.. break;
-//.. case BtOpReset:=20
-//.. storeLE( mkexpr(t_addr1),=20
-//.. binop(Iop_And8, mkexpr(t_fetched),=20
-//.. unop(Iop_Not8, mkexpr(t_mask))=
) );
-//.. break;
-//.. default:=20
-//.. vpanic("dis_bt_G_E(x86)");
-//.. }
-//.. }
-//.. =20
-//.. /* Side effect done; now get selected bit into Carry flag */
-//.. /* Flags: C=3Dselected bit, O,S,Z,A,P undefined, so are set to z=
ero. */
-//.. stmt( IRStmt_Put( OFFB_CC_OP, mkU32(X86G_CC_OP_COPY) ));
-//.. stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) ));
-//.. stmt( IRStmt_Put(=20
-//.. OFFB_CC_DEP1,
-//.. binop(Iop_And32,
-//.. binop(Iop_Shr32,=20
-//.. unop(Iop_8Uto32, mkexpr(t_fetched)),
-//.. mkexpr(t_bitno2)),
-//.. mkU32(1)))
-//.. );
-//..=20
-//.. /* Move reg operand from stack back to reg */
-//.. if (epartIsReg(modrm)) {
-//.. /* t_esp still points at it. */
-//.. putIReg(sz, eregOfRM(modrm), loadLE(szToITy(sz), mkexpr(t_esp=
)) );
-//.. putIReg(4, R_ESP, binop(Iop_Add32, mkexpr(t_esp), mkU32(sz)) =
);
-//.. }
-//..=20
-//.. DIP("bt%s%c %s, %s\n",
-//.. nameBtOp(op), nameISize(sz), nameIReg(sz, gregOfRM(modrm)),=20
-//.. ( epartIsReg(modrm) ? nameIReg(sz, eregOfRM(modrm)) : dis_bu=
f ) );
-//.. =20
-//.. return delta;
-//.. }
=20
=20
+/* Handle BT/BTS/BTR/BTC Gv, Ev. Apparently b-size is not
+ required. */
=20
+typedef enum { BtOpNone, BtOpSet, BtOpReset, BtOpComp } BtOp;
+
+static HChar* nameBtOp ( BtOp op )
+{
+ switch (op) {
+ case BtOpNone: return "";
+ case BtOpSet: return "s";
+ case BtOpReset: return "r";
+ case BtOpComp: return "c";
+ default: vpanic("nameBtOp(amd64)");
+ }
+}
+
+
+static
+ULong dis_bt_G_E ( Prefix pfx, Int sz, Long delta, BtOp op )
+{
+ HChar dis_buf[50];
+ UChar modrm;
+ Int len;
+ IRTemp t_fetched, t_bitno0, t_bitno1, t_bitno2, t_addr0,=20
+ t_addr1, t_rsp, t_mask;
+
+ vassert(sz =3D=3D 2 || sz =3D=3D 4 || sz =3D=3D 8);
+
+ t_fetched =3D t_bitno0 =3D t_bitno1 =3D t_bitno2=20
+ =3D t_addr0 =3D t_addr1 =3D t_rsp =3D t_mask =3D IRTemp_INV=
ALID;
+
+ t_fetched =3D newTemp(Ity_I8);
+ t_bitno0 =3D newTemp(Ity_I64);
+ t_bitno1 =3D newTemp(Ity_I64);
+ t_bitno2 =3D newTemp(Ity_I8);
+ t_addr1 =3D newTemp(Ity_I64);
+ modrm =3D getUChar(delta);
+
+ assign( t_bitno0, widenSto64(getIRegG(sz, pfx, modrm)) );
+ =20
+ if (epartIsReg(modrm)) {
+ delta++;
+ /* Get it onto the client's stack. */
+ t_rsp =3D newTemp(Ity_I64);
+ t_addr0 =3D newTemp(Ity_I64);
+
+ assign( t_rsp, binop(Iop_Sub64, getIReg64(R_RSP), mkU64(sz)) );
+ putIReg64(R_RSP, mkexpr(t_rsp));
+
+ storeLE( mkexpr(t_rsp), getIRegE(sz, pfx, modrm) );
+
+ /* Make t_addr0 point at it. */
+ assign( t_addr0, mkexpr(t_rsp) );
+
+ /* Mask out upper bits of the shift amount, since we're doing a
+ reg. */
+ assign( t_bitno1, binop(Iop_And64,=20
+ mkexpr(t_bitno0),=20
+ mkU64(sz =3D=3D 8 ? 63 : sz =3D=3D 4 ? 31 =
: 15)) );
+
+ } else {
+ t_addr0 =3D disAMode ( &len, pfx, delta, dis_buf, 0 );
+ delta +=3D len;
+ assign( t_bitno1, mkexpr(t_bitno0) );
+ }
+ =20
+ /* At this point: t_addr0 is the address being operated on. If it
+ was a reg, we will have pushed it onto the client's stack.
+ t_bitno1 is the bit number, suitably masked in the case of a
+ reg. */
+ =20
+ /* Now the main sequence. */
+ assign( t_addr1,=20
+ binop(Iop_Add64,=20
+ mkexpr(t_addr0),=20
+ binop(Iop_Sar64, mkexpr(t_bitno1), mkU8(3))) );
+
+ /* t_addr1 now holds effective address */
+
+ assign( t_bitno2,=20
+ unop(Iop_64to8,=20
+ binop(Iop_And64, mkexpr(t_bitno1), mkU64(7))) );
+
+ /* t_bitno2 contains offset of bit within byte */
+
+ if (op !=3D BtOpNone) {
+ t_mask =3D newTemp(Ity_I8);
+ assign( t_mask, binop(Iop_Shl8, mkU8(1), mkexpr(t_bitno2)) );
+ }
+
+ /* t_mask is now a suitable byte mask */
+
+ assign( t_fetched, loadLE(Ity_I8, mkexpr(t_addr1)) );
+
+ if (op !=3D BtOpNone) {
+ switch (op) {
+ case BtOpSet:=20
+ storeLE( mkexpr(t_addr1),=20
+ binop(Iop_Or8, mkexpr(t_fetched),=20
+ mkexpr(t_mask)) );
+ break;
+ case BtOpComp:=20
+ storeLE( mkexpr(t_addr1),=20
+ binop(Iop_Xor8, mkexpr(t_fetched),=20
+ mkexpr(t_mask)) );
+ break;
+ case BtOpReset:=20
+ storeLE( mkexpr(t_addr1),=20
+ binop(Iop_And8, mkexpr(t_fetched),=20
+ unop(Iop_Not8, mkexpr(t_mask))) );
+ break;
+ default:=20
+ vpanic("dis_bt_G_E(amd64)");
+ }
+ }
+=20
+ /* Side effect done; now get selected bit into Carry flag */
+ /* Flags: C=3Dselected bit, O,S,Z,A,P undefined, so are set to zero. =
*/
+ stmt( IRStmt_Put( OFFB_CC_OP, mkU64(AMD64G_CC_OP_COPY) ));
+ stmt( IRStmt_Put( OFFB_CC_DEP2, mkU64(0) ));
+ stmt( IRStmt_Put(=20
+ OFFB_CC_DEP1,
+ binop(Iop_And64,
+ binop(Iop_Shr64,=20
+ unop(Iop_8Uto64, mkexpr(t_fetched)),
+ mkexpr(t_bitno2)),
+ mkU64(1)))
+ );
+ /* 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, mkU64(0) ));
+
+ /* Move reg operand from stack back to reg */
+ if (epartIsReg(modrm)) {
+ /* t_esp still points at it. */
+ putIRegE(sz, pfx, modrm, loadLE(szToITy(sz), mkexpr(t_rsp)) );
+ putIReg64(R_RSP, binop(Iop_Add64, mkexpr(t_rsp), mkU64(sz)) );
+ }
+
+ DIP("bt%s%c %s, %s\n",
+ nameBtOp(op), nameISize(sz), nameIRegG(sz, pfx, modrm),=20
+ ( epartIsReg(modrm) ? nameIRegE(sz, pfx, modrm) : dis_buf ) );
+=20
+ return delta;
+}
+
+
+
/* Handle BSF/BSR. Only v-size seems necessary. */
static
ULong dis_bs_E_G ( Prefix pfx, Int sz, Long delta, Bool fwds )
@@ -12903,21 +12906,32 @@
goto decode_failure;
}
=20
-//.. /* =3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- BT/BTS/BTR/BTC =3D-=3D=
-=3D-=3D-=3D-=3D-=3D */
-//..=20
-//.. case 0xA3: /* BT Gv,Ev */
-//.. delta =3D dis_bt_G_E ( sorb, sz, delta, BtOpNone );
-//.. break;
-//.. case 0xB3: /* BTR Gv,Ev */
-//.. delta =3D dis_bt_G_E ( sorb, sz, delta, BtOpReset );
-//.. break;
-//.. case 0xAB: /* BTS Gv,Ev */
-//.. delta =3D dis_bt_G_E ( sorb, sz, delta, BtOpSet );
-//.. break;
-//.. case 0xBB: /* BTC Gv,Ev */
-//.. delta =3D dis_bt_G_E ( sorb, sz, delta, BtOpComp );
-//.. break;
+ /* =3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- BT/BTS/BTR/BTC =3D-=3D-=3D=
-=3D-=3D-=3D-=3D */
=20
+ /* All of these are possible at sizes 2, 4 and 8, but until size
+ 2 and 4 test cases show up, only handle size 8. */
+
+ case 0xA3: /* BT Gv,Ev */
+ if (haveF2orF3(pfx)) goto decode_failure;
+ if (sz !=3D 8) goto decode_failure;
+ delta =3D dis_bt_G_E ( pfx, sz, delta, BtOpNone );
+ break;
+ case 0xB3: /* BTR Gv,Ev */
+ if (haveF2orF3(pfx)) goto decode_failure;
+ if (sz !=3D 8) goto decode_failure;
+ delta =3D dis_bt_G_E ( pfx, sz, delta, BtOpReset );
+ break;
+ case 0xAB: /* BTS Gv,Ev */
+ if (haveF2orF3(pfx)) goto decode_failure;
+ if (sz !=3D 8) goto decode_failure;
+ delta =3D dis_bt_G_E ( pfx, sz, delta, BtOpSet );
+ break;
+ case 0xBB: /* BTC Gv,Ev */
+ if (haveF2orF3(pfx)) goto decode_failure;
+ if (sz !=3D 8) goto decode_failure;
+ delta =3D dis_bt_G_E ( pfx, sz, delta, BtOpComp );
+ break;
+
/* =3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- CMOV =3D-=3D-=3D-=3D-=3D-=3D=
-=3D-=3D-=3D-=3D-=3D-=3D */
=20
case 0x40:
Modified: branches/VEX_3_0_BRANCH/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
--- branches/VEX_3_0_BRANCH/priv/guest-x86/toIR.c 2005-08-24 17:31:24 UTC=
(rev 1356)
+++ branches/VEX_3_0_BRANCH/priv/guest-x86/toIR.c 2005-08-24 17:36:20 UTC=
(rev 1357)
@@ -5653,7 +5653,7 @@
t_addr1 =3D newTemp(Ity_I32);
modrm =3D getIByte(delta);
=20
- assign( t_bitno0, widenUto32(getIReg(sz, gregOfRM(modrm))) );
+ assign( t_bitno0, widenSto32(getIReg(sz, gregOfRM(modrm))) );
=20
if (epartIsReg(modrm)) {
delta++;
|