From: Julian Seward Date: Mon, 8 Nov 2004 18:53:52 +0000 (+0000) Subject: x86 host: translate Sub32(0,x) into a negl insn. This is a very X-Git-Tag: svn/VALGRIND_3_0_1^2~806 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8c28cbe58da16dbcaf10589e7a53b68b1c806ba5;p=thirdparty%2Fvalgrind.git x86 host: translate Sub32(0,x) into a negl insn. This is a very common idiom from Memcheck ("Left4"). git-svn-id: svn://svn.valgrind.org/vex/trunk@528 --- diff --git a/VEX/priv/host-x86/isel.c b/VEX/priv/host-x86/isel.c index 1e8c89fcf2..040a06c2d1 100644 --- a/VEX/priv/host-x86/isel.c +++ b/VEX/priv/host-x86/isel.c @@ -260,6 +260,15 @@ static HReg iselDblExpr ( ISelEnv* env, IRExpr* e ); /*--- ISEL: Misc helpers ---*/ /*---------------------------------------------------------*/ +/* Is this a 32-bit zero expression? */ + +static Bool isZero32 ( IRExpr* e ) +{ + return e->tag == Iex_Const + && e->Iex.Const.con->tag == Ico_U32 + && e->Iex.Const.con->Ico.U32 == 0; +} + /* Make a int reg-reg move. */ static X86Instr* mk_MOVsd_RR ( HReg src, HReg dst ) @@ -538,6 +547,15 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) X86AluOp aluOp; X86ShiftOp shOp; + /* Pattern: Sub32(0,x) */ + if (e->Iex.Binop.op == Iop_Sub32 && isZero32(e->Iex.Binop.arg1)) { + HReg dst = newVRegI(env); + HReg reg = iselIntExpr_R(env, e->Iex.Binop.arg2); + addInstr(env, mk_MOVsd_RR(reg,dst)); + addInstr(env, X86Instr_Unary32(Xun_NEG,X86RM_Reg(dst))); + return dst; + } + /* Is it an addition or logical style op? */ switch (e->Iex.Binop.op) { case Iop_Add8: case Iop_Add16: case Iop_Add32: @@ -833,7 +851,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) HReg dst = newVRegI(env); HReg src = iselIntExpr_R(env, e->Iex.Unop.arg); addInstr(env, mk_MOVsd_RR(src,dst) ); - addInstr(env, X86Instr_Unary32(Xun_Not,X86RM_Reg(dst))); + addInstr(env, X86Instr_Unary32(Xun_NOT,X86RM_Reg(dst))); return dst; } case Iop_64HIto32: {