From: Julian Seward Date: Thu, 4 Nov 2004 16:57:50 +0000 (+0000) Subject: Add a couple more primops needed by Memcheck. X-Git-Tag: svn/VALGRIND_3_0_1^2~848 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=27e1401165b512b20edbcfe442f6058643a086ac;p=thirdparty%2Fvalgrind.git Add a couple more primops needed by Memcheck. git-svn-id: svn://svn.valgrind.org/vex/trunk@486 --- diff --git a/VEX/priv/host-x86/isel.c b/VEX/priv/host-x86/isel.c index 64b8149434..bbf400a405 100644 --- a/VEX/priv/host-x86/isel.c +++ b/VEX/priv/host-x86/isel.c @@ -1320,7 +1320,7 @@ static X86CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ) switch (e->Iex.Binop.op) { case Iop_CmpEQ16: return Xcc_Z; case Iop_CmpNE16: return Xcc_NZ; - default: vpanic("iselCondCode(x86): CmpXX8"); + default: vpanic("iselCondCode(x86): CmpXX16"); } } @@ -1346,6 +1346,25 @@ static X86CondCode iselCondCode_wrk ( ISelEnv* env, IRExpr* e ) } } + /* CmpNE64 */ + if (e->tag == Iex_Binop + && e->Iex.Binop.op == Iop_CmpNE64) { + HReg hi1, hi2, lo1, lo2; + HReg tHi = newVRegI(env); + HReg tLo = newVRegI(env); + iselIntExpr64( &hi1, &lo1, env, e->Iex.Binop.arg1 ); + iselIntExpr64( &hi2, &lo2, env, e->Iex.Binop.arg2 ); + addInstr(env, mk_MOVsd_RR(hi1, tHi)); + addInstr(env, X86Instr_Alu32R(Xalu_XOR,X86RMI_Reg(hi2), tHi)); + addInstr(env, mk_MOVsd_RR(lo1, tLo)); + addInstr(env, X86Instr_Alu32R(Xalu_XOR,X86RMI_Reg(lo2), tLo)); + addInstr(env, X86Instr_Alu32R(Xalu_OR,X86RMI_Reg(tHi), tLo)); + switch (e->Iex.Binop.op) { + case Iop_CmpNE64: return Xcc_NZ; + default: vpanic("iselCondCode(x86): CmpXX64"); + } + } + /* var */ if (e->tag == Iex_Tmp) { HReg r32 = lookupIRTemp(env, e->Iex.Tmp.tmp); @@ -1490,6 +1509,22 @@ static void iselIntExpr64_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) return; } + /* 1Sto64(e) */ + /* could do better than this, but for now ... */ + if (e->tag == Iex_Unop + && e->Iex.Unop.op == Iop_1Sto64) { + HReg tLo = newVRegI(env); + HReg tHi = newVRegI(env); + X86CondCode cond = iselCondCode(env, e->Iex.Unop.arg); + addInstr(env, X86Instr_Set32(cond,tLo)); + addInstr(env, X86Instr_Sh32(Xsh_SHL, 31, X86RM_Reg(tLo))); + addInstr(env, X86Instr_Sh32(Xsh_SAR, 31, X86RM_Reg(tLo))); + addInstr(env, mk_MOVsd_RR(tLo, tHi)); + *rHi = tHi; + *rLo = tLo; + return; + } + /* 32Uto64(e) */ if (e->tag == Iex_Unop && e->Iex.Unop.op == Iop_32Uto64) { diff --git a/VEX/priv/ir/irdefs.c b/VEX/priv/ir/irdefs.c index dbd38b6b84..9b26708d35 100644 --- a/VEX/priv/ir/irdefs.c +++ b/VEX/priv/ir/irdefs.c @@ -120,6 +120,7 @@ void ppIROp ( IROp op ) case Iop_1Uto8: vex_printf("1Uto8"); return; case Iop_1Uto32: vex_printf("1Uto32"); return; case Iop_1Sto32: vex_printf("1Sto32"); return; + case Iop_1Sto64: vex_printf("1Sto64"); return; case Iop_MullS8: vex_printf("MullS8"); return; case Iop_MullS16: vex_printf("MullS16"); return; @@ -975,6 +976,7 @@ void typeOfPrimop ( IROp op, IRType* t_dst, IRType* t_arg1, IRType* t_arg2 ) case Iop_Not1: UNARY(Ity_Bit,Ity_Bit); case Iop_1Uto8: UNARY(Ity_I8,Ity_Bit); case Iop_1Uto32: case Iop_1Sto32: UNARY(Ity_I32,Ity_Bit); + case Iop_1Sto64: UNARY(Ity_I64,Ity_Bit); case Iop_32to1: UNARY(Ity_Bit,Ity_I32); case Iop_8Uto32: case Iop_8Sto32: diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index e4943cff7e..8c618aac07 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -193,6 +193,7 @@ typedef Iop_1Uto8, /* :: Ity_Bit -> Ity_I8, unsigned widen */ Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */ Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */ + Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */ /* ------ Floating point. We try and be IEEE754 compliant. ------ */