File vg_bug270851_r2148.patch of Package valgrind

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)");
openSUSE Build Service is sponsored by