]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
implemented vaddcuw
authorCerion Armour-Brown <cerion@valgrind.org>
Wed, 14 Sep 2005 21:15:40 +0000 (21:15 +0000)
committerCerion Armour-Brown <cerion@valgrind.org>
Wed, 14 Sep 2005 21:15:40 +0000 (21:15 +0000)
backend:
 Iop_ShrN32x4, Iop_Add32x4, Iop_CmpGT32Ux4
 fixed emit_Instr::Pin_AvSplat for negative nums
 fixed mk_AvDuplicateRI for imm's 16:31, -32:-17 inclusive

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

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

index b8a7460761ba2bfa6ba6b02cf4d6b30e1387e085..e31f90efc24650a91e25aa693a6ce5b16ac7902a 100644 (file)
@@ -5027,6 +5027,11 @@ static Bool dis_av_arith ( UInt theInstr )
    UChar vB_addr  = toUChar((theInstr >> 11) & 0x1F); /* theInstr[11:15] */
    UInt  opc2     =         (theInstr >>  0) & 0x7FF; /* theInstr[0:10]  */
 
+   IRTemp vA = newTemp(Ity_V128);
+   IRTemp vB = newTemp(Ity_V128);
+   assign( vA, getVReg(vA_addr));
+   assign( vB, getVReg(vB_addr));
+
    if (opc1 != 0x4) {
       vex_printf("dis_av_arith(PPC32)(opc1 != 0x4)\n");
       return False;
@@ -5034,11 +5039,16 @@ static Bool dis_av_arith ( UInt theInstr )
 
    switch (opc2) {
    /* Add */
-   case 0x180: // vaddcuw (Add Carryout Unsigned Word, AV p136)
+   case 0x180: // vaddcuw (Add Carryout Unsigned Word, AV p136)
       DIP("vaddcuw v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr);
-      DIP(" => not implemented\n");
-      return False;
-     
+      /* ov = x >u (x+y) */
+      IRTemp sum = newTemp(Ity_V128);
+      assign( sum, binop(Iop_Add32x4, mkexpr(vA), mkexpr(vB)) );
+      putVReg( vD_addr, binop(Iop_ShrN32x4,
+                              binop(Iop_CmpGT32Ux4, mkexpr(vA), mkexpr(sum)),
+                              mkU8(31)) );
+      break;
+   }
    case 0x000: // vaddubm (Add Unsigned Byte Modulo, AV p141)
       DIP("vaddubm v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr);
       DIP(" => not implemented\n");
index 59d1cf6d7d566d09ae980634e42f68fa1528fb1e..7b0a6851696438bdcc7398d64d66982b46817bab 100644 (file)
@@ -3126,6 +3126,7 @@ Int emit_PPC32Instr ( UChar* buf, Int nbuf, PPC32Instr* i )
          /* expects 5-bit-signed-imm */
          Char simm5 = i->Pin.AvSplat.src->Pvi.Imm5s;
          vassert(simm5 >= -16 && simm5 <= 15);
+         simm5 = simm5 & 0x1F;
          p = mkFormVX( p, 4, v_dst, (UInt)simm5, 0, opc2 );
       }
       else {  // Pri_Reg
index d65d17a94c49846158268d46359abc9a6c65e176..fc4c11b80b323c8662c85c995151a291988f6c38 100644 (file)
@@ -780,7 +780,10 @@ static HReg mk_AvDuplicateRI( ISelEnv* env, IRExpr* e )
             HReg v2 = newVRegV(env);
             addInstr(env, PPC32Instr_AvSplat(sz, v1, PPC32VI5s_Imm(-16)));
             addInstr(env, PPC32Instr_AvSplat(sz, v2, PPC32VI5s_Imm(simm6-16)));
-            addInstr(env, PPC32Instr_AvBinary(Pav_SUBUM, dst, v2, v1));
+            addInstr(env,
+               (sz== 8) ? PPC32Instr_AvBin8x16(Pav_SUBUM, dst, v2, v1) :
+               (sz==16) ? PPC32Instr_AvBin16x8(Pav_SUBUM, dst, v2, v1)
+                        : PPC32Instr_AvBin32x4(Pav_SUBUM, dst, v2, v1) );
             return dst;
          }
          if (simm6 < -16) {          /* -32:-17 inclusive */
@@ -788,7 +791,10 @@ static HReg mk_AvDuplicateRI( ISelEnv* env, IRExpr* e )
             HReg v2 = newVRegV(env);
             addInstr(env, PPC32Instr_AvSplat(sz, v1, PPC32VI5s_Imm(-16)));
             addInstr(env, PPC32Instr_AvSplat(sz, v2, PPC32VI5s_Imm(simm6+16)));
-            addInstr(env, PPC32Instr_AvBinary(Pav_ADDUM, dst, v2, v1));
+            addInstr(env,
+               (sz== 8) ? PPC32Instr_AvBin8x16(Pav_ADDUM, dst, v2, v1) :
+               (sz==16) ? PPC32Instr_AvBin16x8(Pav_ADDUM, dst, v2, v1)
+                        : PPC32Instr_AvBin32x4(Pav_ADDUM, dst, v2, v1) );
             return dst;
          }
          /* simplest form:              -16:15 inclusive */
@@ -3335,6 +3341,17 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
          addInstr(env, PPC32Instr_AvBinary(op, dst, arg1, arg2));
          return dst;
       }
+
+      case Iop_Add32x4:    op = Pav_ADDUM;   goto do_AvBin32x4;
+      case Iop_CmpGT32Ux4: op = Pav_CMPGTU; goto do_AvBin32x4;
+      do_AvBin32x4: {
+         HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1);
+         HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2);
+         HReg dst  = newVRegV(env);
+         addInstr(env, PPC32Instr_AvBin32x4(op, dst, arg1, arg2));
+         return dst;
+      }
+
 //..       do_SseReRg: {
 //..          HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1);
 //..          HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2);
@@ -3357,9 +3374,17 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
 //..       case Iop_SarN16x8: op = Xsse_SAR16; goto do_SseShift;
 //..       case Iop_SarN32x4: op = Xsse_SAR32; goto do_SseShift;
 //..       case Iop_ShrN16x8: op = Xsse_SHR16; goto do_SseShift;
-//..       case Iop_ShrN32x4: op = Xsse_SHR32; goto do_SseShift;
 //..       case Iop_ShrN64x2: op = Xsse_SHR64; goto do_SseShift;
 
+      case Iop_ShrN32x4: op = Pav_SHR; goto do_AvShift32x4;
+      do_AvShift32x4: {
+         HReg     r_src   = iselVecExpr(env, e->Iex.Binop.arg1);
+         HReg dst    = newVRegV(env);
+         HReg v_shft = mk_AvDuplicateRI(env, e->Iex.Binop.arg2);
+         addInstr(env, PPC32Instr_AvBin32x4(op, dst, r_src, v_shft));
+         return dst;
+      }
+
       case Iop_ShrV128: op = Pav_SHR; goto do_AvShiftV128;
       do_AvShiftV128: {
          HReg dst    = newVRegV(env);