|
From: <sv...@va...> - 2013-01-26 11:48:06
|
sewardj 2013-01-26 11:47:55 +0000 (Sat, 26 Jan 2013)
New Revision: 2664
Log:
Infrastructure cleanup: change type of the condition field of
IRExpr_Mux0X from Ity_I8 to Ity_I1. This makes more sense, makes it
consistent with condition fields in IRStmt_Dirty and IRStmt_Exit, and
avoids some pointless 1Uto8 casting of the condition, in many cases.
Fixes for s390 are from Florian.
Also, make a small extension to ir_opt.c, that allows the constant
folder to look backwards through arbitrary expressions even in flat
IR. This makes it possible to do arbitrary tree folding in ir_opt,
which is where it belongs. Use this to implement the folding rule
CmpNE32(1Uto32(b), 0) ==> b.
Modified files:
trunk/priv/guest_amd64_toIR.c
trunk/priv/guest_arm_helpers.c
trunk/priv/guest_arm_toIR.c
trunk/priv/guest_ppc_toIR.c
trunk/priv/guest_s390_toIR.c
trunk/priv/guest_x86_toIR.c
trunk/priv/host_amd64_isel.c
trunk/priv/host_arm_isel.c
trunk/priv/host_ppc_isel.c
trunk/priv/host_s390_isel.c
trunk/priv/host_x86_isel.c
trunk/priv/ir_defs.c
trunk/priv/ir_opt.c
Modified: trunk/priv/guest_arm_helpers.c (+1 -1)
===================================================================
--- trunk/priv/guest_arm_helpers.c 2013-01-26 11:39:13 +00:00 (rev 2663)
+++ trunk/priv/guest_arm_helpers.c 2013-01-26 11:47:55 +00:00 (rev 2664)
@@ -798,7 +798,7 @@
*/
return
IRExpr_Mux0X(
- unop(Iop_32to8, cc_ndep),
+ binop(Iop_CmpNE32, cc_ndep, mkU32(0)),
/* case oldC == 0 */
unop(Iop_1Uto32, binop(Iop_CmpLT32U, cc_dep2, cc_dep1)),
/* case oldC != 0 */
Modified: trunk/priv/ir_opt.c (+32 -7)
===================================================================
--- trunk/priv/ir_opt.c 2013-01-26 11:39:13 +00:00 (rev 2663)
+++ trunk/priv/ir_opt.c 2013-01-26 11:47:55 +00:00 (rev 2664)
@@ -1305,6 +1305,25 @@
// return r;
//}
+/* Helper for arbitrary expression pattern matching in flat IR. If
+ 'e' is a reference to a tmp, look it up in env -- repeatedly, if
+ necessary -- until it resolves to a non-tmp. Note that this can
+ return NULL if it can't resolve 'e' to a new expression, which will
+ be the case if 'e' is instead defined by an IRStmt (IRDirty or
+ LLSC). */
+static IRExpr* chase ( IRExpr** env, IRExpr* e )
+{
+ /* Why is this loop guaranteed to terminate? Because all tmps must
+ have definitions before use, hence a tmp cannot be bound
+ (directly or indirectly) to itself. */
+ while (e->tag == Iex_RdTmp) {
+ if (0) { vex_printf("chase "); ppIRExpr(e); vex_printf("\n"); }
+ e = env[(Int)e->Iex.RdTmp.tmp];
+ if (e == NULL) break;
+ }
+ return e;
+}
+
static IRExpr* fold_Expr ( IRExpr** env, IRExpr* e )
{
Int shift;
@@ -2164,6 +2183,15 @@
e2 = mkZeroOfPrimopResultType(e->Iex.Binop.op);
break;
}
+ /* CmpNE32(1Uto32(b), 0) ==> b */
+ if (isZeroU32(e->Iex.Binop.arg2)) {
+ IRExpr* a1 = chase(env, e->Iex.Binop.arg1);
+ if (a1 && a1->tag == Iex_Unop
+ && a1->Iex.Unop.op == Iop_1Uto32) {
+ e2 = a1->Iex.Unop.arg;
+ break;
+ }
+ }
break;
case Iop_CmpEQ32:
@@ -2186,20 +2214,17 @@
case Iex_Mux0X:
/* Mux0X */
-
/* is the discriminant is a constant? */
if (e->Iex.Mux0X.cond->tag == Iex_Const) {
- Bool zero;
/* assured us by the IR type rules */
- vassert(e->Iex.Mux0X.cond->Iex.Const.con->tag == Ico_U8);
- zero = toBool(0 == (0xFF & e->Iex.Mux0X.cond
- ->Iex.Const.con->Ico.U8));
- e2 = zero ? e->Iex.Mux0X.expr0 : e->Iex.Mux0X.exprX;
+ vassert(e->Iex.Mux0X.cond->Iex.Const.con->tag == Ico_U1);
+ e2 = e->Iex.Mux0X.cond->Iex.Const.con->Ico.U1
+ ? e->Iex.Mux0X.exprX : e->Iex.Mux0X.expr0;
}
else
/* are the arms identical? (pretty weedy test) */
if (sameIRExprs(env, e->Iex.Mux0X.expr0,
- e->Iex.Mux0X.exprX)) {
+ e->Iex.Mux0X.exprX)) {
e2 = e->Iex.Mux0X.expr0;
}
break;
Modified: trunk/priv/guest_s390_toIR.c (+1 -1)
===================================================================
--- trunk/priv/guest_s390_toIR.c 2013-01-26 11:39:13 +00:00 (rev 2663)
+++ trunk/priv/guest_s390_toIR.c 2013-01-26 11:47:55 +00:00 (rev 2664)
@@ -240,7 +240,7 @@
{
vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
- return IRExpr_Mux0X(unop(Iop_1Uto8, condition), iffalse, iftrue);
+ return IRExpr_Mux0X(condition, iffalse, iftrue);
}
/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
Modified: trunk/priv/guest_ppc_toIR.c (+83 -75)
===================================================================
--- trunk/priv/guest_ppc_toIR.c 2013-01-26 11:39:13 +00:00 (rev 2663)
+++ trunk/priv/guest_ppc_toIR.c 2013-01-26 11:47:55 +00:00 (rev 2664)
@@ -799,9 +799,8 @@
return IRExpr_Mux0X(
/* if (hi32 == (lo32 >>s 31)) */
- unop(Iop_1Uto8,
- binop(Iop_CmpEQ32, mkexpr(hi32),
- binop( Iop_Sar32, mkexpr(lo32), mkU8(31)))),
+ binop(Iop_CmpEQ32, mkexpr(hi32),
+ binop( Iop_Sar32, mkexpr(lo32), mkU8(31))),
/* else: sign dep saturate: 1->0x80000000, 0->0x7FFFFFFF */
binop(Iop_Add32, mkU32(0x7FFFFFFF),
binop(Iop_Shr32, mkexpr(hi32), mkU8(31))),
@@ -822,7 +821,7 @@
return IRExpr_Mux0X(
/* if (top 32 bits of t64 are 0) */
- unop(Iop_1Uto8, binop(Iop_CmpEQ32, mkexpr(hi32), mkU32(0))),
+ binop(Iop_CmpEQ32, mkexpr(hi32), mkU32(0)),
/* else: positive saturate -> 0xFFFFFFFF */
mkU32(0xFFFFFFFF),
/* then: within unsigned-32 range: lo half good enough */
@@ -1451,8 +1450,9 @@
because otherwise the Shr is a shift by the word size when
mask denotes zero. For rotates by immediates, a lot of
this junk gets folded out. */
- return IRExpr_Mux0X( mask, /* zero rotate */ src,
- /* non-zero rotate */ rot );
+ return IRExpr_Mux0X( binop(Iop_CmpNE8, mask, mkU8(0)),
+ /* zero rotate */ src,
+ /* non-zero rotate */ rot );
}
/* Standard effective address calc: (rA + rB) */
@@ -2231,7 +2231,7 @@
xer_ca
= IRExpr_Mux0X(
/* shift amt > 31 ? */
- unop(Iop_1Uto8, binop(Iop_CmpLT32U, mkU32(31), argR)),
+ binop(Iop_CmpLT32U, mkU32(31), argR),
/* no -- be like srawi */
unop(Iop_1Uto32, binop(Iop_CmpNE32, xer_ca, mkU32(0))),
/* yes -- get sign bit of argL */
@@ -2351,7 +2351,7 @@
xer_ca
= IRExpr_Mux0X(
/* shift amt > 31 ? */
- unop(Iop_1Uto8, binop(Iop_CmpLT64U, mkU64(31), argR)),
+ binop(Iop_CmpLT64U, mkU64(31), argR),
/* no -- be like srawi */
unop(Iop_1Uto32, binop(Iop_CmpNE64, xer_ca, mkU64(0))),
/* yes -- get sign bit of argL */
@@ -2405,7 +2405,7 @@
xer_ca
= IRExpr_Mux0X(
/* shift amt > 63 ? */
- unop(Iop_1Uto8, binop(Iop_CmpLT64U, mkU64(63), argR)),
+ binop(Iop_CmpLT64U, mkU64(63), argR),
/* no -- be like sradi */
unop(Iop_1Uto32, binop(Iop_CmpNE64, xer_ca, mkU64(0))),
/* yes -- get sign bit of argL */
@@ -3855,7 +3855,7 @@
// Iop_Clz32 undefined for arg==0, so deal with that case:
irx = binop(Iop_CmpNE32, lo32, mkU32(0));
assign(rA, mkWidenFrom32(ty,
- IRExpr_Mux0X( unop(Iop_1Uto8, irx),
+ IRExpr_Mux0X( irx,
mkU32(32),
unop(Iop_Clz32, lo32)),
False));
@@ -3962,7 +3962,7 @@
flag_rC ? ".":"", rA_addr, rS_addr);
// Iop_Clz64 undefined for arg==0, so deal with that case:
irx = binop(Iop_CmpNE64, mkexpr(rS), mkU64(0));
- assign(rA, IRExpr_Mux0X( unop(Iop_1Uto8, irx),
+ assign(rA, IRExpr_Mux0X( irx,
mkU64(64),
unop(Iop_Clz64, mkexpr(rS)) ));
// TODO: alternatively: assign(rA, verbose_Clz64(rS));
@@ -6043,7 +6043,7 @@
IRTemp rA = newTemp(ty);
IRTemp rS = newTemp(ty);
IRTemp rB = newTemp(ty);
- IRTemp outofrange = newTemp(Ity_I8);
+ IRTemp outofrange = newTemp(Ity_I1);
IRTemp rS_lo32 = newTemp(Ity_I32);
IRTemp rB_lo32 = newTemp(Ity_I32);
IRExpr* e_tmp;
@@ -6091,9 +6091,7 @@
assign( sh_amt, binop(Iop_And32, mkU32(0x3F),
mkexpr(rB_lo32)) );
assign( outofrange,
- unop( Iop_1Uto8,
- binop(Iop_CmpLT32U, mkU32(31),
- mkexpr(sh_amt)) ));
+ binop(Iop_CmpLT32U, mkU32(31), mkexpr(sh_amt)) );
e_tmp = binop( Iop_Sar32,
mkexpr(rS_lo32),
unop( Iop_32to8,
@@ -6190,9 +6188,7 @@
*/
assign( sh_amt, binop(Iop_And64, mkU64(0x7F), mkexpr(rB)) );
assign( outofrange,
- unop( Iop_1Uto8,
- binop(Iop_CmpLT64U, mkU64(63),
- mkexpr(sh_amt)) ));
+ binop(Iop_CmpLT64U, mkU64(63), mkexpr(sh_amt)) );
assign( rA,
binop( Iop_Sar64,
mkexpr(rS),
@@ -7378,8 +7374,7 @@
// = (cc_b0 == 0) ? frC : frB
assign( frD,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- binop(Iop_CmpEQ32, mkexpr(cc_b0), mkU32(0))),
+ binop(Iop_CmpEQ32, mkexpr(cc_b0), mkU32(0)),
mkexpr(frB),
mkexpr(frC) ));
@@ -8263,21 +8258,29 @@
/* need to preserve sign of zero */
/* frD = (fabs(frB) > 9e18) ? frB :
(sign(frB)) ? -fabs((double)r_tmp64) : (double)r_tmp64 */
- assign(frD, IRExpr_Mux0X( unop(Iop_32to8,
- binop(Iop_CmpF64,
- IRExpr_Const(IRConst_F64(9e18)),
- unop(Iop_AbsF64, mkexpr(frB)))),
- IRExpr_Mux0X(unop(Iop_32to8,
- binop(Iop_Shr32,
- unop(Iop_64HIto32,
- unop(Iop_ReinterpF64asI64,
- mkexpr(frB))), mkU8(31))),
- binop(Iop_I64StoF64, mkU32(0), mkexpr(r_tmp64) ),
- unop(Iop_NegF64,
- unop( Iop_AbsF64,
- binop(Iop_I64StoF64, mkU32(0),
- mkexpr(r_tmp64)) )) ),
- mkexpr(frB)));
+ assign(frD, IRExpr_Mux0X(
+ binop(Iop_CmpNE8,
+ unop(Iop_32to8,
+ binop(Iop_CmpF64,
+ IRExpr_Const(IRConst_F64(9e18)),
+ unop(Iop_AbsF64, mkexpr(frB)))),
+ mkU8(0)),
+ IRExpr_Mux0X(
+ binop(Iop_CmpNE32,
+ binop(Iop_Shr32,
+ unop(Iop_64HIto32,
+ unop(Iop_ReinterpF64asI64,
+ mkexpr(frB))),
+ mkU8(31)),
+ mkU32(0)),
+ binop(Iop_I64StoF64, mkU32(0), mkexpr(r_tmp64) ),
+ unop(Iop_NegF64,
+ unop( Iop_AbsF64,
+ binop(Iop_I64StoF64, mkU32(0),
+ mkexpr(r_tmp64)) ))
+ ),
+ mkexpr(frB)
+ ));
break;
default:
@@ -11836,22 +11839,22 @@
assign( res1, unop(Iop_64HIto32, mkexpr(lo64)) );
assign( res0, unop(Iop_64to32, mkexpr(lo64)) );
- b3_result = IRExpr_Mux0X(unop(Iop_1Uto8, is_NaN_32(b3)),
+ b3_result = IRExpr_Mux0X(is_NaN_32(b3),
// else: result is from the Iop_QFtoI32{s|u}x4_RZ
mkexpr(res3),
// then: result is 0x{8|0}80000000
mkU32(un_signed ? 0x00000000 : 0x80000000));
- b2_result = IRExpr_Mux0X(unop(Iop_1Uto8, is_NaN_32(b2)),
+ b2_result = IRExpr_Mux0X(is_NaN_32(b2),
// else: result is from the Iop_QFtoI32{s|u}x4_RZ
mkexpr(res2),
// then: result is 0x{8|0}80000000
mkU32(un_signed ? 0x00000000 : 0x80000000));
- b1_result = IRExpr_Mux0X(unop(Iop_1Uto8, is_NaN_32(b1)),
+ b1_result = IRExpr_Mux0X(is_NaN_32(b1),
// else: result is from the Iop_QFtoI32{s|u}x4_RZ
mkexpr(res1),
// then: result is 0x{8|0}80000000
mkU32(un_signed ? 0x00000000 : 0x80000000));
- b0_result = IRExpr_Mux0X(unop(Iop_1Uto8, is_NaN_32(b0)),
+ b0_result = IRExpr_Mux0X(is_NaN_32(b0),
// else: result is from the Iop_QFtoI32{s|u}x4_RZ
mkexpr(res0),
// then: result is 0x{8|0}80000000
@@ -12778,11 +12781,11 @@
#define SNAN_MASK 0x0008000000000000ULL
return
- IRExpr_Mux0X(unop(Iop_1Uto8, mkexpr(frA_isSNaN)),
+ IRExpr_Mux0X(mkexpr(frA_isSNaN),
/* else: if frB is a SNaN */
- IRExpr_Mux0X(unop(Iop_1Uto8, mkexpr(frB_isSNaN)),
+ IRExpr_Mux0X(mkexpr(frB_isSNaN),
/* else: if frB is a QNaN */
- IRExpr_Mux0X(unop(Iop_1Uto8, mkexpr(frB_isQNaN)),
+ IRExpr_Mux0X(mkexpr(frB_isQNaN),
/* else: frA is a QNaN, so result = frB */
mkexpr(frB_I64),
/* then: result = frA */
@@ -12804,10 +12807,9 @@
unop( Iop_ReinterpI64asF64,
mkexpr( src2 ) ) ) );
- return IRExpr_Mux0X( unop( Iop_1Uto8,
- binop( Iop_CmpEQ32,
- mkexpr( src1cmpsrc2 ),
- mkU32( isMin ? PPC_CMP_LT : PPC_CMP_GT ) ) ),
+ return IRExpr_Mux0X( binop( Iop_CmpEQ32,
+ mkexpr( src1cmpsrc2 ),
+ mkU32( isMin ? PPC_CMP_LT : PPC_CMP_GT ) ),
/* else: use src2 */
mkexpr( src2 ),
/* then: use src1 */
@@ -12838,11 +12840,10 @@
assign(anyNaN, mkOR1(is_NaN(frA_I64), is_NaN(frB_I64)));
#define MINUS_ZERO 0x8000000000000000ULL
- return IRExpr_Mux0X( unop( Iop_1Uto8,
- /* If both arguments are zero . . . */
- mkAND1( mkexpr( frA_isZero ), mkexpr( frB_isZero ) ) ),
+ return IRExpr_Mux0X( /* If both arguments are zero . . . */
+ mkAND1( mkexpr( frA_isZero ), mkexpr( frB_isZero ) ),
/* else: check if either input is a NaN*/
- IRExpr_Mux0X( unop( Iop_1Uto8, mkexpr( anyNaN ) ),
+ IRExpr_Mux0X( mkexpr( anyNaN ),
/* else: use "comparison helper" */
_get_maxmin_fp_cmp( frB_I64, frA_I64, isMin ),
/* then: use "NaN helper" */
@@ -12850,11 +12851,10 @@
/* then: if frA is -0 and isMin==True, return -0;
* else if frA is +0 and isMin==False; return +0;
* otherwise, simply return frB. */
- IRExpr_Mux0X( unop( Iop_1Uto8,
- binop( Iop_CmpEQ32,
- unop( Iop_64HIto32,
- mkexpr( frA_I64 ) ),
- mkU32( isMin ? 0x80000000 : 0 ) ) ),
+ IRExpr_Mux0X( binop( Iop_CmpEQ32,
+ unop( Iop_64HIto32,
+ mkexpr( frA_I64 ) ),
+ mkU32( isMin ? 0x80000000 : 0 ) ),
mkexpr( frB_I64 ),
mkU64( isMin ? MINUS_ZERO : 0ULL ) ) );
}
@@ -12910,24 +12910,32 @@
/* frD = (fabs(frB) > 9e18) ? frB :
(sign(frB)) ? -fabs((double)intermediateResult) : (double)intermediateResult */
assign( frD,
- IRExpr_Mux0X( unop( Iop_32to8,
- binop( Iop_CmpF64,
- IRExpr_Const( IRConst_F64( 9e18 ) ),
- unop( Iop_AbsF64, mkexpr( frB ) ) ) ),
- IRExpr_Mux0X( unop( Iop_32to8,
- binop( Iop_Shr32,
- unop( Iop_64HIto32,
- mkexpr( frB_I64 ) ),
- mkU8( 31 ) ) ),
- binop( Iop_I64StoF64,
- mkU32( 0 ),
- mkexpr( intermediateResult ) ),
- unop( Iop_NegF64,
- unop( Iop_AbsF64,
- binop( Iop_I64StoF64,
- mkU32( 0 ),
- mkexpr( intermediateResult ) ) ) ) ),
- mkexpr( frB ) ) );
+ IRExpr_Mux0X(
+ binop( Iop_CmpNE8,
+ unop( Iop_32to8,
+ binop( Iop_CmpF64,
+ IRExpr_Const( IRConst_F64( 9e18 ) ),
+ unop( Iop_AbsF64, mkexpr( frB ) ) ) ),
+ mkU8(0) ),
+ IRExpr_Mux0X(
+ binop( Iop_CmpNE32,
+ binop( Iop_Shr32,
+ unop( Iop_64HIto32,
+ mkexpr( frB_I64 ) ),
+ mkU8( 31 ) ),
+ mkU32(0) ),
+ binop( Iop_I64StoF64,
+ mkU32( 0 ),
+ mkexpr( intermediateResult ) ),
+ unop( Iop_NegF64,
+ unop( Iop_AbsF64,
+ binop( Iop_I64StoF64,
+ mkU32( 0 ),
+ mkexpr( intermediateResult ) ) ) )
+ ),
+ mkexpr( frB )
+ )
+ );
/* See Appendix "Floating-Point Round to Integer Model" in ISA doc.
* If frB is a SNAN, then frD <- frB, with bit 12 set to '1'.
@@ -12940,7 +12948,7 @@
binop( Iop_And32, hi32, mkU32( 0x00080000 ) ),
mkU32( 0 ) ) ) );
- return IRExpr_Mux0X( unop( Iop_1Uto8, mkexpr( is_SNAN ) ),
+ return IRExpr_Mux0X( mkexpr( is_SNAN ),
mkexpr( frD ),
unop( Iop_ReinterpI64asF64,
binop( Iop_Xor64,
@@ -17569,7 +17577,7 @@
UInt bi = ifieldRegC( theInstr );
putIReg(
rT,
- IRExpr_Mux0X( unop(Iop_32to8,getCRbit( bi )),
+ IRExpr_Mux0X( binop(Iop_CmpNE32, getCRbit( bi ), mkU32(0)),
getIReg(rB),
rA == 0 ? (mode64 ? mkU64(0) : mkU32(0))
: getIReg(rA) )
Modified: trunk/priv/host_s390_isel.c (+6 -27)
===================================================================
--- trunk/priv/host_s390_isel.c 2013-01-26 11:39:13 +00:00 (rev 2663)
+++ trunk/priv/host_s390_isel.c 2013-01-26 11:47:55 +00:00 (rev 2664)
@@ -1742,43 +1742,22 @@
/* --------- MULTIPLEX --------- */
case Iex_Mux0X: {
IRExpr *cond_expr;
- HReg dst, tmp, rX;
- s390_opnd_RMI cond, r0, zero;
+ HReg dst, rX;
+ s390_opnd_RMI r0;
cond_expr = expr->Iex.Mux0X.cond;
+ vassert(typeOfIRExpr(env->type_env, cond_expr) == Ity_I1);
+
dst = newVRegI(env);
r0 = s390_isel_int_expr_RMI(env, expr->Iex.Mux0X.expr0);
rX = s390_isel_int_expr(env, expr->Iex.Mux0X.exprX);
size = sizeofIRType(typeOfIRExpr(env->type_env, expr->Iex.Mux0X.exprX));
- if (cond_expr->tag == Iex_Unop && cond_expr->Iex.Unop.op == Iop_1Uto8) {
- s390_cc_t cc = s390_isel_cc(env, cond_expr->Iex.Unop.arg);
+ s390_cc_t cc = s390_isel_cc(env, cond_expr);
- addInstr(env, s390_insn_move(size, dst, rX));
- addInstr(env, s390_insn_cond_move(size, s390_cc_invert(cc), dst, r0));
- return dst;
- }
-
- /* Assume the condition is true and move rX to the destination reg. */
addInstr(env, s390_insn_move(size, dst, rX));
-
- /* Compute the condition ... */
- cond = s390_isel_int_expr_RMI(env, cond_expr);
-
- /* tmp = cond & 0xFF */
- tmp = newVRegI(env);
- addInstr(env, s390_insn_load_immediate(4, tmp, 0xFF));
- addInstr(env, s390_insn_alu(4, S390_ALU_AND, tmp, cond));
-
- /* ... and compare it with zero */
- zero = s390_opnd_imm(0);
- addInstr(env, s390_insn_compare(4, tmp, zero, 0 /* signed */));
-
- /* ... and if it compared equal move r0 to the destination reg. */
- size = sizeofIRType(typeOfIRExpr(env->type_env, expr->Iex.Mux0X.expr0));
- addInstr(env, s390_insn_cond_move(size, S390_CC_E, dst, r0));
-
+ addInstr(env, s390_insn_cond_move(size, s390_cc_invert(cc), dst, r0));
return dst;
}
Modified: trunk/priv/guest_amd64_toIR.c (+119 -143)
===================================================================
--- trunk/priv/guest_amd64_toIR.c 2013-01-26 11:39:13 +00:00 (rev 2663)
+++ trunk/priv/guest_amd64_toIR.c 2013-01-26 11:47:55 +00:00 (rev 2664)
@@ -1819,17 +1819,21 @@
vpanic("setFlags_DEP1_DEP2_shift(amd64)");
}
+ /* guard :: Ity_I8. We need to convert it to I1. */
+ IRTemp guardB = newTemp(Ity_I1);
+ assign( guardB, binop(Iop_CmpNE8, mkexpr(guard), mkU8(0)) );
+
/* DEP1 contains the result, DEP2 contains the undershifted value. */
stmt( IRStmt_Put( OFFB_CC_OP,
- IRExpr_Mux0X( mkexpr(guard),
+ IRExpr_Mux0X( mkexpr(guardB),
IRExpr_Get(OFFB_CC_OP,Ity_I64),
mkU64(ccOp))) );
stmt( IRStmt_Put( OFFB_CC_DEP1,
- IRExpr_Mux0X( mkexpr(guard),
+ IRExpr_Mux0X( mkexpr(guardB),
IRExpr_Get(OFFB_CC_DEP1,Ity_I64),
widenUto64(mkexpr(res)))) );
stmt( IRStmt_Put( OFFB_CC_DEP2,
- IRExpr_Mux0X( mkexpr(guard),
+ IRExpr_Mux0X( mkexpr(guardB),
IRExpr_Get(OFFB_CC_DEP2,Ity_I64),
widenUto64(mkexpr(resUS)))) );
}
@@ -3597,21 +3601,25 @@
assign(oldFlags, mk_amd64g_calculate_rflags_all());
+ /* rot_amt64 :: Ity_I8. We need to convert it to I1. */
+ IRTemp rot_amt64b = newTemp(Ity_I1);
+ assign(rot_amt64b, binop(Iop_CmpNE8, mkexpr(rot_amt64), mkU8(0)) );
+
/* CC_DEP1 is the rotated value. CC_NDEP is flags before. */
stmt( IRStmt_Put( OFFB_CC_OP,
- IRExpr_Mux0X( mkexpr(rot_amt64),
+ IRExpr_Mux0X( mkexpr(rot_amt64b),
IRExpr_Get(OFFB_CC_OP,Ity_I64),
mkU64(ccOp))) );
stmt( IRStmt_Put( OFFB_CC_DEP1,
- IRExpr_Mux0X( mkexpr(rot_amt64),
+ IRExpr_Mux0X( mkexpr(rot_amt64b),
IRExpr_Get(OFFB_CC_DEP1,Ity_I64),
widenUto64(mkexpr(dst1)))) );
stmt( IRStmt_Put( OFFB_CC_DEP2,
- IRExpr_Mux0X( mkexpr(rot_amt64),
+ IRExpr_Mux0X( mkexpr(rot_amt64b),
IRExpr_Get(OFFB_CC_DEP2,Ity_I64),
mkU64(0))) );
stmt( IRStmt_Put( OFFB_CC_NDEP,
- IRExpr_Mux0X( mkexpr(rot_amt64),
+ IRExpr_Mux0X( mkexpr(rot_amt64b),
IRExpr_Get(OFFB_CC_NDEP,Ity_I64),
mkexpr(oldFlags))) );
} /* if (isRotate) */
@@ -4656,8 +4664,7 @@
IRTemp res64 = newTemp(Ity_I64);
assign(res64,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- binop(Iop_CmpEQ64, mkexpr(src64x), mkU64(0))),
+ binop(Iop_CmpEQ64, mkexpr(src64x), mkU64(0)),
unop(Iop_Clz64, mkexpr(src64x)),
mkU64(8 * sizeofIRType(ty))
));
@@ -4796,13 +4803,14 @@
static void put_ST ( Int i, IRExpr* value )
{
- put_ST_UNCHECKED( i,
- IRExpr_Mux0X( get_ST_TAG(i),
- /* 0 means empty */
- value,
- /* non-0 means full */
- mkQNaN64()
- )
+ put_ST_UNCHECKED(
+ i,
+ IRExpr_Mux0X( binop(Iop_CmpNE8, get_ST_TAG(i), mkU8(0)),
+ /* 0 means empty */
+ value,
+ /* non-0 means full */
+ mkQNaN64()
+ )
);
}
@@ -4823,7 +4831,7 @@
static IRExpr* get_ST ( Int i )
{
return
- IRExpr_Mux0X( get_ST_TAG(i),
+ IRExpr_Mux0X( binop(Iop_CmpNE8, get_ST_TAG(i), mkU8(0)),
/* 0 means empty */
mkQNaN64(),
/* non-0 means full */
@@ -5000,11 +5008,10 @@
assign( t32, e32 );
return
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- binop(Iop_CmpLT64U,
- unop(Iop_32Uto64,
- binop(Iop_Add32, mkexpr(t32), mkU32(32768))),
- mkU64(65536))),
+ binop(Iop_CmpLT64U,
+ unop(Iop_32Uto64,
+ binop(Iop_Add32, mkexpr(t32), mkU32(32768))),
+ mkU64(65536)),
mkU16( 0x8000 ),
unop(Iop_32to16, mkexpr(t32)));
}
@@ -5742,8 +5749,7 @@
DIP("fcmovb %%st(%u), %%st(0)\n", r_src);
put_ST_UNCHECKED(0,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- mk_amd64g_calculate_condition(AMD64CondB)),
+ mk_amd64g_calculate_condition(AMD64CondB),
get_ST(0), get_ST(r_src)) );
break;
@@ -5752,8 +5758,7 @@
DIP("fcmovz %%st(%u), %%st(0)\n", r_src);
put_ST_UNCHECKED(0,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- mk_amd64g_calculate_condition(AMD64CondZ)),
+ mk_amd64g_calculate_condition(AMD64CondZ),
get_ST(0), get_ST(r_src)) );
break;
@@ -5762,8 +5767,7 @@
DIP("fcmovbe %%st(%u), %%st(0)\n", r_src);
put_ST_UNCHECKED(0,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- mk_amd64g_calculate_condition(AMD64CondBE)),
+ mk_amd64g_calculate_condition(AMD64CondBE),
get_ST(0), get_ST(r_src)) );
break;
@@ -5772,8 +5776,7 @@
DIP("fcmovu %%st(%u), %%st(0)\n", r_src);
put_ST_UNCHECKED(0,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- mk_amd64g_calculate_condition(AMD64CondP)),
+ mk_amd64g_calculate_condition(AMD64CondP),
get_ST(0), get_ST(r_src)) );
break;
@@ -5910,8 +5913,7 @@
DIP("fcmovnb %%st(%u), %%st(0)\n", r_src);
put_ST_UNCHECKED(0,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- mk_amd64g_calculate_condition(AMD64CondNB)),
+ mk_amd64g_calculate_condition(AMD64CondNB),
get_ST(0), get_ST(r_src)) );
break;
@@ -5921,8 +5923,7 @@
put_ST_UNCHECKED(
0,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- mk_amd64g_calculate_condition(AMD64CondNZ)),
+ mk_amd64g_calculate_condition(AMD64CondNZ),
get_ST(0),
get_ST(r_src)
)
@@ -5935,8 +5936,7 @@
put_ST_UNCHECKED(
0,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- mk_amd64g_calculate_condition(AMD64CondNBE)),
+ mk_amd64g_calculate_condition(AMD64CondNBE),
get_ST(0),
get_ST(r_src)
)
@@ -5949,8 +5949,7 @@
put_ST_UNCHECKED(
0,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- mk_amd64g_calculate_condition(AMD64CondNP)),
+ mk_amd64g_calculate_condition(AMD64CondNP),
get_ST(0),
get_ST(r_src)
)
@@ -6889,7 +6888,7 @@
assign(
g1,
IRExpr_Mux0X(
- unop(Iop_1Uto8,binop(Iop_CmpLT64U,mkexpr(amt),mkU64(size))),
+ binop(Iop_CmpLT64U,mkexpr(amt),mkU64(size)),
mkU64(0),
binop(op, mkexpr(g0), mkexpr(amt8))
)
@@ -6899,7 +6898,7 @@
assign(
g1,
IRExpr_Mux0X(
- unop(Iop_1Uto8,binop(Iop_CmpLT64U,mkexpr(amt),mkU64(size))),
+ binop(Iop_CmpLT64U,mkexpr(amt),mkU64(size)),
binop(op, mkexpr(g0), mkU8(size-1)),
binop(op, mkexpr(g0), mkexpr(amt8))
)
@@ -7376,7 +7375,7 @@
*/
return
IRExpr_Mux0X(
- mkexpr(amt),
+ binop(Iop_CmpNE8, mkexpr(amt), mkU8(0)),
mkexpr(base),
binop(Iop_Or64,
binop(Iop_Shl64, mkexpr(base), mkexpr(amt)),
@@ -7397,7 +7396,7 @@
*/
return
IRExpr_Mux0X(
- mkexpr(amt),
+ binop(Iop_CmpNE8, mkexpr(amt), mkU8(0)),
mkexpr(base),
binop(Iop_Or64,
binop(Iop_Shr64, mkexpr(base), mkexpr(amt)),
@@ -7765,7 +7764,7 @@
IRTemp dst = newTemp(ty);
IRTemp src64 = newTemp(Ity_I64);
IRTemp dst64 = newTemp(Ity_I64);
- IRTemp src8 = newTemp(Ity_I8);
+ IRTemp srcB = newTemp(Ity_I1);
vassert(sz == 8 || sz == 4 || sz == 2);
@@ -7789,16 +7788,13 @@
/* First, widen src to 64 bits if it is not already. */
assign( src64, widenUto64(mkexpr(src)) );
- /* Generate an 8-bit expression which is zero iff the original is
+ /* Generate a bool expression which is zero iff the original is
zero, and nonzero otherwise. Ask for a CmpNE version which, if
instrumented by Memcheck, is instrumented expensively, since
this may be used on the output of a preceding movmskb insn,
which has been known to be partially defined, and in need of
careful handling. */
- assign( src8,
- unop(Iop_1Uto8,
- binop(Iop_ExpCmpNE64,
- mkexpr(src64), mkU64(0))) );
+ assign( srcB, binop(Iop_ExpCmpNE64, mkexpr(src64), mkU64(0)) );
/* Flags: Z is 1 iff source value is zero. All others
are undefined -- we force them to zero. */
@@ -7806,7 +7802,7 @@
stmt( IRStmt_Put( OFFB_CC_DEP2, mkU64(0) ));
stmt( IRStmt_Put(
OFFB_CC_DEP1,
- IRExpr_Mux0X( mkexpr(src8),
+ IRExpr_Mux0X( mkexpr(srcB),
/* src==0 */
mkU64(AMD64G_CC_MASK_Z),
/* src!=0 */
@@ -7846,7 +7842,7 @@
/* The main computation, guarding against zero. */
assign( dst64,
IRExpr_Mux0X(
- mkexpr(src8),
+ mkexpr(srcB),
/* src == 0 -- leave dst unchanged */
widenUto64( getIRegG( sz, pfx, modrm ) ),
/* src != 0 */
@@ -7971,7 +7967,7 @@
IRTemp dest = newTemp(ty);
IRTemp dest2 = newTemp(ty);
IRTemp acc2 = newTemp(ty);
- IRTemp cond8 = newTemp(Ity_I8);
+ IRTemp cond = newTemp(Ity_I1);
IRTemp addr = IRTemp_INVALID;
UChar rm = getUChar(delta0);
@@ -7993,9 +7989,9 @@
assign( src, getIRegG(size, pfx, rm) );
assign( acc, getIRegRAX(size) );
setFlags_DEP1_DEP2(Iop_Sub8, acc, dest, ty);
- assign( cond8, unop(Iop_1Uto8, mk_amd64g_calculate_condition(AMD64CondZ)) );
- assign( dest2, IRExpr_Mux0X(mkexpr(cond8), mkexpr(dest), mkexpr(src)) );
- assign( acc2, IRExpr_Mux0X(mkexpr(cond8), mkexpr(dest), mkexpr(acc)) );
+ assign( cond, mk_amd64g_calculate_condition(AMD64CondZ) );
+ assign( dest2, IRExpr_Mux0X(mkexpr(cond), mkexpr(dest), mkexpr(src)) );
+ assign( acc2, IRExpr_Mux0X(mkexpr(cond), mkexpr(dest), mkexpr(acc)) );
putIRegRAX(size, mkexpr(acc2));
putIRegE(size, pfx, rm, mkexpr(dest2));
DIP("cmpxchg%c %s,%s\n", nameISize(size),
@@ -8010,9 +8006,9 @@
assign( src, getIRegG(size, pfx, rm) );
assign( acc, getIRegRAX(size) );
setFlags_DEP1_DEP2(Iop_Sub8, acc, dest, ty);
- assign( cond8, unop(Iop_1Uto8, mk_amd64g_calculate_condition(AMD64CondZ)) );
- assign( dest2, IRExpr_Mux0X(mkexpr(cond8), mkexpr(dest), mkexpr(src)) );
- assign( acc2, IRExpr_Mux0X(mkexpr(cond8), mkexpr(dest), mkexpr(acc)) );
+ assign( cond, mk_amd64g_calculate_condition(AMD64CondZ) );
+ assign( dest2, IRExpr_Mux0X(mkexpr(cond), mkexpr(dest), mkexpr(src)) );
+ assign( acc2, IRExpr_Mux0X(mkexpr(cond), mkexpr(dest), mkexpr(acc)) );
putIRegRAX(size, mkexpr(acc2));
storeLE( mkexpr(addr), mkexpr(dest2) );
DIP("cmpxchg%c %s,%s\n", nameISize(size),
@@ -8033,8 +8029,8 @@
NULL, mkexpr(acc), NULL, mkexpr(src) )
));
setFlags_DEP1_DEP2(Iop_Sub8, acc, dest, ty);
- assign( cond8, unop(Iop_1Uto8, mk_amd64g_calculate_condition(AMD64CondZ)) );
- assign( acc2, IRExpr_Mux0X(mkexpr(cond8), mkexpr(dest), mkexpr(acc)) );
+ assign( cond, mk_amd64g_calculate_condition(AMD64CondZ) );
+ assign( acc2, IRExpr_Mux0X(mkexpr(cond), mkexpr(dest), mkexpr(acc)) );
putIRegRAX(size, mkexpr(acc2));
DIP("cmpxchg%c %s,%s\n", nameISize(size),
nameIRegG(size,pfx,rm), dis_buf);
@@ -8083,8 +8079,7 @@
assign( tmpd, getIRegG(sz, pfx, rm) );
putIRegG( sz, pfx, rm,
- IRExpr_Mux0X( unop(Iop_1Uto8,
- mk_amd64g_calculate_condition(cond)),
+ IRExpr_Mux0X( mk_amd64g_calculate_condition(cond),
mkexpr(tmpd),
mkexpr(tmps) )
);
@@ -8101,8 +8096,7 @@
assign( tmpd, getIRegG(sz, pfx, rm) );
putIRegG( sz, pfx, rm,
- IRExpr_Mux0X( unop(Iop_1Uto8,
- mk_amd64g_calculate_condition(cond)),
+ IRExpr_Mux0X( mk_amd64g_calculate_condition(cond),
mkexpr(tmpd),
mkexpr(tmps) )
);
@@ -8829,8 +8823,7 @@
assign(
g1,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- binop(Iop_CmpLT64U, mkexpr(amt), mkU64(size))),
+ binop(Iop_CmpLT64U, mkexpr(amt), mkU64(size)),
mkV128(0x0000),
binop(op, mkexpr(g0), mkexpr(amt8))
)
@@ -8840,8 +8833,7 @@
assign(
g1,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- binop(Iop_CmpLT64U, mkexpr(amt), mkU64(size))),
+ binop(Iop_CmpLT64U, mkexpr(amt), mkU64(size)),
binop(op, mkexpr(g0), mkU8(size-1)),
binop(op, mkexpr(g0), mkexpr(amt8))
)
@@ -16868,33 +16860,12 @@
return delta;
}
-/* Returns Ity_I32 */
-static IRExpr *IRExpr_getMSBs16x8(IRExpr *exp)
+static IRExpr* math_CTZ32(IRExpr *exp)
{
- IRTemp lo = newTemp(Ity_I64);
- IRTemp hi = newTemp(Ity_I64);
- assign(lo, unop(Iop_V128to64, exp));
- assign(hi, unop(Iop_V128HIto64, exp));
- return unop(Iop_16Uto32,
- binop(Iop_8HLto16,
- unop(Iop_GetMSBs8x8, mkexpr(hi)),
- unop(Iop_GetMSBs8x8, mkexpr(lo))));
-}
-
-static IRExpr *IRExpr_ctz32(IRExpr *exp)
-{
- /* Iop_Ctz32 appears to be broken, so use Iop_Ctz64. */
+ /* Iop_Ctz32 isn't implemented by the amd64 back end, so use Iop_Ctz64. */
return unop(Iop_64to32, unop(Iop_Ctz64, unop(Iop_32Uto64, exp)));
}
-/* For expression representing x, return !!x */
-static IRExpr* IRExpr_notnot(IRExpr *exp)
-{
- /* Iop_ExpCmpNE32 appears broken, so use Iop_ExpCmpNE64. */
- return unop(Iop_1Uto32, binop(Iop_ExpCmpNE64, unop(Iop_32Uto64, exp),
- mkU64(0)));
-}
-
static Long dis_PCMPISTRI_3A ( UChar modrm, UInt regNoL, UInt regNoR,
Long delta, UChar opc, UChar imm,
HChar dis_buf[])
@@ -16911,11 +16882,13 @@
assign(argR, getXMMReg(regNoR));
IRTemp zmaskL = newTemp(Ity_I32);
- assign(zmaskL, IRExpr_getMSBs16x8(binop(Iop_CmpEQ8x16, mkexpr(argL),
- mkV128(0))));
+ assign(zmaskL, unop(Iop_16Uto32,
+ unop(Iop_GetMSBs8x16,
+ binop(Iop_CmpEQ8x16, mkexpr(argL), mkV128(0)))));
IRTemp zmaskR = newTemp(Ity_I32);
- assign(zmaskR, IRExpr_getMSBs16x8(binop(Iop_CmpEQ8x16, mkexpr(argR),
- mkV128(0))));
+ assign(zmaskR, unop(Iop_16Uto32,
+ unop(Iop_GetMSBs8x16,
+ binop(Iop_CmpEQ8x16, mkexpr(argR), mkV128(0)))));
/* We want validL = ~(zmaskL | -zmaskL)
@@ -16925,37 +16898,38 @@
validL = (zmaskL ? (1 << ctz(zmaskL)) : 0) - 1
*/
- IRExpr *ctzL = unop(Iop_32to8, IRExpr_ctz32(mkexpr(zmaskL)));
+ IRExpr *ctzL = unop(Iop_32to8, math_CTZ32(mkexpr(zmaskL)));
- /* Generate an 8-bit expression which is zero iff the original is
+ /* Generate a bool expression which is zero iff the original is
zero. Do this carefully so memcheck can propagate validity bits
correctly.
*/
- IRTemp zmaskL_zero = newTemp(Ity_I32);
- assign(zmaskL_zero, IRExpr_notnot(mkexpr(zmaskL)));
+ IRTemp zmaskL_zero = newTemp(Ity_I1);
+ assign(zmaskL_zero, binop(Iop_ExpCmpNE32, mkexpr(zmaskL), mkU32(0)));
IRTemp validL = newTemp(Ity_I32);
assign(validL, binop(Iop_Sub32,
- IRExpr_Mux0X(unop(Iop_32to8, mkexpr(zmaskL_zero)),
+ IRExpr_Mux0X(mkexpr(zmaskL_zero),
mkU32(0),
binop(Iop_Shl32, mkU32(1), ctzL)),
mkU32(1)));
/* And similarly for validR. */
- IRExpr *ctzR = unop(Iop_32to8, IRExpr_ctz32(mkexpr(zmaskR)));
- IRTemp zmaskR_zero = newTemp(Ity_I32);
- assign(zmaskR_zero, IRExpr_notnot(mkexpr(zmaskR)));
+ IRExpr *ctzR = unop(Iop_32to8, math_CTZ32(mkexpr(zmaskR)));
+ IRTemp zmaskR_zero = newTemp(Ity_I1);
+ assign(zmaskR_zero, binop(Iop_ExpCmpNE32, mkexpr(zmaskR), mkU32(0)));
IRTemp validR = newTemp(Ity_I32);
assign(validR, binop(Iop_Sub32,
- IRExpr_Mux0X(unop(Iop_32to8, mkexpr(zmaskR_zero)),
+ IRExpr_Mux0X(mkexpr(zmaskR_zero),
mkU32(0),
binop(Iop_Shl32, mkU32(1), ctzR)),
mkU32(1)));
/* Do the actual comparison. */
- IRExpr *boolResII = IRExpr_getMSBs16x8(binop(Iop_CmpEQ8x16,
- mkexpr(argL),
- mkexpr(argR)));
+ IRExpr *boolResII = unop(Iop_16Uto32,
+ unop(Iop_GetMSBs8x16,
+ binop(Iop_CmpEQ8x16, mkexpr(argL),
+ mkexpr(argR))));
/* Compute boolresII & validL & validR (i.e., if both valid, use
comparison result) */
@@ -16979,8 +16953,8 @@
/* If the 0x40 bit were set in imm=0x3A, we would return the index
of the msb. Since it is clear, we return the index of the
lsb. */
- IRExpr *newECX = IRExpr_ctz32(binop(Iop_Or32,
- mkexpr(intRes2), mkU32(0x10000)));
+ IRExpr *newECX = math_CTZ32(binop(Iop_Or32,
+ mkexpr(intRes2), mkU32(0x10000)));
/* And thats our rcx. */
putIReg32(R_RCX, newECX);
@@ -16988,14 +16962,18 @@
/* Now for the condition codes... */
/* C == 0 iff intRes2 == 0 */
- IRExpr *c_bit = binop(Iop_Shl32, IRExpr_notnot(mkexpr(intRes2)),
- mkU8(AMD64G_CC_SHIFT_C));
+ IRExpr *c_bit = IRExpr_Mux0X( binop(Iop_ExpCmpNE32, mkexpr(intRes2),
+ mkU32(0)),
+ mkU32(0),
+ mkU32(1 << AMD64G_CC_SHIFT_C) );
/* Z == 1 iff any in argL is 0 */
- IRExpr *z_bit = binop(Iop_Shl32, mkexpr(zmaskL_zero),
- mkU8(AMD64G_CC_SHIFT_Z));
+ IRExpr *z_bit = IRExpr_Mux0X( mkexpr(zmaskL_zero),
+ mkU32(0),
+ mkU32(1 << AMD64G_CC_SHIFT_Z) );
/* S == 1 iff any in argR is 0 */
- IRExpr *s_bit = binop(Iop_Shl32, mkexpr(zmaskR_zero),
- mkU8(AMD64G_CC_SHIFT_S));
+ IRExpr *s_bit = IRExpr_Mux0X( mkexpr(zmaskR_zero),
+ mkU32(0),
+ mkU32(1 << AMD64G_CC_SHIFT_S) );
/* O == IntRes2[0] */
IRExpr *o_bit = binop(Iop_Shl32, binop(Iop_And32, mkexpr(intRes2),
mkU32(0x01)),
@@ -17051,6 +17029,19 @@
delta += alen+1;
}
+ /* Print the insn here, since dis_PCMPISTRI_3A doesn't do so
+ itself. */
+ if (regNoL == 16) {
+ DIP("%spcmp%cstr%c $%x,%s,%s\n",
+ isAvx ? "v" : "", isISTRx ? 'i' : 'e', isxSTRM ? 'm' : 'i',
+ (UInt)imm, dis_buf, nameXMMReg(regNoR));
+ } else {
+ DIP("%spcmp%cstr%c $%x,%s,%s\n",
+ isAvx ? "v" : "", isISTRx ? 'i' : 'e', isxSTRM ? 'm' : 'i',
+ (UInt)imm, nameXMMReg(regNoL), nameXMMReg(regNoR));
+ }
+
+ /* Handle special case(s). */
if (imm == 0x3A && isISTRx && !isxSTRM) {
return dis_PCMPISTRI_3A ( modrm, regNoL, regNoR, delta,
opc, imm, dis_buf);
@@ -17137,16 +17128,6 @@
stmt( IRStmt_Put( OFFB_CC_DEP2, mkU64(0) ));
stmt( IRStmt_Put( OFFB_CC_NDEP, mkU64(0) ));
- if (regNoL == 16) {
- DIP("%spcmp%cstr%c $%x,%s,%s\n",
- isAvx ? "v" : "", isISTRx ? 'i' : 'e', isxSTRM ? 'm' : 'i',
- (UInt)imm, dis_buf, nameXMMReg(regNoR));
- } else {
- DIP("%spcmp%cstr%c $%x,%s,%s\n",
- isAvx ? "v" : "", isISTRx ? 'i' : 'e', isxSTRM ? 'm' : 'i',
- (UInt)imm, nameXMMReg(regNoL), nameXMMReg(regNoR));
- }
-
return delta;
}
@@ -18932,11 +18913,10 @@
stmt( IRStmt_Put(
OFFB_DFLAG,
IRExpr_Mux0X(
- unop(Iop_32to8,
- unop(Iop_64to32,
+ unop(Iop_64to1,
binop(Iop_And64,
binop(Iop_Shr64, mkexpr(t1), mkU8(10)),
- mkU64(1)))),
+ mkU64(1))),
mkU64(1),
mkU64(0xFFFFFFFFFFFFFFFFULL)))
);
@@ -18945,11 +18925,10 @@
stmt( IRStmt_Put(
OFFB_IDFLAG,
IRExpr_Mux0X(
- unop(Iop_32to8,
- unop(Iop_64to32,
+ unop(Iop_64to1,
binop(Iop_And64,
binop(Iop_Shr64, mkexpr(t1), mkU8(21)),
- mkU64(1)))),
+ mkU64(1))),
mkU64(0),
mkU64(1)))
);
@@ -18958,11 +18937,10 @@
stmt( IRStmt_Put(
OFFB_ACFLAG,
IRExpr_Mux0X(
- unop(Iop_32to8,
- unop(Iop_64to32,
+ unop(Iop_64to1,
binop(Iop_And64,
binop(Iop_Shr64, mkexpr(t1), mkU8(18)),
- mkU64(1)))),
+ mkU64(1))),
mkU64(0),
mkU64(1)))
);
@@ -20366,13 +20344,13 @@
expdHi64:expdLo64, even if we're doing a cmpxchg8b. */
/* It's just _so_ much fun ... */
putIRegRDX( 8,
- IRExpr_Mux0X( unop(Iop_1Uto8, mkexpr(success)),
+ IRExpr_Mux0X( mkexpr(success),
sz == 4 ? unop(Iop_32Uto64, mkexpr(oldHi))
: mkexpr(oldHi),
mkexpr(expdHi64)
));
putIRegRAX( 8,
- IRExpr_Mux0X( unop(Iop_1Uto8, mkexpr(success)),
+ IRExpr_Mux0X( mkexpr(success),
sz == 4 ? unop(Iop_32Uto64, mkexpr(oldLo))
: mkexpr(oldLo),
mkexpr(expdLo64)
@@ -20861,8 +20839,7 @@
assign(
g1,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- binop(Iop_CmpLT64U, mkexpr(amt), mkU64(size))),
+ binop(Iop_CmpLT64U, mkexpr(amt), mkU64(size)),
mkV128(0x0000),
binop(op, mkexpr(g0), mkexpr(amt8))
)
@@ -20872,8 +20849,7 @@
assign(
g1,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- binop(Iop_CmpLT64U, mkexpr(amt), mkU64(size))),
+ binop(Iop_CmpLT64U, mkexpr(amt), mkU64(size)),
binop(op, mkexpr(g0), mkU8(size-1)),
binop(op, mkexpr(g0), mkexpr(amt8))
)
@@ -24644,12 +24620,12 @@
breakupV128to64s( dataV, &dHi, &dLo );
breakupV128to64s( ctrlV, &cHi, &cLo );
IRExpr* rHi
- = IRExpr_Mux0X( unop(Iop_64to8,
- binop(Iop_And64, mkexpr(cHi), mkU64(2))),
+ = IRExpr_Mux0X( unop(Iop_64to1,
+ binop(Iop_Shr64, mkexpr(cHi), mkU8(1))),
mkexpr(dLo), mkexpr(dHi) );
IRExpr* rLo
- = IRExpr_Mux0X( unop(Iop_64to8,
- binop(Iop_And64, mkexpr(cLo), mkU64(2))),
+ = IRExpr_Mux0X( unop(Iop_64to1,
+ binop(Iop_Shr64, mkexpr(cLo), mkU8(1))),
mkexpr(dLo), mkexpr(dHi) );
IRTemp res = newTemp(Ity_V128);
assign(res, binop(Iop_64HLtoV128, rHi, rLo));
Modified: trunk/priv/guest_x86_toIR.c (+62 -67)
===================================================================
--- trunk/priv/guest_x86_toIR.c 2013-01-26 11:39:13 +00:00 (rev 2663)
+++ trunk/priv/guest_x86_toIR.c 2013-01-26 11:47:55 +00:00 (rev 2664)
@@ -986,23 +986,27 @@
vpanic("setFlags_DEP1_DEP2_shift(x86)");
}
+ /* guard :: Ity_I8. We need to convert it to I1. */
+ IRTemp guardB = newTemp(Ity_I1);
+ assign( guardB, binop(Iop_CmpNE8, mkexpr(guard), mkU8(0)) );
+
/* DEP1 contains the result, DEP2 contains the undershifted value. */
stmt( IRStmt_Put( OFFB_CC_OP,
- IRExpr_Mux0X( mkexpr(guard),
+ IRExpr_Mux0X( mkexpr(guardB),
IRExpr_Get(OFFB_CC_OP,Ity_I32),
mkU32(ccOp))) );
stmt( IRStmt_Put( OFFB_CC_DEP1,
- IRExpr_Mux0X( mkexpr(guard),
+ IRExpr_Mux0X( mkexpr(guardB),
IRExpr_Get(OFFB_CC_DEP1,Ity_I32),
widenUto32(mkexpr(res)))) );
stmt( IRStmt_Put( OFFB_CC_DEP2,
- IRExpr_Mux0X( mkexpr(guard),
+ IRExpr_Mux0X( mkexpr(guardB),
IRExpr_Get(OFFB_CC_DEP2,Ity_I32),
widenUto32(mkexpr(resUS)))) );
/* 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,
- IRExpr_Mux0X( mkexpr(guard),
+ IRExpr_Mux0X( mkexpr(guardB),
IRExpr_Get(OFFB_CC_NDEP,Ity_I32),
mkU32(0) )));
}
@@ -2571,21 +2575,25 @@
assign(oldFlags, mk_x86g_calculate_eflags_all());
+ /* rot_amt32 :: Ity_I8. We need to convert it to I1. */
+ IRTemp rot_amt32b = newTemp(Ity_I1);
+ assign(rot_amt32b, binop(Iop_CmpNE8, mkexpr(rot_amt32), mkU8(0)) );
+
/* CC_DEP1 is the rotated value. CC_NDEP is flags before. */
stmt( IRStmt_Put( OFFB_CC_OP,
- IRExpr_Mux0X( mkexpr(rot_amt32),
+ IRExpr_Mux0X( mkexpr(rot_amt32b),
IRExpr_Get(OFFB_CC_OP,Ity_I32),
mkU32(ccOp))) );
stmt( IRStmt_Put( OFFB_CC_DEP1,
- IRExpr_Mux0X( mkexpr(rot_amt32),
+ IRExpr_Mux0X( mkexpr(rot_amt32b),
IRExpr_Get(OFFB_CC_DEP1,Ity_I32),
widenUto32(mkexpr(dst1)))) );
stmt( IRStmt_Put( OFFB_CC_DEP2,
- IRExpr_Mux0X( mkexpr(rot_amt32),
+ IRExpr_Mux0X( mkexpr(rot_amt32b),
IRExpr_Get(OFFB_CC_DEP2,Ity_I32),
mkU32(0))) );
stmt( IRStmt_Put( OFFB_CC_NDEP,
- IRExpr_Mux0X( mkexpr(rot_amt32),
+ IRExpr_Mux0X( mkexpr(rot_amt32b),
IRExpr_Get(OFFB_CC_NDEP,Ity_I32),
mkexpr(oldFlags))) );
} /* if (isRotate) */
@@ -3422,8 +3430,7 @@
IRTemp res32 = newTemp(Ity_I32);
assign(res32,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- binop(Iop_CmpEQ32, mkexpr(src32x), mkU32(0))),
+ binop(Iop_CmpEQ32, mkexpr(src32x), mkU32(0)),
unop(Iop_Clz32, mkexpr(src32x)),
mkU32(8 * sizeofIRType(ty))
));
@@ -3560,13 +3567,14 @@
static void put_ST ( Int i, IRExpr* value )
{
- put_ST_UNCHECKED( i,
- IRExpr_Mux0X( get_ST_TAG(i),
- /* 0 means empty */
- value,
- /* non-0 means full */
- mkQNaN64()
- )
+ put_ST_UNCHECKED(
+ i,
+ IRExpr_Mux0X( binop(Iop_CmpNE8, get_ST_TAG(i), mkU8(0)),
+ /* 0 means empty */
+ value,
+ /* non-0 means full */
+ mkQNaN64()
+ )
);
}
@@ -3587,7 +3595,7 @@
static IRExpr* get_ST ( Int i )
{
return
- IRExpr_Mux0X( get_ST_TAG(i),
+ IRExpr_Mux0X( binop(Iop_CmpNE8, get_ST_TAG(i), mkU8(0)),
/* 0 means empty */
mkQNaN64(),
/* non-0 means full */
@@ -4525,8 +4533,7 @@
DIP("fcmovb %%st(%d), %%st(0)\n", (Int)r_src);
put_ST_UNCHECKED(0,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- mk_x86g_calculate_condition(X86CondB)),
+ mk_x86g_calculate_condition(X86CondB),
get_ST(0), get_ST(r_src)) );
break;
@@ -4535,8 +4542,7 @@
DIP("fcmovz %%st(%d), %%st(0)\n", (Int)r_src);
put_ST_UNCHECKED(0,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- mk_x86g_calculate_condition(X86CondZ)),
+ mk_x86g_calculate_condition(X86CondZ),
get_ST(0), get_ST(r_src)) );
break;
@@ -4545,8 +4551,7 @@
DIP("fcmovbe %%st(%d), %%st(0)\n", (Int)r_src);
put_ST_UNCHECKED(0,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- mk_x86g_calculate_condition(X86CondBE)),
+ mk_x86g_calculate_condition(X86CondBE),
get_ST(0), get_ST(r_src)) );
break;
@@ -4555,8 +4560,7 @@
DIP("fcmovu %%st(%d), %%st(0)\n", (Int)r_src);
put_ST_UNCHECKED(0,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- mk_x86g_calculate_condition(X86CondP)),
+ mk_x86g_calculate_condition(X86CondP),
get_ST(0), get_ST(r_src)) );
break;
@@ -4690,8 +4694,7 @@
DIP("fcmovnb %%st(%d), %%st(0)\n", (Int)r_src);
put_ST_UNCHECKED(0,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- mk_x86g_calculate_condition(X86CondNB)),
+ mk_x86g_calculate_condition(X86CondNB),
get_ST(0), get_ST(r_src)) );
break;
@@ -4700,8 +4703,7 @@
DIP("fcmovnz %%st(%d), %%st(0)\n", (Int)r_src);
put_ST_UNCHECKED(0,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- mk_x86g_calculate_condition(X86CondNZ)),
+ mk_x86g_calculate_condition(X86CondNZ),
get_ST(0), get_ST(r_src)) );
break;
@@ -4710,8 +4712,7 @@
DIP("fcmovnbe %%st(%d), %%st(0)\n", (Int)r_src);
put_ST_UNCHECKED(0,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- mk_x86g_calculate_condition(X86CondNBE)),
+ mk_x86g_calculate_condition(X86CondNBE),
get_ST(0), get_ST(r_src)) );
break;
@@ -4720,8 +4721,7 @@
DIP("fcmovnu %%st(%d), %%st(0)\n", (Int)r_src);
put_ST_UNCHECKED(0,
IRExpr_Mux0X(
- unop(Iop_1Uto8,
- mk_x86g_calculate_condition(X86CondNP)),
+ mk_x86g_calculate_condition(X86CondNP),
get_ST(0), get_ST(r_src)) );
break;
@@ -5645,7 +5645,7 @@
assign(
g1,
IRExpr_Mux0X(
- unop(Iop_1Uto8,binop(Iop_CmpLT32U,mkexpr(amt),mkU32(size))),
+ binop(Iop_CmpLT32U,mkexpr(amt),mkU32(size)),
mkU64(0),
binop(op, mkexpr(g0), mkexpr(amt8))
)
@@ -5655,7 +5655,7 @@
assign(
g1,
IRExpr_Mux0X(
- unop(Iop_1Uto8,binop(Iop_CmpLT32U,mkexpr(amt),mkU32(size))),
+ binop(Iop_CmpLT32U,mkexpr(amt),mkU32(size)),
binop(op, mkexpr(g0), mkU8(size-1)),
binop(op, mkexpr(g0), mkexpr(amt8))
)
@@ -6364,7 +6364,7 @@
IRTemp src32 = newTemp(Ity_I32);
IRTemp dst32 = newTemp(Ity_I32);
- IRTemp src8 = newTemp(Ity_I8);
+ IRTemp srcB = newTemp(Ity_I1);
vassert(sz == 4 || sz == 2);
@@ -6386,15 +6386,14 @@
( isReg ? nameIReg(sz, eregOfRM(modrm)) : dis_buf ),
nameIReg(sz, gregOfRM(modrm)));
- /* Generate an 8-bit expression which is zero iff the original is
+ /* Generate a bool expression which is zero iff the original is
zero, and nonzero otherwise. Ask for a CmpNE version which, if
instrumented by Memcheck, is instrumented expensively, since
this may be used on the output of a preceding movmskb insn,
which has been known to be partially defined, and in need of
careful handling. */
- assign( src8,
- unop(Iop_1Uto8, binop(mkSizedOp(ty,Iop_ExpCmpNE8),
- mkexpr(src), mkU(ty,0))) );
+ assign( srcB, binop(mkSizedOp(ty,Iop_ExpCmpNE8),
+ mkexpr(src), mkU(ty,0)) );
/* Flags: Z is 1 iff source value is zero. All others
are undefined -- we force them to zero. */
@@ -6402,7 +6401,7 @@
stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) ));
stmt( IRStmt_Put(
OFFB_CC_DEP1,
- IRExpr_Mux0X( mkexpr(src8),
+ IRExpr_Mux0X( mkexpr(srcB),
/* src==0 */
mkU32(X86G_CC_MASK_Z),
/* src!=0 */
@@ -6439,7 +6438,7 @@
/* The main computation, guarding against zero. */
assign( dst32,
IRExpr_Mux0X(
- mkexpr(src8),
+ mkexpr(srcB),
/* src == 0 -- leave dst unchanged */
widenUto32( getIReg( sz, gregOfRM(modrm) ) ),
/* src != 0 */
@@ -6547,7 +6546,7 @@
IRTemp dest = newTemp(ty);
IRTemp dest2 = newTemp(ty);
IRTemp acc2 = newTemp(ty);
- IRTemp cond8 = newTemp(Ity_I8);
+ IRTemp cond = newTemp(Ity_I1);
IRTemp addr = IRTemp_INVALID;
UChar rm = getUChar(delta0);
@@ -6568,9 +6567,9 @@
assign( src, getIReg(size, gregOfRM(rm)) );
assign( acc, getIReg(size, R_EAX) );
setFlags_DEP1_DEP2(Iop_Sub8, acc, dest, ty);
- assign( ...
[truncated message content] |