]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Added AltiVec integer compare insns.
authorCerion Armour-Brown <cerion@valgrind.org>
Thu, 15 Sep 2005 14:22:58 +0000 (14:22 +0000)
committerCerion Armour-Brown <cerion@valgrind.org>
Thu, 15 Sep 2005 14:22:58 +0000 (14:22 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@1396

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

index 7e53876db87ed9ec2841158f78a659a1bb749388..14656e12db4aef7d2fbbb1cfea1170e51b531cb2 100644 (file)
@@ -1154,6 +1154,50 @@ static IRExpr* /* :: Ity_I32 */ get_XER_CA ( void )
 
 
 
+/* Set the CR6 flags following an AltiVec compare operation. */
+static void set_AV_CR6 ( IRExpr* result )
+{
+   vassert(typeOfIRExpr(irbb->tyenv,result) == Ity_V128);
+
+   /* CR6[0:3] = {all_ones, 0, all_zeros, 0}
+      all_ones  = (v[0] && v[1] && v[2] && v[3])
+      all_zeros = ~(v[0] || v[1] || v[2] || v[3])
+   */
+   IRTemp v0 = newTemp(Ity_V128);
+   IRTemp v1 = newTemp(Ity_V128);
+   IRTemp v2 = newTemp(Ity_V128);
+   IRTemp v3 = newTemp(Ity_V128);
+   IRTemp rOnes  = newTemp(Ity_I8);
+   IRTemp rZeros = newTemp(Ity_I8);
+   assign( v0, result );
+   assign( v1, binop(Iop_ShrV128, result, mkU8(32)) );
+   assign( v2, binop(Iop_ShrV128, result, mkU8(64)) );
+   assign( v3, binop(Iop_ShrV128, result, mkU8(96)) );
+
+   assign( rOnes, unop(Iop_1Uto8,
+      binop(Iop_CmpEQ32, mkU32(0xFFFFFFFF),
+            unop(Iop_V128to32,
+                 binop(Iop_AndV128,
+                       binop(Iop_AndV128, mkexpr(v0), mkexpr(v1)),
+                       binop(Iop_AndV128, mkexpr(v2), mkexpr(v3)))))) );
+
+   assign( rZeros, unop(Iop_1Uto8,
+       binop(Iop_CmpEQ32, mkU32(0xFFFFFFFF),
+             unop(Iop_Not32,
+                  unop(Iop_V128to32,
+                       binop(Iop_OrV128,
+                             binop(Iop_OrV128, mkexpr(v0), mkexpr(v1)),
+                             binop(Iop_OrV128, mkexpr(v2), mkexpr(v3))))
+                  ))) );
+
+   putCR321( 6, binop(Iop_Or8,
+                      binop(Iop_Shl8, mkexpr(rOnes),  mkU8(3)),
+                      binop(Iop_Shl8, mkexpr(rZeros), mkU8(1))) );
+   putCR0( 6, mkU8(0) );
+} 
+
+
+
 /*------------------------------------------------------------*/
 /*--- Abstract register interface                         --- */
 /*------------------------------------------------------------*/
@@ -5429,6 +5473,12 @@ static Bool dis_av_cmp ( UInt theInstr )
    UChar flag_Rc  = toUChar((theInstr >> 10) & 0x1);  /* theInstr[10]    */
    UInt  opc2     =         (theInstr >>  0) & 0x3FF; /* theInstr[0:9]   */
 
+   IRTemp vA = newTemp(Ity_V128);
+   IRTemp vB = newTemp(Ity_V128);
+   IRTemp vD = newTemp(Ity_V128);
+   assign( vA, getVReg(vA_addr));
+   assign( vB, getVReg(vB_addr));
+
    if (opc1 != 0x4) {
       vex_printf("dis_av_cmp(PPC32)(instr)\n");
       return False;
@@ -5437,53 +5487,59 @@ static Bool dis_av_cmp ( UInt theInstr )
    switch (opc2) {
    case 0x006: // vcmpequb (Compare Equal-to Unsigned B, AV p160)
       DIP("vcmpequb%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr);
-      DIP(" => not implemented\n");
-      return False;
+      assign( vD, binop(Iop_CmpEQ8x16, mkexpr(vA), mkexpr(vB)) );
+      break;
 
    case 0x046: // vcmpequh (Compare Equal-to Unsigned HW, AV p161)
       DIP("vcmpequh%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr);
-      DIP(" => not implemented\n");
-      return False;
+      assign( vD, binop(Iop_CmpEQ16x8, mkexpr(vA), mkexpr(vB)) );
+      break;
 
    case 0x086: // vcmpequw (Compare Equal-to Unsigned W, AV p162)
       DIP("vcmpequw%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr);
-      DIP(" => not implemented\n");
-      return False;
+      assign( vD, binop(Iop_CmpEQ32x4, mkexpr(vA), mkexpr(vB)) );
+      break;
 
    case 0x206: // vcmpgtub (Compare Greater-than Unsigned B, AV p168)
       DIP("vcmpgtub%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr);
-      DIP(" => not implemented\n");
-      return False;
+      assign( vD, binop(Iop_CmpGT8Ux16, mkexpr(vA), mkexpr(vB)) );
+      break;
 
    case 0x246: // vcmpgtuh (Compare Greater-than Unsigned HW, AV p169)
       DIP("vcmpgtuh%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr);
-      DIP(" => not implemented\n");
-      return False;
+      assign( vD, binop(Iop_CmpGT16Ux8, mkexpr(vA), mkexpr(vB)) );
+      break;
 
    case 0x286: // vcmpgtuw (Compare Greater-than Unsigned W, AV p170)
       DIP("vcmpgtuw%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr);
-      DIP(" => not implemented\n");
-      return False;
+      assign( vD, binop(Iop_CmpGT32Ux4, mkexpr(vA), mkexpr(vB)) );
+      break;
 
    case 0x306: // vcmpgtsb (Compare Greater-than Signed B, AV p165)
       DIP("vcmpgtsb%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr);
-      DIP(" => not implemented\n");
-      return False;
+      assign( vD, binop(Iop_CmpGT8Sx16, mkexpr(vA), mkexpr(vB)) );
+      break;
 
    case 0x346: // vcmpgtsh (Compare Greater-than Signed HW, AV p166)
       DIP("vcmpgtsh%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr);
-      DIP(" => not implemented\n");
-      return False;
+      assign( vD, binop(Iop_CmpGT16Sx8, mkexpr(vA), mkexpr(vB)) );
+      break;
 
    case 0x386: // vcmpgtsw (Compare Greater-than Signed W, AV p167)
       DIP("vcmpgtsw%s v%d,v%d,v%d\n", (flag_Rc ? ".":""), vD_addr, vA_addr, vB_addr);
-      DIP(" => not implemented\n");
-      return False;
+      assign( vD, binop(Iop_CmpGT32Sx4, mkexpr(vA), mkexpr(vB)) );
+      break;
 
    default:
       vex_printf("dis_av_cmp(PPC32)(opc2)\n");
       return False;
    }
+
+   putVReg( vD_addr, mkexpr(vD) );
+
+   if (flag_Rc) {
+      set_AV_CR6( mkexpr(vD) );
+   }
    return True;
 }
 
index 894efdccc9b41ebe7affa38c058525e478c1d51d..5d4767c8ff334ddbd16a71b167dae3c70f48cce3 100644 (file)
@@ -3344,6 +3344,9 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
       case Iop_Max8Sx16:   op = Pav_MAXS;   goto do_AvBin8x16;
       case Iop_Min8Ux16:   op = Pav_MINU;   goto do_AvBin8x16;
       case Iop_Min8Sx16:   op = Pav_MINS;   goto do_AvBin8x16;
+      case Iop_CmpEQ8x16:  op = Pav_CMPEQU; goto do_AvBin8x16;
+      case Iop_CmpGT8Ux16: op = Pav_CMPGTU; goto do_AvBin8x16;
+      case Iop_CmpGT8Sx16: op = Pav_CMPGTS; goto do_AvBin8x16;
       do_AvBin8x16: {
          HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1);
          HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2);
@@ -3368,6 +3371,9 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
       case Iop_MulLo16Sx8: op = Pav_OMULS;  goto do_AvBin16x8;
       case Iop_MulHi16Ux8: op = Pav_EMULU;  goto do_AvBin16x8;
       case Iop_MulHi16Sx8: op = Pav_EMULS;  goto do_AvBin16x8;
+      case Iop_CmpEQ16x8:  op = Pav_CMPEQU; goto do_AvBin16x8;
+      case Iop_CmpGT16Ux8: op = Pav_CMPGTU; goto do_AvBin16x8;
+      case Iop_CmpGT16Sx8: op = Pav_CMPGTS; goto do_AvBin16x8;
       do_AvBin16x8: {
          HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1);
          HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2);
@@ -3388,11 +3394,13 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
       case Iop_Max32Sx4:   op = Pav_MAXS;   goto do_AvBin32x4;
       case Iop_Min32Ux4:   op = Pav_MINU;   goto do_AvBin32x4;
       case Iop_Min32Sx4:   op = Pav_MINS;   goto do_AvBin32x4;
-      case Iop_CmpGT32Ux4: op = Pav_CMPGTU; goto do_AvBin32x4;
       case Iop_MulLo32Ux4: op = Pav_OMULU;  goto do_AvBin32x4;
       case Iop_MulLo32Sx4: op = Pav_OMULS;  goto do_AvBin32x4;
       case Iop_MulHi32Ux4: op = Pav_EMULU;  goto do_AvBin32x4;
       case Iop_MulHi32Sx4: op = Pav_EMULS;  goto do_AvBin32x4;
+      case Iop_CmpEQ32x4:  op = Pav_CMPEQU; goto do_AvBin32x4;
+      case Iop_CmpGT32Ux4: op = Pav_CMPGTU; goto do_AvBin32x4;
+      case Iop_CmpGT32Sx4: op = Pav_CMPGTS; goto do_AvBin32x4;
       do_AvBin32x4: {
          HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1);
          HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2);