]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
A bit more backend tidying:
authorJulian Seward <jseward@acm.org>
Thu, 26 Jan 2006 02:24:17 +0000 (02:24 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 26 Jan 2006 02:24:17 +0000 (02:24 +0000)
- fix up more float-integer conversions
- remove unused signedness field on PPCInstr_Load

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

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

index 06b964f5b4eb91de042ffedc96b64931b664b757..6d027285d2191af7e353f4c21c35e6fe9769fa99 100644 (file)
@@ -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);
index bab0b7d0a370df0dd0a16af65c2b5688d44f0b8b..622ef48d4566b0d52c3b3c646940e889d7943b2b 100644 (file)
@@ -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 );
index 2884076e1b4f4758bd6e2097b3c10f5b67310635..e4ecdda0d695576caade81e72116f91e3a9a5a25 100644 (file)
@@ -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;
+         }
       }
    }