Dirk Mueller
f062078a7c
OBS-URL: https://build.opensuse.org/package/show/devel:tools/valgrind?expand=0&rev=29
212 lines
8.4 KiB
Diff
212 lines
8.4 KiB
Diff
Index: VEX/priv/host_ppc_defs.c
|
|
===================================================================
|
|
--- VEX/priv/host_ppc_defs.c.orig
|
|
+++ VEX/priv/host_ppc_defs.c
|
|
@@ -962,17 +962,65 @@ PPCInstr* PPCInstr_FpRSP ( HReg dst, HRe
|
|
i->Pin.FpRSP.src = src;
|
|
return i;
|
|
}
|
|
+
|
|
+/*
|
|
+Valid combo | fromI | int32 | syned | flt64 |
|
|
+--------------------------------------------
|
|
+ | n n n n |
|
|
+--------------------------------------------
|
|
+ F64->I64U | n n n y |
|
|
+--------------------------------------------
|
|
+ | n n y n |
|
|
+--------------------------------------------
|
|
+ F64->I64S | n n y y |
|
|
+--------------------------------------------
|
|
+ | n y n n |
|
|
+--------------------------------------------
|
|
+ F64->I32U | n y n y |
|
|
+--------------------------------------------
|
|
+ | n y y n |
|
|
+--------------------------------------------
|
|
+ F64->I32S | n y y y |
|
|
+--------------------------------------------
|
|
+ I64U->F32 | y n n n |
|
|
+--------------------------------------------
|
|
+ I64U->F64 | y n n y |
|
|
+--------------------------------------------
|
|
+ | y n y n |
|
|
+--------------------------------------------
|
|
+ I64S->F64 | y n y y |
|
|
+--------------------------------------------
|
|
+ | y y n n |
|
|
+--------------------------------------------
|
|
+ | y y n y |
|
|
+--------------------------------------------
|
|
+ | y y y n |
|
|
+--------------------------------------------
|
|
+ | y y y y |
|
|
+--------------------------------------------
|
|
+*/
|
|
PPCInstr* PPCInstr_FpCftI ( Bool fromI, Bool int32, Bool syned,
|
|
- Bool dst64, HReg dst, HReg src ) {
|
|
+ Bool flt64, HReg dst, HReg src ) {
|
|
+ Bool tmp = fromI | int32 | syned | flt64;
|
|
+ vassert(tmp == True || tmp == False); // iow, no high bits set
|
|
+ UShort conversion = 0;
|
|
+ conversion = (fromI << 3) | (int32 << 2) | (syned << 1) | flt64;
|
|
+ switch (conversion) {
|
|
+ // Supported conversion operations
|
|
+ case 1: case 3: case 5: case 7:
|
|
+ case 8: case 9: case 11:
|
|
+ break;
|
|
+ default:
|
|
+ vpanic("PPCInstr_FpCftI(ppc_host)");
|
|
+ }
|
|
PPCInstr* i = LibVEX_Alloc(sizeof(PPCInstr));
|
|
i->tag = Pin_FpCftI;
|
|
i->Pin.FpCftI.fromI = fromI;
|
|
i->Pin.FpCftI.int32 = int32;
|
|
i->Pin.FpCftI.syned = syned;
|
|
- i->Pin.FpCftI.dst64 = dst64;
|
|
+ i->Pin.FpCftI.flt64 = flt64;
|
|
i->Pin.FpCftI.dst = dst;
|
|
i->Pin.FpCftI.src = src;
|
|
- vassert(!(int32 && fromI)); /* no such insn ("fcfiw"). */
|
|
return i;
|
|
}
|
|
PPCInstr* PPCInstr_FpCMov ( PPCCondCode cond, HReg dst, HReg src ) {
|
|
@@ -1445,7 +1493,7 @@ void ppPPCInstr ( PPCInstr* i, Bool mode
|
|
if (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == False) {
|
|
if (i->Pin.FpCftI.syned == True)
|
|
str = "fcfid";
|
|
- else if (i->Pin.FpCftI.dst64 == True)
|
|
+ else if (i->Pin.FpCftI.flt64 == True)
|
|
str = "fcfidu";
|
|
else
|
|
str = "fcfidus";
|
|
@@ -3397,7 +3445,7 @@ Int emit_PPCInstr ( UChar* buf, Int nbuf
|
|
// fcfid (conv i64 to f64), PPC64 p434
|
|
p = mkFormX(p, 63, fr_dst, 0, fr_src, 846, 0);
|
|
goto done;
|
|
- } else if (i->Pin.FpCftI.dst64 == True) {
|
|
+ } else if (i->Pin.FpCftI.flt64 == True) {
|
|
// fcfidu (conv u64 to f64)
|
|
p = mkFormX(p, 63, fr_dst, 0, fr_src, 974, 0);
|
|
goto done;
|
|
Index: VEX/priv/host_ppc_defs.h
|
|
===================================================================
|
|
--- VEX/priv/host_ppc_defs.h.orig
|
|
+++ VEX/priv/host_ppc_defs.h
|
|
@@ -461,7 +461,7 @@ typedef
|
|
Pin_FpLdSt, /* FP load/store */
|
|
Pin_FpSTFIW, /* stfiwx */
|
|
Pin_FpRSP, /* FP round IEEE754 double to IEEE754 single */
|
|
- Pin_FpCftI, /* fcfid/fctid/fctiw */
|
|
+ Pin_FpCftI, /* fcfid[u,s,us]/fctid[u]/fctiw[u] */
|
|
Pin_FpCMov, /* FP floating point conditional move */
|
|
Pin_FpLdFPSCR, /* mtfsf */
|
|
Pin_FpCmp, /* FP compare, generating value into int reg */
|
|
@@ -662,13 +662,15 @@ typedef
|
|
HReg src;
|
|
HReg dst;
|
|
} FpRSP;
|
|
- /* fcfid/fctid/fctiw. Note there's no fcfiw so fromI==True
|
|
- && int32==True is not allowed. */
|
|
+ /* fcfid[u,s,us]/fctid[u]/fctiw[u]. Only some combinations
|
|
+ of the various fields are allowed. This is asserted for
|
|
+ and documented in the code for the constructor,
|
|
+ PPCInstr_FpCftI, in host_ppc_defs.c. */
|
|
struct {
|
|
- Bool fromI; /* False==F->I, True==I->F */
|
|
- Bool int32; /* True== I is 32, False==I is 64 */
|
|
+ Bool fromI; /* True== I->F, False== F->I */
|
|
+ Bool int32; /* True== I is 32, False== I is 64 */
|
|
Bool syned;
|
|
- Bool dst64; /* True==dest is 64bit; False==dest is 32bit */
|
|
+ Bool flt64; /* True== F is 64, False== F is 32 */
|
|
HReg src;
|
|
HReg dst;
|
|
} FpCftI;
|
|
Index: VEX/priv/host_ppc_isel.c
|
|
===================================================================
|
|
--- VEX/priv/host_ppc_isel.c.orig
|
|
+++ VEX/priv/host_ppc_isel.c
|
|
@@ -1471,8 +1471,9 @@ static HReg iselWordExpr_R_wrk ( ISelEnv
|
|
set_FPU_rounding_mode( env, e->Iex.Binop.arg1 );
|
|
|
|
sub_from_sp( env, 16 );
|
|
- addInstr(env, PPCInstr_FpCftI(False/*F->I*/, True/*int32*/, True,
|
|
- False, ftmp, fsrc));
|
|
+ addInstr(env, PPCInstr_FpCftI(False/*F->I*/, True/*int32*/,
|
|
+ True/*syned*/, True/*flt64*/,
|
|
+ ftmp, fsrc));
|
|
addInstr(env, PPCInstr_FpSTFIW(r1, ftmp));
|
|
addInstr(env, PPCInstr_Load(4, idst, zero_r1, mode64));
|
|
|
|
@@ -2959,6 +2960,8 @@ static HReg iselFltExpr ( ISelEnv* env,
|
|
/* DO NOT CALL THIS DIRECTLY */
|
|
static HReg iselFltExpr_wrk ( ISelEnv* env, IRExpr* e )
|
|
{
|
|
+ Bool mode64 = env->mode64;
|
|
+
|
|
IRType ty = typeOfIRExpr(env->type_env,e);
|
|
vassert(ty == Ity_F32);
|
|
|
|
@@ -3027,6 +3030,60 @@ static HReg iselFltExpr_wrk ( ISelEnv* e
|
|
return fdst;
|
|
}
|
|
|
|
+ if (e->tag == Iex_Binop && e->Iex.Binop.op == Iop_I64UtoF32) {
|
|
+ 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 );
|
|
+
|
|
+ sub_from_sp( env, 16 );
|
|
+
|
|
+ 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*/,
|
|
+ False, False,
|
|
+ fdst, fdst));
|
|
+
|
|
+ add_to_sp( env, 16 );
|
|
+
|
|
+ ///* Restore default FPU rounding. */
|
|
+ //set_FPU_rounding_default( env );
|
|
+ return fdst;
|
|
+ } else {
|
|
+ /* 32-bit mode */
|
|
+ HReg fdst = newVRegF(env);
|
|
+ HReg isrcHi, isrcLo;
|
|
+ HReg r1 = StackFramePtr(env->mode64);
|
|
+ PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
|
|
+ PPCAMode* four_r1 = PPCAMode_IR( 4, r1 );
|
|
+
|
|
+ iselInt64Expr(&isrcHi, &isrcLo, env, e->Iex.Binop.arg2);
|
|
+
|
|
+ /* Set host rounding mode */
|
|
+ set_FPU_rounding_mode( env, e->Iex.Binop.arg1 );
|
|
+
|
|
+ sub_from_sp( env, 16 );
|
|
+
|
|
+ addInstr(env, PPCInstr_Store(4, zero_r1, isrcHi, False/*mode32*/));
|
|
+ addInstr(env, PPCInstr_Store(4, four_r1, isrcLo, False/*mode32*/));
|
|
+ addInstr(env, PPCInstr_FpLdSt(True/*load*/, 8, fdst, zero_r1));
|
|
+ addInstr(env, PPCInstr_FpCftI(True/*I->F*/, False/*int64*/,
|
|
+ False, False,
|
|
+ fdst, fdst));
|
|
+
|
|
+ add_to_sp( env, 16 );
|
|
+
|
|
+ ///* Restore default FPU rounding. */
|
|
+ //set_FPU_rounding_default( env );
|
|
+ return fdst;
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
vex_printf("iselFltExpr(ppc): No such tag(%u)\n", e->tag);
|
|
ppIRExpr(e);
|
|
vpanic("iselFltExpr_wrk(ppc)");
|