]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/host_ppc_defs.c
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / VEX / priv / host_ppc_defs.c
index 54fd2fd68c2accabe2675bf95558cc7cacf781a8..c28fc62159af4ada0ef4742c394a197f70021ed8 100644 (file)
@@ -286,6 +286,8 @@ HChar* showPPCCondCode ( PPCCondCode cond )
       return (cond.test == Pct_TRUE) ? "cr7.gt=1" : "cr7.gt=0";
    case Pcf_7LT:
       return (cond.test == Pct_TRUE) ? "cr7.lt=1" : "cr7.lt=0";
+   case Pcf_NONE:
+      return "no-flag";
    default: vpanic("ppPPCCondCode");
    }
 }
@@ -296,6 +298,11 @@ PPCCondCode mk_PPCCondCode ( PPCCondTest test, PPCCondFlag flag )
    PPCCondCode cc;
    cc.flag = flag;
    cc.test = test;
+   if (test == Pct_ALWAYS) { 
+      vassert(flag == Pcf_NONE);
+   } else {
+      vassert(flag != Pcf_NONE);
+   }
    return cc;
 }
 
@@ -962,15 +969,65 @@ PPCInstr* PPCInstr_FpRSP ( HReg dst, HReg src ) {
    i->Pin.FpRSP.src = src;
    return i;
 }
-PPCInstr* PPCInstr_FpCftI ( Bool fromI, Bool int32, 
-                            HReg dst, HReg src ) {
+
+/*
+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 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.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 ) {
@@ -1065,7 +1122,7 @@ PPCInstr* PPCInstr_AvBin32x4 ( PPCAvOp op, HReg dst,
    i->Pin.AvBin32x4.srcR = srcR;
    return i;
 }
-PPCInstr* PPCInstr_AvBin32Fx4 ( PPCAvOp op, HReg dst,
+PPCInstr* PPCInstr_AvBin32Fx4 ( PPCAvFpOp op, HReg dst,
                                 HReg srcL, HReg srcR ) {
    PPCInstr* i            = LibVEX_Alloc(sizeof(PPCInstr));
    i->tag                 = Pin_AvBin32Fx4;
@@ -1075,7 +1132,7 @@ PPCInstr* PPCInstr_AvBin32Fx4 ( PPCAvOp op, HReg dst,
    i->Pin.AvBin32Fx4.srcR = srcR;
    return i;
 }
-PPCInstr* PPCInstr_AvUn32Fx4 ( PPCAvOp op, HReg dst, HReg src ) {
+PPCInstr* PPCInstr_AvUn32Fx4 ( PPCAvFpOp op, HReg dst, HReg src ) {
    PPCInstr* i          = LibVEX_Alloc(sizeof(PPCInstr));
    i->tag               = Pin_AvUn32Fx4;
    i->Pin.AvUn32Fx4.op  = op;
@@ -1433,15 +1490,21 @@ void ppPPCInstr ( PPCInstr* i, Bool mode64 )
       ppHRegPPC(i->Pin.FpRSP.src);
       return;
    case Pin_FpCftI: {
-      HChar* str = "fc???";
+      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";
+      if (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == False) {
+         if (i->Pin.FpCftI.syned == True)
+            str = "fcfid";
+         else if (i->Pin.FpCftI.flt64 == True)
+            str = "fcfidu";
+         else
+            str = "fcfidus";
+      }
       vex_printf("%s ", str);
       ppHRegPPC(i->Pin.FpCftI.dst);
       vex_printf(",");
@@ -3144,6 +3207,7 @@ Int emit_PPCInstr ( UChar* buf, Int nbuf, PPCInstr* i,
          // Just load 1 to dst => li dst,1
          p = mkFormD(p, 14, r_dst, 0, 1);
       } else {
+         vassert(cond.flag != Pcf_NONE);
          rot_imm = 1 + cond.flag;
          r_tmp = 0;  // Not set in getAllocable, so no need to declare.
 
@@ -3385,9 +3449,19 @@ Int emit_PPCInstr ( UChar* buf, Int nbuf, PPCInstr* i,
          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;
+         if (i->Pin.FpCftI.syned == True) {
+            // 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.flt64 == True) {
+            // fcfidu (conv u64 to f64)
+            p = mkFormX(p, 63, fr_dst, 0, fr_src, 974, 0);
+            goto done;
+         } else {
+            // fcfidus (conv u64 to f32)
+            p = mkFormX(p, 59, fr_dst, 0, fr_src, 974, 0);
+            goto done;
+         }
       }
       goto bad;
    }