Mark Wielaard f9c9f2
Fix without v-bit test program changes which changed too much since 3.11.0.
Mark Wielaard f9c9f2
Mark Wielaard f9c9f2
commit 568f3ab3f7a4c074fe9ce6f4f395fb25b6fa375b
Mark Wielaard f9c9f2
Author: carll <carll@8f6e269a-dfd6-0310-a8e1-e2731360e62c>
Mark Wielaard f9c9f2
Date:   Tue Apr 26 19:52:56 2016 +0000
Mark Wielaard f9c9f2
Mark Wielaard f9c9f2
    Power PC  Fix V bit error in 128-bit BCD add and subtract instructions
Mark Wielaard f9c9f2
    
Mark Wielaard f9c9f2
    The original code was using the bcdadd / bcdsub instruction on the operand
Mark Wielaard f9c9f2
    shadow bits to calculate the shadow bits for the result.  This introduced
Mark Wielaard f9c9f2
    non-zero bits shadow bits in the result.   The shadow bits for these
Mark Wielaard f9c9f2
    instructions should be set to all valid or all invalid.  If one of the
Mark Wielaard f9c9f2
    argument shadow bits was one, then all of the shadow bits of the result should
Mark Wielaard f9c9f2
    be one.  Otherwise the result shadow bits should be zero.
Mark Wielaard f9c9f2
    
Mark Wielaard f9c9f2
    This patch fixes the above bug in memcheck/mc_translate.c
Mark Wielaard f9c9f2
    
Mark Wielaard f9c9f2
    Fixing the above bug broke the v-bit test.  The issue is the v-bit tester
Mark Wielaard f9c9f2
    assumes the shadow bits for the operands of a given Iop can be set to one
Mark Wielaard f9c9f2
    for testing purposes.  The implementation of the bcdadd and bcdsub was passing
Mark Wielaard f9c9f2
    a constant value for the variable ps.  The ps value is an argument to the
Mark Wielaard f9c9f2
    instruction that specifies how to set the sign code of the result.  The
Mark Wielaard f9c9f2
    implementation of the instructions was changed to issue the instruction with
Mark Wielaard f9c9f2
    ps=0.  Then the result of the instruction is updated in the VEX code if ps=1.
Mark Wielaard f9c9f2
    This changed also results in cleaning up the vbit test code.
Mark Wielaard f9c9f2
    
Mark Wielaard f9c9f2
    This patch also fixes the issues with the v-bit test program.
Mark Wielaard f9c9f2
    
Mark Wielaard f9c9f2
    Bugzilla 360035
Mark Wielaard f9c9f2
    
Mark Wielaard f9c9f2
    
Mark Wielaard f9c9f2
    git-svn-id: svn://svn.valgrind.org/vex/trunk@3218 8f6e269a-dfd6-0310-a8e1-e2731360e62c
Mark Wielaard f9c9f2
Mark Wielaard f9c9f2
diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c
Mark Wielaard f9c9f2
index 034a766..44304df 100644
Mark Wielaard f9c9f2
--- a/VEX/priv/guest_ppc_toIR.c
Mark Wielaard f9c9f2
+++ b/VEX/priv/guest_ppc_toIR.c
Mark Wielaard f9c9f2
@@ -21297,6 +21297,43 @@ static Bool dis_av_quad ( UInt theInstr )
Mark Wielaard f9c9f2
    return True;
Mark Wielaard f9c9f2
 }
Mark Wielaard f9c9f2
 
Mark Wielaard f9c9f2
+static IRExpr * bcd_sign_code_adjust( UInt ps, IRExpr * tmp)
Mark Wielaard f9c9f2
+{
Mark Wielaard f9c9f2
+   /* The Iop_BCDAdd and Iop_BCDSub will result in the corresponding Power PC
Mark Wielaard f9c9f2
+    * instruction being issued with ps = 0.  If ps = 1, the sign code, which
Mark Wielaard f9c9f2
+    * is in the least significant four bits of the result, needs to be updated
Mark Wielaard f9c9f2
+    * per the ISA:
Mark Wielaard f9c9f2
+    *
Mark Wielaard f9c9f2
+    *    If PS=0, the sign code of the result is set to 0b1100.
Mark Wielaard f9c9f2
+    *    If PS=1, the sign code of the result is set to 0b1111.
Mark Wielaard f9c9f2
+    *
Mark Wielaard f9c9f2
+    * Note, the ps value is NOT being passed down to the instruction issue
Mark Wielaard f9c9f2
+    * because passing a constant via triop() breaks the vbit-test test.  The
Mark Wielaard f9c9f2
+    * vbit-tester assumes it can set non-zero shadow bits for the triop()
Mark Wielaard f9c9f2
+    * arguments.  Thus they have to be expressions not a constant.
Mark Wielaard f9c9f2
+    */
Mark Wielaard f9c9f2
+   IRTemp mask  = newTemp(Ity_I64);
Mark Wielaard f9c9f2
+   IRExpr *rtn;
Mark Wielaard f9c9f2
+
Mark Wielaard f9c9f2
+   if ( ps == 0 ) {
Mark Wielaard f9c9f2
+      /* sign code is correct, just return it.  */
Mark Wielaard f9c9f2
+      rtn = tmp;
Mark Wielaard f9c9f2
+
Mark Wielaard f9c9f2
+   } else {
Mark Wielaard f9c9f2
+      /* check if lower four bits are 0b1100, if so, change to 0b1111 */
Mark Wielaard f9c9f2
+      assign( mask, unop( Iop_1Sto64,
Mark Wielaard f9c9f2
+                          binop( Iop_CmpEQ64, mkU64( 0xC ),
Mark Wielaard f9c9f2
+                                 binop( Iop_And64, mkU64( 0xF ),
Mark Wielaard f9c9f2
+                                        unop( Iop_V128to64, tmp ) ) ) ) );
Mark Wielaard f9c9f2
+      rtn = binop( Iop_64HLtoV128,
Mark Wielaard f9c9f2
+                   unop( Iop_V128HIto64, tmp ),
Mark Wielaard f9c9f2
+                   binop( Iop_Or64,
Mark Wielaard f9c9f2
+                          binop( Iop_And64, mkU64( 0xF ), mkexpr( mask ) ),
Mark Wielaard f9c9f2
+                          unop( Iop_V128to64, tmp ) ) );
Mark Wielaard f9c9f2
+   }
Mark Wielaard f9c9f2
+
Mark Wielaard f9c9f2
+   return rtn;
Mark Wielaard f9c9f2
+}
Mark Wielaard f9c9f2
 
Mark Wielaard f9c9f2
 /*
Mark Wielaard f9c9f2
   AltiVec BCD Arithmetic instructions.
Mark Wielaard f9c9f2
@@ -21329,15 +21366,19 @@ static Bool dis_av_bcd ( UInt theInstr )
Mark Wielaard f9c9f2
    switch (opc2) {
Mark Wielaard f9c9f2
    case 0x1:  // bcdadd
Mark Wielaard f9c9f2
      DIP("bcdadd. v%d,v%d,v%d,%u\n", vRT_addr, vRA_addr, vRB_addr, ps);
Mark Wielaard f9c9f2
-     assign( dst, triop( Iop_BCDAdd, mkexpr( vA ),
Mark Wielaard f9c9f2
-                         mkexpr( vB ), mkU8( ps ) ) );
Mark Wielaard f9c9f2
+     assign( dst, bcd_sign_code_adjust( ps,
Mark Wielaard f9c9f2
+                                        binop( Iop_BCDAdd,
Mark Wielaard f9c9f2
+                                               mkexpr( vA ),
Mark Wielaard f9c9f2
+                                               mkexpr( vB ) ) ) );
Mark Wielaard f9c9f2
      putVReg( vRT_addr, mkexpr(dst));
Mark Wielaard f9c9f2
      return True;
Mark Wielaard f9c9f2
 
Mark Wielaard f9c9f2
    case 0x41:  // bcdsub
Mark Wielaard f9c9f2
      DIP("bcdsub. v%d,v%d,v%d,%u\n", vRT_addr, vRA_addr, vRB_addr, ps);
Mark Wielaard f9c9f2
-     assign( dst, triop( Iop_BCDSub, mkexpr( vA ),
Mark Wielaard f9c9f2
-                         mkexpr( vB ), mkU8( ps ) ) );
Mark Wielaard f9c9f2
+     assign( dst, bcd_sign_code_adjust( ps,
Mark Wielaard f9c9f2
+                                        binop( Iop_BCDSub,
Mark Wielaard f9c9f2
+                                               mkexpr( vA ),
Mark Wielaard f9c9f2
+                                               mkexpr( vB ) ) ) );
Mark Wielaard f9c9f2
      putVReg( vRT_addr, mkexpr(dst));
Mark Wielaard f9c9f2
      return True;
Mark Wielaard f9c9f2
 
Mark Wielaard f9c9f2
diff --git a/VEX/priv/host_ppc_defs.c b/VEX/priv/host_ppc_defs.c
Mark Wielaard f9c9f2
index 13b193c..06487b5 100644
Mark Wielaard f9c9f2
--- a/VEX/priv/host_ppc_defs.c
Mark Wielaard f9c9f2
+++ b/VEX/priv/host_ppc_defs.c
Mark Wielaard f9c9f2
@@ -1415,15 +1415,14 @@ PPCInstr* PPCInstr_AvHashV128Binary ( PPCAvOp op, HReg dst,
Mark Wielaard f9c9f2
    i->Pin.AvHashV128Binary.s_field = s_field;
Mark Wielaard f9c9f2
    return i;
Mark Wielaard f9c9f2
 }
Mark Wielaard f9c9f2
-PPCInstr* PPCInstr_AvBCDV128Trinary ( PPCAvOp op, HReg dst,
Mark Wielaard f9c9f2
-                                      HReg src1, HReg src2, PPCRI* ps ) {
Mark Wielaard f9c9f2
+PPCInstr* PPCInstr_AvBCDV128Binary ( PPCAvOp op, HReg dst,
Mark Wielaard f9c9f2
+                                     HReg src1, HReg src2 ) {
Mark Wielaard f9c9f2
    PPCInstr* i = LibVEX_Alloc_inline(sizeof(PPCInstr));
Mark Wielaard f9c9f2
-   i->tag      = Pin_AvBCDV128Trinary;
Mark Wielaard f9c9f2
-   i->Pin.AvBCDV128Trinary.op   = op;
Mark Wielaard f9c9f2
-   i->Pin.AvBCDV128Trinary.dst  = dst;
Mark Wielaard f9c9f2
-   i->Pin.AvBCDV128Trinary.src1 = src1;
Mark Wielaard f9c9f2
-   i->Pin.AvBCDV128Trinary.src2 = src2;
Mark Wielaard f9c9f2
-   i->Pin.AvBCDV128Trinary.ps   = ps;
Mark Wielaard f9c9f2
+   i->tag      = Pin_AvBCDV128Binary;
Mark Wielaard f9c9f2
+   i->Pin.AvBCDV128Binary.op   = op;
Mark Wielaard f9c9f2
+   i->Pin.AvBCDV128Binary.dst  = dst;
Mark Wielaard f9c9f2
+   i->Pin.AvBCDV128Binary.src1 = src1;
Mark Wielaard f9c9f2
+   i->Pin.AvBCDV128Binary.src2 = src2;
Mark Wielaard f9c9f2
    return i;
Mark Wielaard f9c9f2
 }
Mark Wielaard f9c9f2
 
Mark Wielaard f9c9f2
@@ -2038,15 +2037,13 @@ void ppPPCInstr ( const PPCInstr* i, Bool mode64 )
Mark Wielaard f9c9f2
       ppPPCRI(i->Pin.AvHashV128Binary.s_field);
Mark Wielaard f9c9f2
       return;
Mark Wielaard f9c9f2
 
Mark Wielaard f9c9f2
-   case Pin_AvBCDV128Trinary:
Mark Wielaard f9c9f2
-      vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvBCDV128Trinary.op));
Mark Wielaard f9c9f2
-      ppHRegPPC(i->Pin.AvBCDV128Trinary.dst);
Mark Wielaard f9c9f2
+   case Pin_AvBCDV128Binary:
Mark Wielaard f9c9f2
+      vex_printf("%s(w) ", showPPCAvOp(i->Pin.AvBCDV128Binary.op));
Mark Wielaard f9c9f2
+      ppHRegPPC(i->Pin.AvBCDV128Binary.dst);
Mark Wielaard f9c9f2
       vex_printf(",");
Mark Wielaard f9c9f2
-      ppHRegPPC(i->Pin.AvBCDV128Trinary.src1);
Mark Wielaard f9c9f2
+      ppHRegPPC(i->Pin.AvBCDV128Binary.src1);
Mark Wielaard f9c9f2
       vex_printf(",");
Mark Wielaard f9c9f2
-      ppHRegPPC(i->Pin.AvBCDV128Trinary.src2);
Mark Wielaard f9c9f2
-      vex_printf(",");
Mark Wielaard f9c9f2
-      ppPPCRI(i->Pin.AvBCDV128Trinary.ps);
Mark Wielaard f9c9f2
+      ppHRegPPC(i->Pin.AvBCDV128Binary.src2);
Mark Wielaard f9c9f2
       return;
Mark Wielaard f9c9f2
 
Mark Wielaard f9c9f2
    case Pin_Dfp64Unary:
Mark Wielaard f9c9f2
@@ -2511,11 +2508,10 @@ void getRegUsage_PPCInstr ( HRegUsage* u, const PPCInstr* i, Bool mode64 )
Mark Wielaard f9c9f2
       addHRegUse(u, HRmRead,  i->Pin.AvHashV128Binary.src);
Mark Wielaard f9c9f2
       addRegUsage_PPCRI(u,    i->Pin.AvHashV128Binary.s_field);
Mark Wielaard f9c9f2
       return;
Mark Wielaard f9c9f2
-   case Pin_AvBCDV128Trinary:
Mark Wielaard f9c9f2
-      addHRegUse(u, HRmWrite, i->Pin.AvBCDV128Trinary.dst);
Mark Wielaard f9c9f2
-      addHRegUse(u, HRmRead,  i->Pin.AvBCDV128Trinary.src1);
Mark Wielaard f9c9f2
-      addHRegUse(u, HRmRead,  i->Pin.AvBCDV128Trinary.src2);
Mark Wielaard f9c9f2
-      addRegUsage_PPCRI(u,    i->Pin.AvBCDV128Trinary.ps);
Mark Wielaard f9c9f2
+   case Pin_AvBCDV128Binary:
Mark Wielaard f9c9f2
+      addHRegUse(u, HRmWrite, i->Pin.AvBCDV128Binary.dst);
Mark Wielaard f9c9f2
+      addHRegUse(u, HRmRead,  i->Pin.AvBCDV128Binary.src1);
Mark Wielaard f9c9f2
+      addHRegUse(u, HRmRead,  i->Pin.AvBCDV128Binary.src2);
Mark Wielaard f9c9f2
       return;
Mark Wielaard f9c9f2
    case Pin_Dfp64Unary:
Mark Wielaard f9c9f2
       addHRegUse(u, HRmWrite, i->Pin.Dfp64Unary.dst);
Mark Wielaard f9c9f2
@@ -2844,11 +2840,10 @@ void mapRegs_PPCInstr ( HRegRemap* m, PPCInstr* i, Bool mode64 )
Mark Wielaard f9c9f2
       mapReg(m, &i->Pin.AvHashV128Binary.dst);
Mark Wielaard f9c9f2
       mapReg(m, &i->Pin.AvHashV128Binary.src);
Mark Wielaard f9c9f2
       return;
Mark Wielaard f9c9f2
-   case Pin_AvBCDV128Trinary:
Mark Wielaard f9c9f2
-      mapReg(m, &i->Pin.AvBCDV128Trinary.dst);
Mark Wielaard f9c9f2
-      mapReg(m, &i->Pin.AvBCDV128Trinary.src1);
Mark Wielaard f9c9f2
-      mapReg(m, &i->Pin.AvBCDV128Trinary.src2);
Mark Wielaard f9c9f2
-      mapRegs_PPCRI(m, i->Pin.AvBCDV128Trinary.ps);
Mark Wielaard f9c9f2
+   case Pin_AvBCDV128Binary:
Mark Wielaard f9c9f2
+      mapReg(m, &i->Pin.AvBCDV128Binary.dst);
Mark Wielaard f9c9f2
+      mapReg(m, &i->Pin.AvBCDV128Binary.src1);
Mark Wielaard f9c9f2
+      mapReg(m, &i->Pin.AvBCDV128Binary.src2);
Mark Wielaard f9c9f2
       return;
Mark Wielaard f9c9f2
    case Pin_Dfp64Unary:
Mark Wielaard f9c9f2
       mapReg(m, &i->Pin.Dfp64Unary.dst);
Mark Wielaard f9c9f2
@@ -5104,20 +5099,22 @@ Int emit_PPCInstr ( /*MB_MOD*/Bool* is_profInc,
Mark Wielaard f9c9f2
       p = mkFormVX( p, 4, v_dst, v_src, s_field->Pri.Imm, opc2, endness_host );
Mark Wielaard f9c9f2
       goto done;
Mark Wielaard f9c9f2
    }
Mark Wielaard f9c9f2
-   case Pin_AvBCDV128Trinary: {
Mark Wielaard f9c9f2
-      UInt v_dst  = vregEnc(i->Pin.AvBCDV128Trinary.dst);
Mark Wielaard f9c9f2
-      UInt v_src1 = vregEnc(i->Pin.AvBCDV128Trinary.src1);
Mark Wielaard f9c9f2
-      UInt v_src2 = vregEnc(i->Pin.AvBCDV128Trinary.src2);
Mark Wielaard f9c9f2
-      PPCRI* ps   = i->Pin.AvBCDV128Trinary.ps;
Mark Wielaard f9c9f2
+   case Pin_AvBCDV128Binary: {
Mark Wielaard f9c9f2
+      UInt v_dst  = vregEnc(i->Pin.AvBCDV128Binary.dst);
Mark Wielaard f9c9f2
+      UInt v_src1 = vregEnc(i->Pin.AvBCDV128Binary.src1);
Mark Wielaard f9c9f2
+      UInt v_src2 = vregEnc(i->Pin.AvBCDV128Binary.src2);
Mark Wielaard f9c9f2
+      UInt ps = 0;    /* Issue the instruction with ps=0.  The IR code will
Mark Wielaard f9c9f2
+                       * fix up the result if ps=1.
Mark Wielaard f9c9f2
+                       */
Mark Wielaard f9c9f2
       UInt opc2;
Mark Wielaard f9c9f2
-      switch (i->Pin.AvBCDV128Trinary.op) {
Mark Wielaard f9c9f2
+      switch (i->Pin.AvBCDV128Binary.op) {
Mark Wielaard f9c9f2
       case Pav_BCDAdd:   opc2 =  1; break; // bcdadd
Mark Wielaard f9c9f2
       case Pav_BCDSub:   opc2 = 65; break; // bcdsub
Mark Wielaard f9c9f2
       default:
Mark Wielaard f9c9f2
          goto bad;
Mark Wielaard f9c9f2
       }
Mark Wielaard f9c9f2
       p = mkFormVXR( p, 4, v_dst, v_src1, v_src2,
Mark Wielaard f9c9f2
-                     0x1, (ps->Pri.Imm << 9) | opc2, endness_host );
Mark Wielaard f9c9f2
+                     0x1, ps | opc2, endness_host );
Mark Wielaard f9c9f2
       goto done;
Mark Wielaard f9c9f2
    }
Mark Wielaard f9c9f2
    case Pin_AvBin32Fx4: {
Mark Wielaard f9c9f2
diff --git a/VEX/priv/host_ppc_defs.h b/VEX/priv/host_ppc_defs.h
Mark Wielaard f9c9f2
index c04c994..0b1939d 100644
Mark Wielaard f9c9f2
--- a/VEX/priv/host_ppc_defs.h
Mark Wielaard f9c9f2
+++ b/VEX/priv/host_ppc_defs.h
Mark Wielaard f9c9f2
@@ -499,7 +499,7 @@ typedef
Mark Wielaard f9c9f2
       Pin_AvCipherV128Unary,  /* AV Vector unary Cipher */
Mark Wielaard f9c9f2
       Pin_AvCipherV128Binary, /* AV Vector binary Cipher */
Mark Wielaard f9c9f2
       Pin_AvHashV128Binary, /* AV Vector binary Hash */
Mark Wielaard f9c9f2
-      Pin_AvBCDV128Trinary, /* BCD Arithmetic */
Mark Wielaard f9c9f2
+      Pin_AvBCDV128Binary,  /* BCD Arithmetic */
Mark Wielaard f9c9f2
       Pin_Dfp64Unary,   /* DFP64  unary op */
Mark Wielaard f9c9f2
       Pin_Dfp128Unary,  /* DFP128 unary op */
Mark Wielaard f9c9f2
       Pin_DfpShift,     /* Decimal floating point shift by immediate value */
Mark Wielaard f9c9f2
@@ -867,8 +867,7 @@ typedef
Mark Wielaard f9c9f2
             HReg       dst;
Mark Wielaard f9c9f2
             HReg      src1;
Mark Wielaard f9c9f2
             HReg      src2;
Mark Wielaard f9c9f2
-            PPCRI*      ps;
Mark Wielaard f9c9f2
-         } AvBCDV128Trinary;
Mark Wielaard f9c9f2
+         } AvBCDV128Binary;
Mark Wielaard f9c9f2
          struct {
Mark Wielaard f9c9f2
             PPCAvOp   op;
Mark Wielaard f9c9f2
             HReg      dst;
Mark Wielaard f9c9f2
@@ -1063,9 +1062,8 @@ extern PPCInstr* PPCInstr_AvCipherV128Binary ( PPCAvOp op, HReg dst,
Mark Wielaard f9c9f2
                                                HReg srcL, HReg srcR );
Mark Wielaard f9c9f2
 extern PPCInstr* PPCInstr_AvHashV128Binary ( PPCAvOp op, HReg dst,
Mark Wielaard f9c9f2
                                              HReg src, PPCRI* s_field );
Mark Wielaard f9c9f2
-extern PPCInstr* PPCInstr_AvBCDV128Trinary ( PPCAvOp op, HReg dst,
Mark Wielaard f9c9f2
-                                             HReg src1, HReg src2,
Mark Wielaard f9c9f2
-                                             PPCRI* ps );
Mark Wielaard f9c9f2
+extern PPCInstr* PPCInstr_AvBCDV128Binary ( PPCAvOp op, HReg dst,
Mark Wielaard f9c9f2
+                                            HReg src1, HReg src2 );
Mark Wielaard f9c9f2
 extern PPCInstr* PPCInstr_Dfp64Unary  ( PPCFpOp op, HReg dst, HReg src );
Mark Wielaard f9c9f2
 extern PPCInstr* PPCInstr_Dfp64Binary ( PPCFpOp op, HReg dst, HReg srcL,
Mark Wielaard f9c9f2
                                         HReg srcR );
Mark Wielaard f9c9f2
diff --git a/VEX/priv/host_ppc_isel.c b/VEX/priv/host_ppc_isel.c
Mark Wielaard f9c9f2
index 11a9943..5a701ed 100644
Mark Wielaard f9c9f2
--- a/VEX/priv/host_ppc_isel.c
Mark Wielaard f9c9f2
+++ b/VEX/priv/host_ppc_isel.c
Mark Wielaard f9c9f2
@@ -5392,25 +5392,25 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
Mark Wielaard f9c9f2
          addInstr(env, PPCInstr_AvHashV128Binary(op, dst, arg1, s_field));
Mark Wielaard f9c9f2
          return dst;
Mark Wielaard f9c9f2
       }
Mark Wielaard f9c9f2
-      default:
Mark Wielaard f9c9f2
-         break;
Mark Wielaard f9c9f2
-      } /* switch (e->Iex.Binop.op) */
Mark Wielaard f9c9f2
-   } /* if (e->tag == Iex_Binop) */
Mark Wielaard f9c9f2
 
Mark Wielaard f9c9f2
-   if (e->tag == Iex_Triop) {
Mark Wielaard f9c9f2
-      IRTriop *triop = e->Iex.Triop.details;
Mark Wielaard f9c9f2
-      switch (triop->op) {
Mark Wielaard f9c9f2
       case Iop_BCDAdd:op = Pav_BCDAdd; goto do_AvBCDV128;
Mark Wielaard f9c9f2
       case Iop_BCDSub:op = Pav_BCDSub; goto do_AvBCDV128;
Mark Wielaard f9c9f2
       do_AvBCDV128: {
Mark Wielaard f9c9f2
-         HReg arg1 = iselVecExpr(env, triop->arg1, IEndianess);
Mark Wielaard f9c9f2
-         HReg arg2 = iselVecExpr(env, triop->arg2, IEndianess);
Mark Wielaard f9c9f2
+         HReg arg1 = iselVecExpr(env, e->Iex.Binop.arg1, IEndianess);
Mark Wielaard f9c9f2
+         HReg arg2 = iselVecExpr(env, e->Iex.Binop.arg2, IEndianess);
Mark Wielaard f9c9f2
          HReg dst  = newVRegV(env);
Mark Wielaard f9c9f2
-         PPCRI* ps = iselWordExpr_RI(env, triop->arg3, IEndianess);
Mark Wielaard f9c9f2
-         addInstr(env, PPCInstr_AvBCDV128Trinary(op, dst, arg1, arg2, ps));
Mark Wielaard f9c9f2
+         addInstr(env, PPCInstr_AvBCDV128Binary(op, dst, arg1, arg2));
Mark Wielaard f9c9f2
          return dst;
Mark Wielaard f9c9f2
       }
Mark Wielaard f9c9f2
 
Mark Wielaard f9c9f2
+      default:
Mark Wielaard f9c9f2
+         break;
Mark Wielaard f9c9f2
+      } /* switch (e->Iex.Binop.op) */
Mark Wielaard f9c9f2
+   } /* if (e->tag == Iex_Binop) */
Mark Wielaard f9c9f2
+
Mark Wielaard f9c9f2
+   if (e->tag == Iex_Triop) {
Mark Wielaard f9c9f2
+      IRTriop *triop = e->Iex.Triop.details;
Mark Wielaard f9c9f2
+      switch (triop->op) {
Mark Wielaard f9c9f2
       case Iop_Add32Fx4: fpop = Pavfp_ADDF; goto do_32Fx4_with_rm;
Mark Wielaard f9c9f2
       case Iop_Sub32Fx4: fpop = Pavfp_SUBF; goto do_32Fx4_with_rm;
Mark Wielaard f9c9f2
       case Iop_Mul32Fx4: fpop = Pavfp_MULF; goto do_32Fx4_with_rm;
Mark Wielaard f9c9f2
diff --git a/VEX/priv/ir_defs.c b/VEX/priv/ir_defs.c
Mark Wielaard f9c9f2
index 4a7b770..8fdfcab 100644
Mark Wielaard f9c9f2
--- a/VEX/priv/ir_defs.c
Mark Wielaard f9c9f2
+++ b/VEX/priv/ir_defs.c
Mark Wielaard f9c9f2
@@ -3122,7 +3122,8 @@ void typeOfPrimop ( IROp op,
Mark Wielaard f9c9f2
 
Mark Wielaard f9c9f2
       case Iop_BCDAdd:
Mark Wielaard f9c9f2
       case Iop_BCDSub:
Mark Wielaard f9c9f2
-         TERNARY(Ity_V128,Ity_V128, Ity_I8, Ity_V128);
Mark Wielaard f9c9f2
+         BINARY(Ity_V128, Ity_V128, Ity_V128);
Mark Wielaard f9c9f2
+
Mark Wielaard f9c9f2
       case Iop_QDMull16Sx4: case Iop_QDMull32Sx2:
Mark Wielaard f9c9f2
          BINARY(Ity_I64, Ity_I64, Ity_V128);
Mark Wielaard f9c9f2
 
Mark Wielaard f9c9f2
commit c8da12c274b2d94c42c07676139378b57fa7b31b
Mark Wielaard f9c9f2
Author: carll <carll@a5019735-40e9-0310-863c-91ae7b9d1cf9>
Mark Wielaard f9c9f2
Date:   Tue Apr 26 19:53:56 2016 +0000
Mark Wielaard f9c9f2
Mark Wielaard f9c9f2
    Power PC  Fix V bit error in 128-bit BCD add and subtract instructions
Mark Wielaard f9c9f2
    
Mark Wielaard f9c9f2
    The original code was using the bcdadd / bcdsub instruction on the operand
Mark Wielaard f9c9f2
    shadow bits to calculate the shadow bits for the result.  This introduced
Mark Wielaard f9c9f2
    non-zero bits shadow bits in the result.   The shadow bits for these
Mark Wielaard f9c9f2
    instructions should be set to all valid or all invalid.  If one of the
Mark Wielaard f9c9f2
    argument shadow bits was one, then all of the shadow bits of the result should
Mark Wielaard f9c9f2
    be one.  Otherwise the result shadow bits should be zero.
Mark Wielaard f9c9f2
    
Mark Wielaard f9c9f2
    This patch fixes the above bug in memcheck/mc_translate.c
Mark Wielaard f9c9f2
    
Mark Wielaard f9c9f2
    Fixing the above bug broke the v-bit test.  The issue is the v-bit tester
Mark Wielaard f9c9f2
    assumes the shadow bits for the operands of a given Iop can be set to one
Mark Wielaard f9c9f2
    for testing purposes.  The implementation of the bcdadd and bcdsub was passing
Mark Wielaard f9c9f2
    a constant value for the variable ps.  The ps value is an argument to the
Mark Wielaard f9c9f2
    instruction that specifies how to set the sign code of the result.  The
Mark Wielaard f9c9f2
    implementation of the instructions was changed to issue the instruction with
Mark Wielaard f9c9f2
    ps=0.  Then the result of the instruction is updated in the VEX code if ps=1.
Mark Wielaard f9c9f2
    This changed also results in cleaning up the vbit test code.
Mark Wielaard f9c9f2
    
Mark Wielaard f9c9f2
    This patch also fixes the issues with the v-bit test program.
Mark Wielaard f9c9f2
    
Mark Wielaard f9c9f2
    Valgrind commit 3218
Mark Wielaard f9c9f2
    
Mark Wielaard f9c9f2
    Bugzilla 360035
Mark Wielaard f9c9f2
    
Mark Wielaard f9c9f2
    
Mark Wielaard f9c9f2
    git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15871 a5019735-40e9-0310-863c-91ae7b9d1cf9
Mark Wielaard f9c9f2
Mark Wielaard f9c9f2
diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c
Mark Wielaard f9c9f2
index c239e46..d50b53d 100644
Mark Wielaard f9c9f2
--- a/memcheck/mc_translate.c
Mark Wielaard f9c9f2
+++ b/memcheck/mc_translate.c
Mark Wielaard f9c9f2
@@ -852,6 +852,17 @@ static IRAtom* mkPCastTo( MCEnv* mce, IRType dst_ty, IRAtom* vbits )
Mark Wielaard f9c9f2
                                        unop(Iop_CmpNEZ64, tmp4));
Mark Wielaard f9c9f2
          break;
Mark Wielaard f9c9f2
       }
Mark Wielaard f9c9f2
+      case Ity_V128: {
Mark Wielaard f9c9f2
+         /* Chop it in half, OR the halves together, and compare that
Mark Wielaard f9c9f2
+          * with zero.
Mark Wielaard f9c9f2
+          */
Mark Wielaard f9c9f2
+         IRAtom* tmp2 = assignNew('V', mce, Ity_I64, unop(Iop_V128HIto64, vbits));
Mark Wielaard f9c9f2
+         IRAtom* tmp3 = assignNew('V', mce, Ity_I64, unop(Iop_V128to64, vbits));
Mark Wielaard f9c9f2
+         IRAtom* tmp4 = assignNew('V', mce, Ity_I64, binop(Iop_Or64, tmp2, tmp3));
Mark Wielaard f9c9f2
+         tmp1         = assignNew('V', mce, Ity_I1,
Mark Wielaard f9c9f2
+                                       unop(Iop_CmpNEZ64, tmp4));
Mark Wielaard f9c9f2
+         break;
Mark Wielaard f9c9f2
+      }
Mark Wielaard f9c9f2
       default:
Mark Wielaard f9c9f2
          ppIRType(src_ty);
Mark Wielaard f9c9f2
          VG_(tool_panic)("mkPCastTo(1)");
Mark Wielaard f9c9f2
@@ -2888,11 +2899,6 @@ IRAtom* expr2vbits_Triop ( MCEnv* mce,
Mark Wielaard f9c9f2
       case Iop_SetElem32x2:
Mark Wielaard f9c9f2
          complainIfUndefined(mce, atom2, NULL);
Mark Wielaard f9c9f2
          return assignNew('V', mce, Ity_I64, triop(op, vatom1, atom2, vatom3));
Mark Wielaard f9c9f2
-      /* BCDIops */
Mark Wielaard f9c9f2
-      case Iop_BCDAdd:
Mark Wielaard f9c9f2
-      case Iop_BCDSub:
Mark Wielaard f9c9f2
-         complainIfUndefined(mce, atom3, NULL);
Mark Wielaard f9c9f2
-         return assignNew('V', mce, Ity_V128, triop(op, vatom1, vatom2, atom3));
Mark Wielaard f9c9f2
 
Mark Wielaard f9c9f2
       /* Vector FP with rounding mode as the first arg */
Mark Wielaard f9c9f2
       case Iop_Add64Fx2:
Mark Wielaard f9c9f2
@@ -3723,6 +3729,10 @@ IRAtom* expr2vbits_Binop ( MCEnv* mce,
Mark Wielaard f9c9f2
          complainIfUndefined(mce, atom2, NULL);
Mark Wielaard f9c9f2
          return assignNew('V', mce, Ity_V128, binop(op, vatom1, atom2));
Mark Wielaard f9c9f2
 
Mark Wielaard f9c9f2
+      case Iop_BCDAdd:
Mark Wielaard f9c9f2
+      case Iop_BCDSub:
Mark Wielaard f9c9f2
+         return mkLazy2(mce, Ity_V128, vatom1, vatom2);
Mark Wielaard f9c9f2
+
Mark Wielaard f9c9f2
       /* SHA Iops */
Mark Wielaard f9c9f2
       case Iop_SHA256:
Mark Wielaard f9c9f2
       case Iop_SHA512: