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