]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fill in a few missing Altivec cases:
authorJulian Seward <jseward@acm.org>
Sat, 22 Oct 2005 12:49:49 +0000 (12:49 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 22 Oct 2005 12:49:49 +0000 (12:49 +0000)
- rename Iop_Perm to Iop_Perm8x16
- backend: handle Iop_CmpNEZ8x16
- frontend: for vperm, mask off all irrelevant parts of the steering values

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

VEX/priv/guest-ppc32/toIR.c
VEX/priv/host-ppc32/hdefs.c
VEX/priv/host-ppc32/isel.c
VEX/priv/ir/irdefs.c
VEX/pub/libvex_ir.h

index 0732193bb939811eaf72e7dfe9da79c2ebaa2880..66cb95281353c16e20c6489b5f6b2e51b417dcb0 100644 (file)
@@ -5977,12 +5977,18 @@ static Bool dis_av_permute ( UInt theInstr )
      
    case 0x2B: { // vperm (Permute, AV p218)
       /* limited to two args for IR, so have to play games... */
-      IRTemp a_perm = newTemp(Ity_V128);
-      IRTemp b_perm = newTemp(Ity_V128);
-      IRTemp mask = newTemp(Ity_V128);
-      DIP("vperma v%d,v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr, vC_addr);
-      assign( a_perm, binop(Iop_Perm, mkexpr(vA), mkexpr(vC)) );
-      assign( b_perm, binop(Iop_Perm, mkexpr(vB), mkexpr(vC)) );
+      IRTemp a_perm  = newTemp(Ity_V128);
+      IRTemp b_perm  = newTemp(Ity_V128);
+      IRTemp mask    = newTemp(Ity_V128);
+      IRTemp vC_andF = newTemp(Ity_V128);
+      DIP("vperm v%d,v%d,v%d,v%d\n", vD_addr, vA_addr, vB_addr, vC_addr);
+      /* Limit the Perm8x16 steering values to 0 .. 15 as that is what
+         IR specifies, and also to hide irrelevant bits from
+         memcheck */
+      assign( vC_andF, binop(Iop_AndV128, mkexpr(vC), 
+                                          unop(Iop_Dup8x16, mkU8(0xF))) );
+      assign( a_perm, binop(Iop_Perm8x16, mkexpr(vA), mkexpr(vC_andF)) );
+      assign( b_perm, binop(Iop_Perm8x16, mkexpr(vB), mkexpr(vC_andF)) );
       // mask[i8] = (vC[i8]_4 == 1) ? 0xFF : 0x0
       assign( mask, binop(Iop_SarN8x16,
                           binop(Iop_ShlN8x16, mkexpr(vC), mkU8(3)),
index 4d6815eac0f4f32de58c0aaab3c070fd267accd1..54c7bf248bc62c6f9d37653f153d340786e593ca 100644 (file)
@@ -1608,9 +1608,17 @@ void getRegUsage_PPC32Instr ( HRegUsage* u, PPC32Instr* i )
       addHRegUse(u, HRmRead,  i->Pin.AvUnary.src);
       return;
    case Pin_AvBinary:
-      addHRegUse(u, HRmWrite, i->Pin.AvBinary.dst);
-      addHRegUse(u, HRmRead,  i->Pin.AvBinary.srcL);
-      addHRegUse(u, HRmRead,  i->Pin.AvBinary.srcR);
+      if (i->Pin.AvBinary.op == Pav_XOR
+          && i->Pin.AvBinary.dst == i->Pin.AvBinary.srcL
+          && i->Pin.AvBinary.dst == i->Pin.AvBinary.srcR) {
+         /* reg-alloc needs to understand 'xor r,r,r' as a write of r */
+         /* (as opposed to a rite of passage :-) */
+         addHRegUse(u, HRmWrite, i->Pin.AvBinary.dst);
+      } else {
+         addHRegUse(u, HRmWrite, i->Pin.AvBinary.dst);
+         addHRegUse(u, HRmRead,  i->Pin.AvBinary.srcL);
+         addHRegUse(u, HRmRead,  i->Pin.AvBinary.srcR);
+      }
       return;
    case Pin_AvBin8x16:
       addHRegUse(u, HRmWrite, i->Pin.AvBin8x16.dst);
index 974d64518fa4c98579f4c662c93e95fc3ea67fc8..137e3a7aee70b607d96abf5194fcd9099b01d381 100644 (file)
@@ -2999,7 +2999,15 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
 //..          return dst;
 //..       }
 //.. 
-//..       case Iop_CmpNEZ8x16:
+      case Iop_CmpNEZ8x16: {
+         HReg arg  = iselVecExpr(env, e->Iex.Unop.arg);
+         HReg zero = newVRegV(env);
+         HReg dst  = newVRegV(env);
+         addInstr(env, PPC32Instr_AvBinary(Pav_XOR, zero, zero, zero));
+         addInstr(env, PPC32Instr_AvBin8x16(Pav_CMPEQU, dst, arg, zero));
+         addInstr(env, PPC32Instr_AvUnary(Pav_NOT, dst, dst));
+         return dst;
+      }
 //..       case Iop_CmpNEZ16x8: {
 //..          /* We can use SSE2 instructions for this. */
 //..          HReg arg;
@@ -3433,7 +3441,7 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e )
          return dst;
       }
 
-      case Iop_Perm: {
+      case Iop_Perm8x16: {
          HReg dst   = newVRegV(env);
          HReg v_src = iselVecExpr(env, e->Iex.Binop.arg1);
          HReg v_ctl = iselVecExpr(env, e->Iex.Binop.arg2);
index 885dd519ce08a26f67a8c268c741fd27d3a559dc..1dcdd1cbcb9828f702eb4bf057958aeb85f4912d 100644 (file)
@@ -519,7 +519,7 @@ void ppIROp ( IROp op )
       case Iop_InterleaveLO32x4: vex_printf("InterleaveLO32x4"); return;
       case Iop_InterleaveLO64x2: vex_printf("InterleaveLO64x2"); return;
 
-      case Iop_Perm: vex_printf("Perm"); return;
+      case Iop_Perm8x16: vex_printf("Perm8x16"); return;
 
       default: vpanic("ppIROp(1)");
    }
@@ -1574,7 +1574,7 @@ void typeOfPrimop ( IROp op, IRType* t_dst, IRType* t_arg1, IRType* t_arg2 )
       case Iop_InterleaveHI32x4: case Iop_InterleaveHI64x2:
       case Iop_InterleaveLO8x16: case Iop_InterleaveLO16x8: 
       case Iop_InterleaveLO32x4: case Iop_InterleaveLO64x2:
-      case Iop_Perm:
+      case Iop_Perm8x16:
          BINARY(Ity_V128, Ity_V128,Ity_V128);
 
       case Iop_NotV128:
index 03de4321b2bfce26a3b7856ae65dcf91e851cfb1..b0d2de4398559d8ce9e4cb552b5ec0f7e18e2460 100644 (file)
@@ -597,8 +597,11 @@ typedef
       Iop_Dup8x16, Iop_Dup16x8, Iop_Dup32x4,
 
       /* PERMUTING -- copy src bytes to dst,
-         as indexed by control vector bytes: dst[i] = src[ ctl[i] ] */
-      Iop_Perm
+         as indexed by control vector bytes:
+            for i in 0 .. 15 . result[i] = argL[ argR[i] ] 
+         argR[i] values may only be in the range 0 .. 15, else behaviour
+         is undefined. */
+      Iop_Perm8x16
    }
    IROp;