]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Change the way the ppc backend does ppc32/64 float-integer
authorJulian Seward <jseward@acm.org>
Wed, 25 Jan 2006 21:29:48 +0000 (21:29 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 25 Jan 2006 21:29:48 +0000 (21:29 +0000)
conversions.  fctiw/fctid/fcfid/stfiwx are now represented explicitly
and are generated by the instruction selector.  This removes the need
for hdefs.c to know anything about scratch areas on the stack and
scratch FP registers.

git-svn-id: svn://svn.valgrind.org/vex/trunk@1550

VEX/priv/host-ppc/hdefs.c
VEX/priv/host-ppc/hdefs.h
VEX/priv/host-ppc/isel.c

index e88e5f148fc44142548e0bc3d4d6d9966e9148ec..06b964f5b4eb91de042ffedc96b64931b664b757 100644 (file)
@@ -910,32 +910,30 @@ PPCInstr* PPCInstr_FpLdSt ( Bool isLoad, UChar sz,
    vassert(sz == 4 || sz == 8);
    return i;
 }
-PPCInstr* PPCInstr_FpF64toF32 ( HReg dst, HReg src ) {
-   PPCInstr* i           = LibVEX_Alloc(sizeof(PPCInstr));
-   i->tag                = Pin_FpF64toF32;
-   i->Pin.FpF64toF32.dst = dst;
-   i->Pin.FpF64toF32.src = src;
-   return i;
-}
-PPCInstr* PPCInstr_FpF64toI32 ( HReg dst, HReg src ) {
-   PPCInstr* i           = LibVEX_Alloc(sizeof(PPCInstr));
-   i->tag                = Pin_FpF64toI32;
-   i->Pin.FpF64toI32.dst = dst;
-   i->Pin.FpF64toI32.src = src;
+PPCInstr* PPCInstr_FpSTFIW ( HReg addr, HReg data )
+{
+   PPCInstr* i         = LibVEX_Alloc(sizeof(PPCInstr));
+   i->tag              = Pin_FpSTFIW;
+   i->Pin.FpSTFIW.addr = addr;
+   i->Pin.FpSTFIW.data = data;
    return i;
 }
-PPCInstr* PPCInstr_FpF64toI64 ( HReg dst, HReg src ) {
-   PPCInstr* i           = LibVEX_Alloc(sizeof(PPCInstr));
-   i->tag                = Pin_FpF64toI64;
-   i->Pin.FpF64toI64.dst = dst;
-   i->Pin.FpF64toI64.src = src;
+PPCInstr* PPCInstr_FpRSP ( HReg dst, HReg src ) {
+   PPCInstr* i      = LibVEX_Alloc(sizeof(PPCInstr));
+   i->tag           = Pin_FpRSP;
+   i->Pin.FpRSP.dst = dst;
+   i->Pin.FpRSP.src = src;
    return i;
 }
-PPCInstr* PPCInstr_FpI64toF64 ( HReg dst, HReg src ) {
-   PPCInstr* i           = LibVEX_Alloc(sizeof(PPCInstr));
-   i->tag                = Pin_FpI64toF64;
-   i->Pin.FpI64toF64.dst = dst;
-   i->Pin.FpI64toF64.src = src;
+PPCInstr* PPCInstr_FpCftI ( Bool fromI, Bool int32, 
+                            HReg dst, HReg src ) {
+   PPCInstr* i         = LibVEX_Alloc(sizeof(PPCInstr));
+   i->tag              = Pin_FpCftI;
+   i->Pin.FpCftI.fromI = fromI;
+   i->Pin.FpCftI.int32 = int32;
+   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 ) {
@@ -1417,37 +1415,35 @@ void ppPPCInstr ( PPCInstr* i, Bool mode64 )
       }
       return;
    }
-   case Pin_FpF64toF32:
+   case Pin_FpSTFIW:
+      vex_printf("stfiwz ");
+      ppHRegPPC(i->Pin.FpSTFIW.data);
+      vex_printf(",0(");
+      ppHRegPPC(i->Pin.FpSTFIW.addr);
+      vex_printf(")");
+      return;
+   case Pin_FpRSP:
       vex_printf("frsp ");
-      ppHRegPPC(i->Pin.FpF64toF32.dst);
+      ppHRegPPC(i->Pin.FpRSP.dst);
+      vex_printf(",");
+      ppHRegPPC(i->Pin.FpRSP.src);
+      return;
+   case Pin_FpCftI: {
+      HChar* str = "fc???";
+      if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == False)
+         str = "fctid";
+      else
+      if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == True)
+         str = "fctiw";
+      else
+      if (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == False)
+         str = "fcfid";
+      vex_printf("%s ", str);
+      ppHRegPPC(i->Pin.FpCftI.dst);
       vex_printf(",");
-      ppHRegPPC(i->Pin.FpF64toF32.src);
-      return;
-   case Pin_FpF64toI32:
-      vex_printf("fctiw %%fr7,");
-      ppHRegPPC(i->Pin.FpF64toI32.src);
-      vex_printf("; stfiwx %%fr7,%%r0,%%r1");
-      vex_printf("; lwzx ");
-      ppHRegPPC(i->Pin.FpF64toI32.dst);
-      vex_printf(",%%r0,%%r1");
-      return;
-   case Pin_FpF64toI64:
-      vex_printf("fctid %%fr7,");
-      ppHRegPPC(i->Pin.FpF64toI64.src);
-      vex_printf("; stfdx %%fr7,%%r0,%%r1");
-      vex_printf("; ldx ");
-      ppHRegPPC(i->Pin.FpF64toI64.dst);
-      vex_printf(",%%r0,%%r1");
-      return;
-   case Pin_FpI64toF64:
-      vex_printf("stdx ");
-      ppHRegPPC(i->Pin.FpI64toF64.src);
-      vex_printf(",%%r0,%%r1");
-      vex_printf("; lfdx %%fr7,%%r0,%%r1");
-      vex_printf("; fcfid ");
-      ppHRegPPC(i->Pin.FpI64toF64.dst);
-      vex_printf(",%%r7");
+      ppHRegPPC(i->Pin.FpCftI.src);
       return;
+   }
    case Pin_FpCMov:
       vex_printf("fpcmov (%s) ", showPPCCondCode(i->Pin.FpCMov.cond));
       ppHRegPPC(i->Pin.FpCMov.dst);
@@ -1778,24 +1774,17 @@ void getRegUsage_PPCInstr ( HRegUsage* u, PPCInstr* i, Bool mode64 )
                  i->Pin.FpLdSt.reg);
       addRegUsage_PPCAMode(u, i->Pin.FpLdSt.addr);
       return;
-   case Pin_FpF64toF32:
-      addHRegUse(u, HRmWrite, i->Pin.FpF64toF32.dst);
-      addHRegUse(u, HRmRead,  i->Pin.FpF64toF32.src);
-      return;
-   case Pin_FpF64toI32:
-      addHRegUse(u, HRmWrite, i->Pin.FpF64toI32.dst);
-      addHRegUse(u, HRmWrite, hregPPC_FPR7());
-      addHRegUse(u, HRmRead,  i->Pin.FpF64toI32.src);
+   case Pin_FpSTFIW:
+      addHRegUse(u, HRmRead, i->Pin.FpSTFIW.addr);
+      addHRegUse(u, HRmRead, i->Pin.FpSTFIW.data);
       return;
-   case Pin_FpF64toI64:
-      addHRegUse(u, HRmWrite, i->Pin.FpF64toI64.dst);
-      addHRegUse(u, HRmWrite, hregPPC_FPR7());
-      addHRegUse(u, HRmRead,  i->Pin.FpF64toI64.src);
+   case Pin_FpRSP:
+      addHRegUse(u, HRmWrite, i->Pin.FpRSP.dst);
+      addHRegUse(u, HRmRead,  i->Pin.FpRSP.src);
       return;
-   case Pin_FpI64toF64:
-      addHRegUse(u, HRmWrite, i->Pin.FpI64toF64.dst);
-      addHRegUse(u, HRmWrite, hregPPC_FPR7());
-      addHRegUse(u, HRmRead,  i->Pin.FpI64toF64.src);
+   case Pin_FpCftI:
+      addHRegUse(u, HRmWrite, i->Pin.FpCftI.dst);
+      addHRegUse(u, HRmRead,  i->Pin.FpCftI.src);
       return;
    case Pin_FpCMov:
       addHRegUse(u, HRmModify, i->Pin.FpCMov.dst);
@@ -1983,21 +1972,17 @@ void mapRegs_PPCInstr ( HRegRemap* m, PPCInstr* i, Bool mode64 )
       mapReg(m, &i->Pin.FpLdSt.reg);
       mapRegs_PPCAMode(m, i->Pin.FpLdSt.addr);
       return;
-   case Pin_FpF64toF32:
-      mapReg(m, &i->Pin.FpF64toF32.dst);
-      mapReg(m, &i->Pin.FpF64toF32.src);
-      return;
-   case Pin_FpF64toI32:
-      mapReg(m, &i->Pin.FpF64toI32.dst);
-      mapReg(m, &i->Pin.FpF64toI32.src);
+   case Pin_FpSTFIW:
+      mapReg(m, &i->Pin.FpSTFIW.addr);
+      mapReg(m, &i->Pin.FpSTFIW.data);
       return;
-   case Pin_FpF64toI64:
-      mapReg(m, &i->Pin.FpF64toI64.dst);
-      mapReg(m, &i->Pin.FpF64toI64.src);
+   case Pin_FpRSP:
+      mapReg(m, &i->Pin.FpRSP.dst);
+      mapReg(m, &i->Pin.FpRSP.src);
       return;
-   case Pin_FpI64toF64:
-      mapReg(m, &i->Pin.FpI64toF64.dst);
-      mapReg(m, &i->Pin.FpI64toF64.src);
+   case Pin_FpCftI:
+      mapReg(m, &i->Pin.FpCftI.dst);
+      mapReg(m, &i->Pin.FpCftI.src);
       return;
    case Pin_FpCMov:
       mapReg(m, &i->Pin.FpCMov.dst);
@@ -3205,73 +3190,93 @@ Int emit_PPCInstr ( UChar* buf, Int nbuf, PPCInstr* i,
       goto done;
    }
 
-   case Pin_FpF64toF32: {
-      UInt fr_dst = fregNo(i->Pin.FpF64toF32.dst);
-      UInt fr_src = fregNo(i->Pin.FpF64toF32.src);
-      // frsp, PPC32 p423
-      p = mkFormX(p, 63, fr_dst, 0, fr_src, 12, 0);
-      goto done;
-   }
-
-   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) );
-
+   case Pin_FpSTFIW: {
+      UInt ir_addr = iregNo(i->Pin.FpSTFIW.addr, mode64);
+      UInt fr_data = fregNo(i->Pin.FpSTFIW.data);
       // 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);
+      // Use rA==0, so that EA == rB == ir_addr
+      p = mkFormX(p, 31, fr_data, 0/*rA=0*/, ir_addr, 983, 0);
       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);
+   case Pin_FpRSP: {
+      UInt fr_dst = fregNo(i->Pin.FpRSP.dst);
+      UInt fr_src = fregNo(i->Pin.FpRSP.src);
+      // frsp, PPC32 p423
+      p = mkFormX(p, 63, fr_dst, 0, fr_src, 12, 0);
       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_FpCftI: {
+      UInt fr_dst = fregNo(i->Pin.FpCftI.dst);
+      UInt fr_src = fregNo(i->Pin.FpCftI.src);
+      if (i->Pin.FpCftI.fromI == False && i->Pin.FpCftI.int32 == True) {
+         // fctiw (conv f64 to i32), PPC32 p404
+         p = mkFormX(p, 63, fr_dst, 0, fr_src, 14, 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);
index e4a00133fd07c2d80fefe18c2a60b1611174980f..bab0b7d0a370df0dd0a16af65c2b5688d44f0b8b 100644 (file)
@@ -207,8 +207,8 @@ extern PPCCondTest invertCondTest ( PPCCondTest );
 
 typedef
    enum {
-     Pam_IR,        /* Immediate (signed 16-bit) + Reg */
-     Pam_RR         /* Reg1 + Reg2     */
+     Pam_IR=1,      /* Immediate (signed 16-bit) + Reg */
+     Pam_RR=2       /* Reg1 + Reg2     */
    }
    PPCAModeTag;
 
@@ -240,8 +240,8 @@ extern void ppPPCAMode ( PPCAMode* );
 /* ("RH" == "Register or Halfword immediate") */
 typedef 
    enum {
-      Prh_Imm=1,
-      Prh_Reg=2
+      Prh_Imm=3,
+      Prh_Reg=4
    }
    PPCRHTag;
 
@@ -271,8 +271,8 @@ extern void ppPPCRH ( PPCRH* );
 
 typedef
    enum {
-      Pri_Imm=3,
-      Pri_Reg=4
+      Pri_Imm=5,
+      Pri_Reg=6
    } 
    PPCRITag;
 
@@ -297,8 +297,8 @@ extern void ppPPCRI ( PPCRI* );
 /* ("VI" == "Vector Register or Immediate") */
 typedef
    enum {
-      Pvi_Imm=5,
-      Pvi_Reg=6
+      Pvi_Imm=7,
+      Pvi_Reg=8
    } 
    PPCVI5sTag;
 
@@ -459,16 +459,15 @@ typedef
       Pin_FpUnary,    /* FP unary op */
       Pin_FpBinary,   /* FP binary op */
       Pin_FpLdSt,     /* FP load/store */
-      Pin_FpF64toF32, /* FP round IEEE754 double to IEEE754 single */
-      Pin_FpF64toI32, /* FP round IEEE754 double to 32-bit integer */
-      Pin_FpF64toI64, /* FP round IEEE754 double to 64-bit integer */
-      Pin_FpI64toF64, /* FP round IEEE754 64-bit integer to double */
+      Pin_FpSTFIW,    /* stfiwx */
+      Pin_FpRSP,      /* FP round IEEE754 double to IEEE754 single */
+      Pin_FpCftI,     /* fcfid/fctid/fctiw */
       Pin_FpCMov,     /* FP floating point conditional move */
       Pin_FpLdFPSCR,  /* mtfsf */
       Pin_FpCmp,      /* FP compare, generating value into int reg */
+
       Pin_RdWrLR,     /* Read/Write Link Register */
 
-//    Pin_AvConst,    /* Generate restricted AV literal */
       Pin_AvLdSt,     /* AV load/store (kludging for AMode_IR) */
       Pin_AvUnary,    /* AV unary general reg=>reg */
 
@@ -636,31 +635,24 @@ typedef
             HReg      reg;
             PPCAMode* addr;
          } FpLdSt;
-         /* By observing the current FPU rounding mode, round src->dst,
-            re-interpreting dst to an IEEE754 32-bit (float) type. */
-         struct {
-            HReg src;
-            HReg dst;
-         } FpF64toF32;
-         /* By observing the current FPU rounding mode, round src->dst,
-            re-interpreting dst to an 32-bit integer type. */
          struct {
-            HReg src;
-            HReg dst;
-         } FpF64toI32;
-         /* Ditto to 64-bit integer type. */
+            HReg addr; /* int reg */
+            HReg data; /* float reg */
+         } FpSTFIW;
+         /* Round 64-bit FP value to 32-bit FP value in an FP reg. */
          struct {
             HReg src;
             HReg dst;
-         } FpF64toI64;
-         /* By observing the current FPU rounding mode, reinterpret src
-            from a 64bit integer to double type, and round into dst. */
+         } FpRSP;
+         /* fcfid/fctid/fctiw.  Note there's no fcfiw so fromI==True
+            && int32==True is not allowed. */
          struct {
+            Bool fromI; /* False==F->I, True==I->F */
+            Bool int32; /* True== I is 32, False==I is 64 */
             HReg src;
             HReg dst;
-         } FpI64toF64;
-         /* Mov src to dst on the given condition, which may not
-            be the bogus Xcc_ALWAYS. */
+         } FpCftI;
+         /* FP mov src to dst on the given condition. */
          struct {
             PPCCondCode cond;
             HReg        dst;
@@ -793,10 +785,10 @@ extern PPCInstr* PPCInstr_MFence     ( void );
 extern PPCInstr* PPCInstr_FpUnary    ( PPCFpOp op, HReg dst, HReg src );
 extern PPCInstr* PPCInstr_FpBinary   ( PPCFpOp op, HReg dst, HReg srcL, HReg srcR );
 extern PPCInstr* PPCInstr_FpLdSt     ( Bool isLoad, UChar sz, HReg, PPCAMode* );
-extern PPCInstr* PPCInstr_FpF64toF32 ( HReg dst, HReg src );
-extern PPCInstr* PPCInstr_FpF64toI32 ( HReg dst, HReg src );
-extern PPCInstr* PPCInstr_FpF64toI64 ( HReg dst, HReg src );
-extern PPCInstr* PPCInstr_FpI64toF64 ( HReg dst, HReg src );
+extern PPCInstr* PPCInstr_FpSTFIW    ( HReg addr, HReg data );
+extern PPCInstr* PPCInstr_FpRSP      ( HReg dst, HReg src );
+extern PPCInstr* PPCInstr_FpCftI     ( Bool fromI, Bool int32, 
+                                       HReg dst, HReg src );
 extern PPCInstr* PPCInstr_FpCMov     ( PPCCondCode, HReg dst, HReg src );
 extern PPCInstr* PPCInstr_FpLdFPSCR  ( HReg src );
 extern PPCInstr* PPCInstr_FpCmp      ( HReg dst, HReg srcL, HReg srcR );
index 1edb6125f5b09b4c7283a894bc1ed7d90d31279b..2884076e1b4f4758bd6e2097b3c10f5b67310635 100644 (file)
@@ -1299,18 +1299,27 @@ static HReg iselWordExpr_R_wrk ( ISelEnv* env, IRExpr* e )
       }
 
       if (e->Iex.Binop.op == Iop_F64toI32) {
-         HReg fr_src = iselDblExpr(env, e->Iex.Binop.arg2);
-         HReg r_dst = newVRegI(env);         
+         /* This works in both mode64 and mode32. */
+         HReg      r1      = StackFramePtr(env->mode64);
+         PPCAMode* zero_r1 = PPCAMode_IR( 0, r1 );
+         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 );
 
          sub_from_sp( env, 16 );
-         addInstr(env, PPCInstr_FpF64toI32(r_dst, fr_src));
+         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));
          add_to_sp( env, 16 );
 
          /* Restore default FPU rounding. */
          set_FPU_rounding_default( env );
-         return r_dst;
+         return idst;
       }
 
       if (e->Iex.Binop.op == Iop_F64toI64) {
@@ -1320,7 +1329,8 @@ static HReg iselWordExpr_R_wrk ( ISelEnv* env, IRExpr* e )
          set_FPU_rounding_mode( env, e->Iex.Binop.arg1 );
 
          sub_from_sp( env, 16 );
-         addInstr(env, PPCInstr_FpF64toI64(r_dst, fr_src));
+vassert(0);
+//         addInstr(env, PPCInstr_FpF64toI64(r_dst, fr_src));
          add_to_sp( env, 16 );
 
          /* Restore default FPU rounding. */
@@ -2638,7 +2648,7 @@ static HReg iselFltExpr_wrk ( ISelEnv* env, IRExpr* e )
       HReg r_dst = newVRegF(env);
       HReg r_src = iselDblExpr(env, e->Iex.Binop.arg2);
       set_FPU_rounding_mode( env, e->Iex.Binop.arg1 );
-      addInstr(env, PPCInstr_FpF64toF32(r_dst, r_src));
+      addInstr(env, PPCInstr_FpRSP(r_dst, r_src));
       set_FPU_rounding_default( env );
       return r_dst;
    }
@@ -2780,7 +2790,8 @@ static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e )
          set_FPU_rounding_mode( env, e->Iex.Binop.arg1 );
 
          sub_from_sp( env, 16 );
-         addInstr(env, PPCInstr_FpI64toF64(fr_dst, r_src));
+vassert(0);
+//         addInstr(env, PPCInstr_FpI64toF64(fr_dst, r_src));
          add_to_sp( env, 16 );
 
          /* Restore default FPU rounding. */