]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Implemented most of the remaining altivec fp ops:
authorCerion Armour-Brown <cerion@valgrind.org>
Wed, 16 Nov 2005 18:02:58 +0000 (18:02 +0000)
committerCerion Armour-Brown <cerion@valgrind.org>
Wed, 16 Nov 2005 18:02:58 +0000 (18:02 +0000)
rounds (vrfi*), converts (vctu/sxs, vcfu/sx)

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

VEX/priv/guest-ppc32/toIR.c
VEX/priv/host-ppc32/hdefs.c
VEX/priv/host-ppc32/hdefs.h
VEX/priv/host-ppc32/isel.c

index 70fbab0eb159acb3317a1354137d88fa82fcb96c..d43aae9a938db4dc9e16ad8a0e1801ca253a6f11 100644 (file)
@@ -6811,14 +6811,10 @@ static Bool dis_av_fp_arith ( UInt theInstr )
       return True;
 
    case 0x2F: { // vnmsubfp (Negative Multiply-Subtract FP, AV p215)
-      IRTemp zeros = newTemp(Ity_V128);
       DIP("vnmsubfp v%d,v%d,v%d,v%d\n", vD_addr, vA_addr, vC_addr, vB_addr);
-      assign( zeros, unop(Iop_Dup32x4, mkU32(0)) );
-      putVReg( vD_addr,
-               binop(Iop_Sub32Fx4, mkexpr(zeros),
-                     binop(Iop_Sub32Fx4,
-                           binop(Iop_Mul32Fx4, mkexpr(vA), mkexpr(vC)),
-                           mkexpr(vB))) );
+      putVReg( vD_addr, binop(Iop_Sub32Fx4,
+                              mkexpr(vB),
+                              binop(Iop_Mul32Fx4, mkexpr(vA), mkexpr(vC))) );
       return True;
    }
 
@@ -6983,6 +6979,17 @@ static Bool dis_av_fp_convert ( UInt theInstr )
    UChar vB_addr  = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */
    UInt  opc2     =         (theInstr >>  0) & 0x7FF; /* theInstr[0:10]  */
 
+   IRTemp vB = newTemp(Ity_V128);
+   IRTemp vScale = newTemp(Ity_V128);
+   IRTemp vInvScale = newTemp(Ity_V128);
+   assign( vB, getVReg(vB_addr));
+
+   /* scale = 2^UIMM, cast to float, reinterpreted as uint */
+   float scale = (float)( (unsigned int) 1<<UIMM_5 );
+   assign( vScale, unop(Iop_Dup32x4, mkU32( *((unsigned int*)(&scale)) )) );
+   float inv_scale = 1/scale;
+   assign( vInvScale, unop(Iop_Dup32x4, mkU32( *((unsigned int*)(&inv_scale)) )) );
+
    if (opc1 != 0x4) {
       vex_printf("dis_av_fp_convert(PPC32)(instr)\n");
       return False;
@@ -6991,23 +6998,32 @@ static Bool dis_av_fp_convert ( UInt theInstr )
    switch (opc2) {
    case 0x30A: // vcfux (Convert from Unsigned Fixed-Point W, AV p156)
       DIP("vcfux v%d,v%d,%d\n", vD_addr, vB_addr, UIMM_5);
-      DIP(" => not implemented\n");
-      return False;
+      putVReg( vD_addr, binop(Iop_Mul32Fx4,
+                              unop(Iop_I32UtoFx4, mkexpr(vB)),
+                              mkexpr(vInvScale)) );
+      return True;
 
    case 0x34A: // vcfsx (Convert from Signed Fixed-Point W, AV p155)
       DIP("vcfsx v%d,v%d,%d\n", vD_addr, vB_addr, UIMM_5);
-      DIP(" => not implemented\n");
-      return False;
+
+      putVReg( vD_addr, binop(Iop_Mul32Fx4,
+                              unop(Iop_I32StoFx4, mkexpr(vB)),
+                              mkexpr(vInvScale)) );
+      return True;
 
    case 0x38A: // vctuxs (Convert to Unsigned Fixed-Point W Saturate, AV p172)
       DIP("vctuxs v%d,v%d,%d\n", vD_addr, vB_addr, UIMM_5);
-      DIP(" => not implemented\n");
-      return False;
+      putVReg( vD_addr,
+               unop(Iop_QFtoI32Ux4_RZ, 
+                    binop(Iop_Mul32Fx4, mkexpr(vB), mkexpr(vScale))) );
+      return True;
 
    case 0x3CA: // vctsxs (Convert to Signed Fixed-Point W Saturate, AV p171)
       DIP("vctsxs v%d,v%d,%d\n", vD_addr, vB_addr, UIMM_5);
-      DIP(" => not implemented\n");
-      return False;
+      putVReg( vD_addr, 
+               unop(Iop_QFtoI32Sx4_RZ, 
+                     binop(Iop_Mul32Fx4, mkexpr(vB), mkexpr(vScale))) );
+      return True;
 
    default:
      break;    // Fall through...
@@ -7021,23 +7037,23 @@ static Bool dis_av_fp_convert ( UInt theInstr )
    switch (opc2) {
    case 0x20A: // vrfin (Round to FP Integer Nearest, AV p231)
       DIP("vrfin v%d,v%d\n", vD_addr, vB_addr);
-      DIP(" => not implemented\n");
-      return False;
+      putVReg( vD_addr, unop(Iop_RoundF32x4_RN, mkexpr(vB)) );
+      break;
 
    case 0x24A: // vrfiz (Round to FP Integer toward zero, AV p233)
       DIP("vrfiz v%d,v%d\n", vD_addr, vB_addr);
-      DIP(" => not implemented\n");
-      return False;
+      putVReg( vD_addr, unop(Iop_RoundF32x4_RZ, mkexpr(vB)) );
+      break;
 
    case 0x28A: // vrfip (Round to FP Integer toward +inf, AV p232)
       DIP("vrfip v%d,v%d\n", vD_addr, vB_addr);
-      DIP(" => not implemented\n");
-      return False;
+      putVReg( vD_addr, unop(Iop_RoundF32x4_RP, mkexpr(vB)) );
+      break;
 
    case 0x2CA: // vrfim (Round to FP Integer toward -inf, AV p230)
       DIP("vrfim v%d,v%d\n", vD_addr, vB_addr);
-      DIP(" => not implemented\n");
-      return False;
+      putVReg( vD_addr, unop(Iop_RoundF32x4_RM, mkexpr(vB)) );
+      break;
 
    default:
       vex_printf("dis_av_fp_convert(PPC32)(opc2)\n");
index d855fe36c4722678f64d20b1bd2d27327967ab99..9ffe1df111678dd902d48ab3728814680a94185e 100644 (file)
@@ -708,8 +708,16 @@ HChar* showPPC32AvFpOp ( PPC32AvFpOp op ) {
    /* Floating Point Unary */
    case Pavfp_RCPF:      return "vrefp";
    case Pavfp_RSQRTF:    return "vrsqrtefp";
+   case Pavfp_CVTU2F:    return "vcfux";
+   case Pavfp_CVTS2F:    return "vcfsx";
+   case Pavfp_QCVTF2U:   return "vctuxs";
+   case Pavfp_QCVTF2S:   return "vctsxs";
+   case Pavfp_ROUNDM:    return "vrfim";
+   case Pavfp_ROUNDP:    return "vrfip";
+   case Pavfp_ROUNDN:    return "vrfin";
+   case Pavfp_ROUNDZ:    return "vrfiz";
 
-   default: vpanic("showPPC32AvOp");
+   default: vpanic("showPPC32AvFpOp");
    }
 }
 
@@ -1412,7 +1420,7 @@ void ppPPC32Instr ( PPC32Instr* i )
       ppHRegPPC32(i->Pin.AvBin32x4.srcR);
       return;
    case Pin_AvBin32Fx4:
-      vex_printf("%s ", showPPC32AvOp(i->Pin.AvBin32Fx4.op));
+      vex_printf("%s ", showPPC32AvFpOp(i->Pin.AvBin32Fx4.op));
       ppHRegPPC32(i->Pin.AvBin32Fx4.dst);
       vex_printf(",");
       ppHRegPPC32(i->Pin.AvBin32Fx4.srcL);
@@ -1420,7 +1428,7 @@ void ppPPC32Instr ( PPC32Instr* i )
       ppHRegPPC32(i->Pin.AvBin32Fx4.srcR);
       return;
    case Pin_AvUn32Fx4:
-      vex_printf("%s ", showPPC32AvOp(i->Pin.AvUn32Fx4.op));
+      vex_printf("%s ", showPPC32AvFpOp(i->Pin.AvUn32Fx4.op));
       ppHRegPPC32(i->Pin.AvUn32Fx4.dst);
       vex_printf(",");
       ppHRegPPC32(i->Pin.AvUn32Fx4.src);
@@ -3153,7 +3161,7 @@ Int emit_PPC32Instr ( UChar* buf, Int nbuf, PPC32Instr* i )
          UInt vB = 29;                    // XXX: Using r29 for temp
          UInt konst = 0x1F;
 
-         // Better way to load zero_imm?
+         // Better way to load -0.0 (0x80000000) ?
          // vspltisw vB,0x1F   (0x1F => each word of vB)
          p = mkFormVX( p, 4, vB, konst, 0, 908 );
 
@@ -3185,8 +3193,16 @@ Int emit_PPC32Instr ( UChar* buf, Int nbuf, PPC32Instr* i )
       UInt v_src = vregNo(i->Pin.AvUn32Fx4.src);
       UInt opc2;
       switch (i->Pin.AvUn32Fx4.op) {
-      case Pavfp_RCPF:   opc2 =  266; break; // vrefp
-      case Pavfp_RSQRTF: opc2 =  330; break; // vrsqrtefp
+      case Pavfp_RCPF:    opc2 =  266; break; // vrefp
+      case Pavfp_RSQRTF:  opc2 =  330; break; // vrsqrtefp
+      case Pavfp_CVTU2F:  opc2 =  778; break; // vcfux
+      case Pavfp_CVTS2F:  opc2 =  842; break; // vcfsx
+      case Pavfp_QCVTF2U: opc2 =  906; break; // vctuxs
+      case Pavfp_QCVTF2S: opc2 =  970; break; // vctsxs
+      case Pavfp_ROUNDM:  opc2 =  714; break; // vrfim
+      case Pavfp_ROUNDP:  opc2 =  650; break; // vrfip
+      case Pavfp_ROUNDN:  opc2 =  522; break; // vrfin
+      case Pavfp_ROUNDZ:  opc2 =  586; break; // vrfiz
       default:
          goto bad;
       }
index 248647f094d7696b67154422ed8d22504544b8ee..e210a8c0052b6494e5187b5f6e360950c1301605 100644 (file)
@@ -414,6 +414,8 @@ typedef
 
       /* Floating point unary */
       Pavfp_RCPF, Pavfp_RSQRTF,
+      Pavfp_CVTU2F, Pavfp_CVTS2F, Pavfp_QCVTF2U, Pavfp_QCVTF2S,
+      Pavfp_ROUNDM, Pavfp_ROUNDP, Pavfp_ROUNDN, Pavfp_ROUNDZ,
    }
    PPC32AvFpOp;
 
index 42f509b31451ca89dd0ef64d7c767b4918dccc1c..04fb988b11785980ffb8ae75c06a86451e9eef51 100644 (file)
@@ -3059,6 +3059,14 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
       case Iop_Recip32Fx4: op = Pavfp_RCPF;   goto do_32Fx4_unary;
       case Iop_RSqrt32Fx4: op = Pavfp_RSQRTF; goto do_32Fx4_unary;
 //..       case Iop_Sqrt32Fx4:  op = Xsse_SQRTF;  goto do_32Fx4_unary;
+      case Iop_I32UtoFx4:     op = Pavfp_CVTU2F;  goto do_32Fx4_unary;
+      case Iop_I32StoFx4:     op = Pavfp_CVTS2F;  goto do_32Fx4_unary;
+      case Iop_QFtoI32Ux4_RZ: op = Pavfp_QCVTF2U; goto do_32Fx4_unary;
+      case Iop_QFtoI32Sx4_RZ: op = Pavfp_QCVTF2S; goto do_32Fx4_unary;
+      case Iop_RoundF32x4_RM: op = Pavfp_ROUNDM;    goto do_32Fx4_unary;
+      case Iop_RoundF32x4_RP: op = Pavfp_ROUNDP;    goto do_32Fx4_unary;
+      case Iop_RoundF32x4_RN: op = Pavfp_ROUNDN;    goto do_32Fx4_unary;
+      case Iop_RoundF32x4_RZ: op = Pavfp_ROUNDZ;    goto do_32Fx4_unary;
       do_32Fx4_unary:
       {
          HReg arg = iselVecExpr(env, e->Iex.Unop.arg);