From: Julian Seward Date: Thu, 26 Jan 2006 02:24:17 +0000 (+0000) Subject: A bit more backend tidying: X-Git-Tag: svn/VALGRIND_3_2_3^2~110 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=41b512f796200de1d1e9b8459f287b84e78ef57f;p=thirdparty%2Fvalgrind.git A bit more backend tidying: - fix up more float-integer conversions - remove unused signedness field on PPCInstr_Load git-svn-id: svn://svn.valgrind.org/vex/trunk@1551 --- diff --git a/VEX/priv/host-ppc/hdefs.c b/VEX/priv/host-ppc/hdefs.c index 06b964f5b4..6d027285d2 100644 --- a/VEX/priv/host-ppc/hdefs.c +++ b/VEX/priv/host-ppc/hdefs.c @@ -582,6 +582,7 @@ HChar* showPPCUnaryOp ( PPCUnaryOp op ) { case Pun_NEG: return "neg"; case Pun_CLZ32: return "cntlzw"; case Pun_CLZ64: return "cntlzd"; + case Pun_EXTSW: return "extsw"; default: vpanic("showPPCUnaryOp"); } } @@ -837,12 +838,11 @@ PPCInstr* PPCInstr_CMov ( PPCCondCode cond, vassert(cond.test != Pct_ALWAYS); return i; } -PPCInstr* PPCInstr_Load ( UChar sz, Bool syned, +PPCInstr* PPCInstr_Load ( UChar sz, HReg dst, PPCAMode* src, Bool mode64 ) { PPCInstr* i = LibVEX_Alloc(sizeof(PPCInstr)); i->tag = Pin_Load; i->Pin.Load.sz = sz; - i->Pin.Load.syned = syned; i->Pin.Load.src = src; i->Pin.Load.dst = dst; vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8); @@ -1333,8 +1333,7 @@ void ppPPCInstr ( PPCInstr* i, Bool mode64 ) Bool idxd = toBool(i->Pin.Load.src->tag == Pam_RR); UChar sz = i->Pin.Load.sz; UChar c_sz = sz==1 ? 'b' : sz==2 ? 'h' : sz==4 ? 'w' : 'd'; - HChar* s_syned = i->Pin.Load.syned ? "a" : sz==8 ? "" : "z"; - vex_printf("l%c%s%s ", c_sz, s_syned, idxd ? "x" : "" ); + vex_printf("l%cz%s ", c_sz, idxd ? "x" : "" ); ppHRegPPC(i->Pin.Load.dst); vex_printf(","); ppPPCAMode(i->Pin.Load.src); @@ -2138,10 +2137,10 @@ PPCInstr* genReload_PPC ( HReg rreg, UShort offsetB, Bool mode64 ) switch (hregClass(rreg)) { case HRcInt64: vassert(mode64); - return PPCInstr_Load( 8, False, rreg, am, mode64 ); + return PPCInstr_Load( 8, rreg, am, mode64 ); case HRcInt32: vassert(!mode64); - return PPCInstr_Load( 4, False, rreg, am, mode64 ); + return PPCInstr_Load( 4, rreg, am, mode64 ); case HRcFlt64: return PPCInstr_FpLdSt ( True/*load*/, 8, rreg, am ); case HRcVec128: @@ -2534,7 +2533,9 @@ Int emit_PPCInstr ( UChar* buf, Int nbuf, PPCInstr* i, UChar* ptmp = p; vassert(nbuf >= 32); -// vex_printf("asm ");ppPPCInstr(i, mode64); vex_printf("\n"); + if (0) { + vex_printf("asm ");ppPPCInstr(i, mode64); vex_printf("\n"); + } switch (i->tag) { @@ -2797,8 +2798,13 @@ Int emit_PPCInstr ( UChar* buf, Int nbuf, PPCInstr* i, p = mkFormX(p, 31, r_src, r_dst, 0, 26, 0); break; case Pun_CLZ64: // cntlzd r_dst, r_src + vassert(mode64); p = mkFormX(p, 31, r_src, r_dst, 0, 58, 0); break; + case Pun_EXTSW: // extsw r_dst, r_src + vassert(mode64); + p = mkFormX(p, 31, r_src, r_dst, 0, 986, 0); + break; default: goto bad; } goto done; @@ -3011,28 +3017,25 @@ Int emit_PPCInstr ( UChar* buf, Int nbuf, PPCInstr* i, case Pin_Load: { PPCAMode* am_addr = i->Pin.Load.src; UInt r_dst = iregNo(i->Pin.Load.dst, mode64); - Bool syned = i->Pin.Load.syned; UInt opc1, opc2, sz = i->Pin.Load.sz; switch (am_addr->tag) { case Pam_IR: switch(sz) { - case 1: opc1 = 34; break; - case 2: opc1 = (syned) ? 42: 40; break; - case 4: opc1 = 32; break; - case 8: opc1 = 58; break; - default: - goto bad; + case 1: opc1 = 34; break; + case 2: opc1 = 40; break; + case 4: opc1 = 32; break; + case 8: opc1 = 58; vassert(mode64); break; + default: goto bad; } p = doAMode_IR(p, opc1, r_dst, am_addr, mode64); goto done; case Pam_RR: switch(sz) { - case 1: opc2 = 87; break; - case 2: opc2 = (syned) ? 343: 279; break; - case 4: opc2 = 23; break; - case 8: opc2 = 21; break; - default: - goto bad; + case 1: opc2 = 87; break; + case 2: opc2 = 279; break; + case 4: opc2 = 23; break; + case 8: opc2 = 21; vassert(mode64); break; + default: goto bad; } p = doAMode_RR(p, 31, opc2, r_dst, am_addr, mode64); goto done; @@ -3215,68 +3218,19 @@ Int emit_PPCInstr ( UChar* buf, Int nbuf, PPCInstr* i, p = mkFormX(p, 63, fr_dst, 0, fr_src, 14, 0); goto done; } + if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == False) { + // fctid (conv f64 to i64), PPC64 p437 + p = mkFormX(p, 63, fr_dst, 0, fr_src, 814, 0); + goto done; + } + if (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == False) { + // fcfid (conv i64 to f64), PPC64 p434 + p = mkFormX(p, 63, fr_dst, 0, fr_src, 846, 0); + goto done; + } goto bad; } -// case Pin_FpF64toI32: { -// UInt r_dst = iregNo(i->Pin.FpF64toI32.dst, mode64); -// UInt fr_src = fregNo(i->Pin.FpF64toI32.src); -// UChar fr_tmp = 7; // Temp freg -// PPCAMode* am_addr; -// -// // fctiw (conv f64 to i32), PPC32 p404 -// p = mkFormX(p, 63, fr_tmp, 0, fr_src, 14, 0); -// -// // No RI form of stfiwx, so need PPCAMode_RR: -// am_addr = PPCAMode_RR( StackFramePtr(mode64), -// hregPPC_GPR0(mode64) ); -// -// // stfiwx (store fp64[lo32] as int32), PPC32 p517 -// p = doAMode_RR(p, 31, 983, fr_tmp, am_addr, mode64); -// -// // lwzx (load int32), PPC32 p463 -// p = doAMode_RR(p, 31, 23, r_dst, am_addr, mode64); -// goto done; -// } -// -// case Pin_FpF64toI64: { -// UInt r_dst = iregNo(i->Pin.FpF64toI64.dst, mode64); -// UInt fr_src = fregNo(i->Pin.FpF64toI64.src); -// UChar fr_tmp = 7; // Temp freg -// PPCAMode* am_addr; -// -// // fctid (conv f64 to i64), PPC64 p437 -// p = mkFormX(p, 63, fr_tmp, 0, fr_src, 814, 0); -// -// am_addr = PPCAMode_RR( StackFramePtr(mode64), -// hregPPC_GPR0(mode64) ); -// -// // stfdx (store fp64), PPC64 p589 -// p = doAMode_RR(p, 31, 727, fr_tmp, am_addr, mode64); -// -// // ldx (load int64), PPC64 p476 -// p = doAMode_RR(p, 31, 21, r_dst, am_addr, mode64); -// goto done; -// } -// -// case Pin_FpI64toF64: { -// UInt r_src = iregNo(i->Pin.FpI64toF64.src, mode64); -// UInt fr_dst = fregNo(i->Pin.FpI64toF64.dst); -// UChar fr_tmp = 7; // Temp freg -// PPCAMode* am_addr = PPCAMode_RR( StackFramePtr(mode64), -// hregPPC_GPR0(mode64) ); -// -// // stdx r_src,r0,r1 -// p = doAMode_RR(p, 31, 149, r_src, am_addr, mode64); -// -// // lfdx fr7,r0,r1 -// p = doAMode_RR(p, 31, 599, fr_tmp, am_addr, mode64); -// -// // fcfid (conv i64 to f64), PPC64 p434 -// p = mkFormX(p, 63, fr_dst, 0, fr_tmp, 846, 0); -// goto done; -// } - case Pin_FpCMov: { UInt fr_dst = fregNo(i->Pin.FpCMov.dst); UInt fr_src = fregNo(i->Pin.FpCMov.src); diff --git a/VEX/priv/host-ppc/hdefs.h b/VEX/priv/host-ppc/hdefs.h index bab0b7d0a3..622ef48d45 100644 --- a/VEX/priv/host-ppc/hdefs.h +++ b/VEX/priv/host-ppc/hdefs.h @@ -327,7 +327,8 @@ typedef Pun_NEG, Pun_NOT, Pun_CLZ32, - Pun_CLZ64 + Pun_CLZ64, + Pun_EXTSW } PPCUnaryOp; @@ -450,7 +451,7 @@ typedef Pin_Call, /* call to address in register */ Pin_Goto, /* conditional/unconditional jmp to dst */ Pin_CMov, /* conditional move */ - Pin_Load, /* load a 8|16|32|64 bit value from mem */ + Pin_Load, /* zero-extending load a 8|16|32|64 bit value from mem */ Pin_Store, /* store a 8|16|32|64 bit value to mem */ Pin_Set, /* convert condition code to value 0 or 1 */ Pin_MfCR, /* move from condition register to GPR */ @@ -543,7 +544,7 @@ typedef HReg srcL; PPCRH* srcR; } Cmp; - /* Not and Neg */ + /* Not, Neg, Clz32/64, Extsw */ struct { PPCUnaryOp op; HReg dst; @@ -589,10 +590,9 @@ typedef HReg dst; PPCRI* src; } CMov; - /* Sign/Zero extending loads. Dst size is host word size */ + /* Zero extending loads. Dst size is host word size */ struct { UChar sz; /* 1|2|4|8 */ - Bool syned; HReg dst; PPCAMode* src; } Load; @@ -774,7 +774,7 @@ extern PPCInstr* PPCInstr_Div ( Bool syned, Bool sz32, HReg dst, HReg src extern PPCInstr* PPCInstr_Call ( PPCCondCode, Addr64, UInt ); extern PPCInstr* PPCInstr_Goto ( IRJumpKind, PPCCondCode cond, PPCRI* dst ); extern PPCInstr* PPCInstr_CMov ( PPCCondCode, HReg dst, PPCRI* src ); -extern PPCInstr* PPCInstr_Load ( UChar sz, Bool syned, +extern PPCInstr* PPCInstr_Load ( UChar sz, HReg dst, PPCAMode* src, Bool mode64 ); extern PPCInstr* PPCInstr_Store ( UChar sz, PPCAMode* dst, HReg src, Bool mode64 ); diff --git a/VEX/priv/host-ppc/isel.c b/VEX/priv/host-ppc/isel.c index 2884076e1b..e4ecdda0d6 100644 --- a/VEX/priv/host-ppc/isel.c +++ b/VEX/priv/host-ppc/isel.c @@ -1029,7 +1029,7 @@ static HReg iselWordExpr_R_wrk ( ISelEnv* env, IRExpr* e ) if (e->Iex.Load.end != Iend_BE) goto irreducible; addInstr(env, PPCInstr_Load( toUChar(sizeofIRType(ty)), - False, r_dst, am_addr, mode64 )); + r_dst, am_addr, mode64 )); return r_dst; break; } @@ -1305,7 +1305,7 @@ static HReg iselWordExpr_R_wrk ( ISelEnv* env, IRExpr* e ) HReg fsrc = iselDblExpr(env, e->Iex.Binop.arg2); HReg ftmp = newVRegF(env); HReg idst = newVRegI(env); - vassert(!env->mode64); // wait for 64-bit test case + /* Set host rounding mode */ set_FPU_rounding_mode( env, e->Iex.Binop.arg1 ); @@ -1313,8 +1313,12 @@ static HReg iselWordExpr_R_wrk ( ISelEnv* env, IRExpr* e ) addInstr(env, PPCInstr_FpCftI(False/*F->I*/, True/*int32*/, ftmp, fsrc)); addInstr(env, PPCInstr_FpSTFIW(r1, ftmp)); - addInstr(env, PPCInstr_Load(4, True/*signed*/, - idst, zero_r1, mode64)); + addInstr(env, PPCInstr_Load(4, idst, zero_r1, mode64)); + + /* in 64-bit mode we need to sign-widen idst. */ + if (mode64) + addInstr(env, PPCInstr_Unary(Pun_EXTSW, idst, idst)); + add_to_sp( env, 16 ); /* Restore default FPU rounding. */ @@ -1323,19 +1327,27 @@ static HReg iselWordExpr_R_wrk ( ISelEnv* env, IRExpr* e ) } if (e->Iex.Binop.op == Iop_F64toI64) { - HReg fr_src = iselDblExpr(env, e->Iex.Binop.arg2); - HReg r_dst = newVRegI(env); - /* Set host rounding mode */ - set_FPU_rounding_mode( env, e->Iex.Binop.arg1 ); - - sub_from_sp( env, 16 ); -vassert(0); -// addInstr(env, PPCInstr_FpF64toI64(r_dst, fr_src)); - add_to_sp( env, 16 ); - - /* Restore default FPU rounding. */ - set_FPU_rounding_default( env ); - return r_dst; + if (mode64) { + HReg r1 = StackFramePtr(env->mode64); + PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 ); + HReg fsrc = iselDblExpr(env, e->Iex.Binop.arg2); + HReg idst = newVRegI(env); + HReg ftmp = newVRegF(env); + + /* Set host rounding mode */ + set_FPU_rounding_mode( env, e->Iex.Binop.arg1 ); + + sub_from_sp( env, 16 ); + addInstr(env, PPCInstr_FpCftI(False/*F->I*/, False/*int64*/, + ftmp, fsrc)); + addInstr(env, PPCInstr_FpLdSt(False/*store*/, 8, ftmp, zero_r1)); + addInstr(env, PPCInstr_Load(8, idst, zero_r1, True/*mode64*/)); + add_to_sp( env, 16 ); + + /* Restore default FPU rounding. */ + set_FPU_rounding_default( env ); + return idst; + } } break; @@ -1366,7 +1378,7 @@ vassert(0); if (matchIRExpr(&mi,p_LDbe16_then_16Uto32,e)) { HReg r_dst = newVRegI(env); PPCAMode* amode = iselWordExpr_AMode( env, mi.bindee[0] ); - addInstr(env, PPCInstr_Load(2,False,r_dst,amode, mode64)); + addInstr(env, PPCInstr_Load(2,r_dst,amode, mode64)); return r_dst; } } @@ -1566,7 +1578,7 @@ vassert(0); addInstr(env, PPCInstr_AvLdSt( False/*store*/, 16, vec, am_off0 )); addInstr(env, - PPCInstr_Load( 4, False, dst, am_off12, mode64 )); + PPCInstr_Load( 4, dst, am_off12, mode64 )); add_to_sp( env, 32 ); // Reset SP return dst; @@ -1591,7 +1603,7 @@ vassert(0); PPCInstr_AvLdSt( False/*store*/, 16, vec, am_off0 )); addInstr(env, PPCInstr_Load( - 8, False, dst, + 8, dst, op_unop == Iop_V128HIto64 ? am_off0 : am_off8, mode64 )); @@ -1624,8 +1636,7 @@ vassert(0); addInstr(env, PPCInstr_FpLdSt( False/*store*/, 8, fr_src, am_addr )); // load as Ity_I64 - addInstr(env, PPCInstr_Load( 8, False, - r_dst, am_addr, mode64 )); + addInstr(env, PPCInstr_Load( 8, r_dst, am_addr, mode64 )); add_to_sp( env, 16 ); // Reset SP return r_dst; @@ -1646,7 +1657,7 @@ vassert(0); PPCAMode* am_addr = PPCAMode_IR( e->Iex.Get.offset, GuestStatePtr(mode64) ); addInstr(env, PPCInstr_Load( toUChar(sizeofIRType(ty)), - False, r_dst, am_addr, mode64 )); + r_dst, am_addr, mode64 )); return r_dst; } break; @@ -1659,7 +1670,7 @@ vassert(0); e->Iex.GetI.ix, e->Iex.GetI.bias ); HReg r_dst = newVRegI(env); addInstr(env, PPCInstr_Load( toUChar(8), - False, r_dst, src_am, mode64 )); + r_dst, src_am, mode64 )); return r_dst; } break; @@ -2370,8 +2381,8 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, PPCAMode* am_addr4 = advance4(env, am_addr); HReg tLo = newVRegI(env); HReg tHi = newVRegI(env); - addInstr(env, PPCInstr_Load( 4, False, tHi, am_addr, False/*mode32*/ )); - addInstr(env, PPCInstr_Load( 4, False, tLo, am_addr4, False/*mode32*/ )); + addInstr(env, PPCInstr_Load( 4, tHi, am_addr, False/*mode32*/ )); + addInstr(env, PPCInstr_Load( 4, tLo, am_addr4, False/*mode32*/ )); *rHi = tHi; *rLo = tLo; return; @@ -2521,9 +2532,9 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, // load hi,lo words (of hi/lo half of vec) as Ity_I32's addInstr(env, - PPCInstr_Load( 4, False, tHi, am_offHI, False/*mode32*/ )); + PPCInstr_Load( 4, tHi, am_offHI, False/*mode32*/ )); addInstr(env, - PPCInstr_Load( 4, False, tLo, am_offLO, False/*mode32*/ )); + PPCInstr_Load( 4, tLo, am_offLO, False/*mode32*/ )); add_to_sp( env, 32 ); // Reset SP *rHi = tHi; @@ -2581,9 +2592,9 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, fr_src, am_addr0 )); // load hi,lo as Ity_I32's - addInstr(env, PPCInstr_Load( 4, False, r_dstHi, + addInstr(env, PPCInstr_Load( 4, r_dstHi, am_addr0, False/*mode32*/ )); - addInstr(env, PPCInstr_Load( 4, False, r_dstLo, + addInstr(env, PPCInstr_Load( 4, r_dstLo, am_addr1, False/*mode32*/ )); *rHi = r_dstHi; *rLo = r_dstLo; @@ -2782,21 +2793,28 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e ) } if (e->Iex.Binop.op == Iop_I64toF64) { - HReg fr_dst = newVRegF(env); - HReg r_src = iselWordExpr_R(env, e->Iex.Binop.arg2); - vassert(mode64); + if (mode64) { + HReg fdst = newVRegF(env); + HReg isrc = iselWordExpr_R(env, e->Iex.Binop.arg2); + HReg r1 = StackFramePtr(env->mode64); + PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 ); - /* Set host rounding mode */ - set_FPU_rounding_mode( env, e->Iex.Binop.arg1 ); + /* Set host rounding mode */ + set_FPU_rounding_mode( env, e->Iex.Binop.arg1 ); - sub_from_sp( env, 16 ); -vassert(0); -// addInstr(env, PPCInstr_FpI64toF64(fr_dst, r_src)); - add_to_sp( env, 16 ); + sub_from_sp( env, 16 ); - /* Restore default FPU rounding. */ - set_FPU_rounding_default( env ); - return fr_dst; + addInstr(env, PPCInstr_Store(8, zero_r1, isrc, True/*mode64*/)); + addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, fdst, zero_r1)); + addInstr(env, PPCInstr_FpCftI(True/*I->F*/, False/*int64*/, + fdst, fdst)); + + add_to_sp( env, 16 ); + + /* Restore default FPU rounding. */ + set_FPU_rounding_default( env ); + return fdst; + } } }