From: Julian Seward Date: Tue, 26 Apr 2005 23:39:45 +0000 (+0000) Subject: * Enhance the x86 instruction selector to generate for the primops X-Git-Tag: svn/VALGRIND_3_0_1^2~189 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=40fb75f74e2ac8b66abaec6001febf0612da44e8;p=thirdparty%2Fvalgrind.git * Enhance the x86 instruction selector to generate for the primops introduced in rev 1144. * Rearrange iselCondCode and introduce a few new patterns which deal better with the IR that Memcheck commonly generates git-svn-id: svn://svn.valgrind.org/vex/trunk@1145 --- diff --git a/VEX/priv/host-x86/isel.c b/VEX/priv/host-x86/isel.c index 7fc824dad2..941fc0ea26 100644 --- a/VEX/priv/host-x86/isel.c +++ b/VEX/priv/host-x86/isel.c @@ -763,15 +763,6 @@ 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_iMOVsd_RR(reg,dst)); - addInstr(env, X86Instr_Unary32(Xun_NEG,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: @@ -1121,6 +1112,15 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) X86RMI_Reg(tmp), dst)); return dst; } + case Iop_Neg8: + case Iop_Neg16: + case Iop_Neg32: { + HReg dst = newVRegI(env); + HReg reg = iselIntExpr_R(env, e->Iex.Unop.arg); + addInstr(env, mk_iMOVsd_RR(reg,dst)); + addInstr(env, X86Instr_Unary32(Xun_NEG,dst)); + return dst; + } case Iop_V128to32: { HReg dst = newVRegI(env); @@ -1487,6 +1487,15 @@ static X86CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ) vassert(e); vassert(typeOfIRExpr(env->type_env,e) == Ity_I1); + /* var */ + if (e->tag == Iex_Tmp) { + HReg r32 = lookupIRTemp(env, e->Iex.Tmp.tmp); + HReg dst = newVRegI(env); + addInstr(env, mk_iMOVsd_RR(r32,dst)); + addInstr(env, X86Instr_Alu32R(Xalu_AND,X86RMI_Imm(1),dst)); + return Xcc_NZ; + } + /* Constant 1:Bit */ if (e->tag == Iex_Const && e->Iex.Const.con->Ico.U1 == True) { HReg r; @@ -1497,13 +1506,15 @@ static X86CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ) return Xcc_Z; } - /* Not1(...) */ + /* Not1(e) */ if (e->tag == Iex_Unop && e->Iex.Unop.op == Iop_Not1) { /* Generate code for the arg, and negate the test condition */ return 1 ^ iselCondCode(env, e->Iex.Unop.arg); } - /* 32to1(1Uto32(expr1)) -- the casts are pointless, ignore them */ + /* --- patterns rooted at: 32to1 --- */ + + /* 32to1(1Uto32(e)) ==> e */ DEFINE_PATTERN(p_1Uto32_then_32to1, unop(Iop_32to1,unop(Iop_1Uto32,bind(0)))); if (matchIRExpr(&mi,p_1Uto32_then_32to1,e)) { @@ -1511,7 +1522,7 @@ static X86CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ) return iselCondCode(env, expr1); } - /* 32to1(1Sto32(expr1)) -- the casts are pointless, ignore them */ + /* 32to1(1Sto32(e)) ==> e */ DEFINE_PATTERN(p_1Sto32_then_32to1, unop(Iop_32to1,unop(Iop_1Sto32,bind(0)))); if (matchIRExpr(&mi,p_1Sto32_then_32to1,e)) { @@ -1519,9 +1530,9 @@ static X86CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ) return iselCondCode(env, expr1); } - /* pattern: 32to1(expr32) */ + /* 32to1(expr32) */ DEFINE_PATTERN(p_32to1, - unop(Iop_32to1,bind(0)) + unop(Iop_32to1,bind(0)) ); if (matchIRExpr(&mi,p_32to1,e)) { HReg r = iselIntExpr_R(env, mi.bindee[0]); @@ -1529,6 +1540,102 @@ static X86CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ) return Xcc_NZ; } + /* --- patterns rooted at: CmpNEZ8 --- */ + + /* CmpNEZ8(x) */ + if (e->tag == Iex_Unop + && e->Iex.Unop.op == Iop_CmpNEZ8) { + HReg r = iselIntExpr_R(env, e->Iex.Unop.arg); + addInstr(env, X86Instr_Test32(0xFF,r)); + return Xcc_NZ; + } + + /* --- patterns rooted at: CmpNEZ16 --- */ + + /* CmpNEZ16(x) */ + if (e->tag == Iex_Unop + && e->Iex.Unop.op == Iop_CmpNEZ16) { + HReg r = iselIntExpr_R(env, e->Iex.Unop.arg); + addInstr(env, X86Instr_Test32(0xFFFF,r)); + return Xcc_NZ; + } + + /* --- patterns rooted at: CmpNEZ32 --- */ + + /* CmpNEZ32(1Sto32(b)) ==> b */ + { + DECLARE_PATTERN(p_CmpNEZ32_1Sto32); + DEFINE_PATTERN(p_CmpNEZ32_1Sto32, + unop(Iop_CmpNEZ32, unop(Iop_1Sto32,bind(0)))); + if (matchIRExpr(&mi, p_CmpNEZ32_1Sto32, e)) { + return iselCondCode(env, mi.bindee[0]); + } + } + + /* CmpNEZ32(And32(x,y)) */ + { + DECLARE_PATTERN(p_CmpNEZ32_And32); + DEFINE_PATTERN(p_CmpNEZ32_And32, + unop(Iop_CmpNEZ32, binop(Iop_And32, bind(0), bind(1)))); + if (matchIRExpr(&mi, p_CmpNEZ32_And32, e)) { + HReg r0 = iselIntExpr_R(env, mi.bindee[0]); + X86RMI* rmi1 = iselIntExpr_RMI(env, mi.bindee[1]); + HReg tmp = newVRegI(env); + addInstr(env, mk_iMOVsd_RR(r0, tmp)); + addInstr(env, X86Instr_Alu32R(Xalu_AND,rmi1,tmp)); + return Xcc_NZ; + } + } + + /* CmpNEZ32(Or32(x,y)) */ + { + DECLARE_PATTERN(p_CmpNEZ32_Or32); + DEFINE_PATTERN(p_CmpNEZ32_Or32, + unop(Iop_CmpNEZ32, binop(Iop_Or32, bind(0), bind(1)))); + if (matchIRExpr(&mi, p_CmpNEZ32_Or32, e)) { + HReg r0 = iselIntExpr_R(env, mi.bindee[0]); + X86RMI* rmi1 = iselIntExpr_RMI(env, mi.bindee[1]); + HReg tmp = newVRegI(env); + addInstr(env, mk_iMOVsd_RR(r0, tmp)); + addInstr(env, X86Instr_Alu32R(Xalu_OR,rmi1,tmp)); + return Xcc_NZ; + } + } + /* CmpNEZ32(x) */ + if (e->tag == Iex_Unop + && e->Iex.Unop.op == Iop_CmpNEZ32) { + HReg r1 = iselIntExpr_R(env, e->Iex.Unop.arg); + X86RMI* rmi2 = X86RMI_Imm(0); + addInstr(env, X86Instr_Alu32R(Xalu_CMP,rmi2,r1)); + return Xcc_NZ; + } + + /* --- patterns rooted at: CmpNEZ64 --- */ + + /* CmpNEZ64(1Sto64(b)) ==> b */ + { + DECLARE_PATTERN(p_CmpNEZ64_1Sto64); + DEFINE_PATTERN( + p_CmpNEZ64_1Sto64, + unop(Iop_CmpNEZ64, unop(Iop_1Sto64,bind(0)))); + if (matchIRExpr(&mi, p_CmpNEZ64_1Sto64, e)) { + return iselCondCode(env, mi.bindee[0]); + } + } + + /* CmpNEZ64(x) */ + if (e->tag == Iex_Unop + && e->Iex.Unop.op == Iop_CmpNEZ64) { + HReg hi, lo; + HReg tmp = newVRegI(env); + iselInt64Expr( &hi, &lo, env, e->Iex.Unop.arg ); + addInstr(env, mk_iMOVsd_RR(hi, tmp)); + addInstr(env, X86Instr_Alu32R(Xalu_OR,X86RMI_Reg(lo), tmp)); + return Xcc_NZ; + } + + /* --- patterns rooted at: Cmp{EQ,NE}{8,16} --- */ + /* CmpEQ8 / CmpNE8 */ if (e->tag == Iex_Binop && (e->Iex.Binop.op == Iop_CmpEQ8 @@ -1563,17 +1670,6 @@ static X86CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ) } } - /* CmpNE32(1Sto32(b), 0) ==> b */ - { - DECLARE_PATTERN(p_CmpNE32_1Sto32); - DEFINE_PATTERN( - p_CmpNE32_1Sto32, - binop(Iop_CmpNE32, unop(Iop_1Sto32,bind(0)), mkU32(0))); - if (matchIRExpr(&mi, p_CmpNE32_1Sto32, e)) { - return iselCondCode(env, mi.bindee[0]); - } - } - /* Cmp*32*(x,y) */ if (e->tag == Iex_Binop && (e->Iex.Binop.op == Iop_CmpEQ32 @@ -1596,34 +1692,6 @@ static X86CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ) } } - /* CmpNE64(1Sto64(b), 0) ==> b */ - { - DECLARE_PATTERN(p_CmpNE64_1Sto64); - DEFINE_PATTERN( - p_CmpNE64_1Sto64, - binop(Iop_CmpNE64, unop(Iop_1Sto64,bind(0)), mkU64(0))); - if (matchIRExpr(&mi, p_CmpNE64_1Sto64, e)) { - return iselCondCode(env, mi.bindee[0]); - } - } - - /* CmpNE64(x, 0) */ - { - DECLARE_PATTERN(p_CmpNE64_x_zero); - DEFINE_PATTERN( - p_CmpNE64_x_zero, - binop(Iop_CmpNE64, bind(0), mkU64(0)) ); - if (matchIRExpr(&mi, p_CmpNE64_x_zero, e)) { - HReg hi, lo; - IRExpr* x = mi.bindee[0]; - HReg tmp = newVRegI(env); - iselInt64Expr( &hi, &lo, env, x ); - addInstr(env, mk_iMOVsd_RR(hi, tmp)); - addInstr(env, X86Instr_Alu32R(Xalu_OR,X86RMI_Reg(lo), tmp)); - return Xcc_NZ; - } - } - /* CmpNE64 */ if (e->tag == Iex_Binop && e->Iex.Binop.op == Iop_CmpNE64) { @@ -1643,15 +1711,6 @@ static X86CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ) } } - /* var */ - if (e->tag == Iex_Tmp) { - HReg r32 = lookupIRTemp(env, e->Iex.Tmp.tmp); - HReg dst = newVRegI(env); - addInstr(env, mk_iMOVsd_RR(r32,dst)); - addInstr(env, X86Instr_Alu32R(Xalu_AND,X86RMI_Imm(1),dst)); - return Xcc_NZ; - } - ppIRExpr(e); vpanic("iselCondCode"); }