|
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] |
|
From: Florian K. <br...@ac...> - 2013-01-26 16:38:57
|
On 01/26/2013 06:47 AM, sv...@va... wrote: > Infrastructure cleanup: change type of the condition field of > IRExpr_Mux0X from Ity_I8 to Ity_I1. > 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 > Mips? I'm going to work on the follow-on patch replacing Iex_Mux0X with Iex_ITE swapping the order of the arguments as discussed previously. Florian |
|
From: Julian S. <js...@ac...> - 2013-01-26 16:53:16
|
On 01/26/2013 05:38 PM, Florian Krohm wrote: > Mips? I'm going to work on the follow-on patch replacing Iex_Mux0X with > Iex_ITE swapping the order of the arguments as discussed previously. I'll do MIPS as soon as I can get a shell on the relevant machine (gcc49 in the gcc compile farm), but at the moment it's not available. Don't delay your ITE swapping thing until that is done, though .. the Mux0X type change and the ITE are orthogonal, and not too difficult to test. Plus I haven't a clue when gcc49 will come back online. J |