]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
The existing overflow detection in VEX/priv/guest_ppc_toIR.c/set_XER_OV_64()
authorCarl Love <cel@us.ibm.com>
Fri, 6 Sep 2013 22:27:34 +0000 (22:27 +0000)
committerCarl Love <cel@us.ibm.com>
Fri, 6 Sep 2013 22:27:34 +0000 (22:27 +0000)
under the case PPCG_FLAG_OP_MULLW: does not apply to the mulldo as we need to
detect overflow when performing a Multiply Low Doubleword (not Multiply Low
Word). Hence, we added a new enumeration value PPCG_FLAG_OP_MULLD in
VEX/priv/guest_ppc_defs.h and a corresponding new case under which the
computation for detecting overflow for mulldo/mulldo. is added in
set_XER_OV_64(). The tests have been added to: none/tests/ppc32/jm-insns.c

Bugzilla 324594, submitted by Anmol P. Paralkar

Patch reviewed and tested by Carl Love

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

VEX/priv/guest_ppc_defs.h
VEX/priv/guest_ppc_toIR.c

index 11844b10df962c8060ed52dc673842da88af8399..0ac45748c37a19967737e90448448571ba5eda68 100644 (file)
@@ -134,6 +134,7 @@ enum {
    /* 15 */ PPCG_FLAG_OP_DIVWEU,  // divweuo
    /* 16 */ PPCG_FLAG_OP_DIVWE,   // divweo
    /* 17 */ PPCG_FLAG_OP_DIVDEU,  // divdeuo
+   /* 18 */ PPCG_FLAG_OP_MULLD,   // mulldo
    PPCG_FLAG_OP_NUMBER
 };
 
index ab13815f443a599ab26a7b62903eb5db65f2ac9c..34166b04916c66fbf52358e14539b6657978a16c 100644 (file)
@@ -2121,6 +2121,22 @@ static void set_XER_OV_64( UInt op, IRExpr* res,
                          binop( Iop_CmpLE64U, argR, argL ) );
      break;
 
+   case /* 18 */ PPCG_FLAG_OP_MULLD: {
+      IRTemp  t128;
+      /* OV true if result can't be represented in 64 bits
+         i.e sHi != sign extension of sLo */
+      t128 = newTemp(Ity_I128);
+      assign( t128, binop(Iop_MullS64, argL, argR) );
+      xer_ov 
+         = binop( Iop_CmpNE64,
+                  unop(Iop_128HIto64, mkexpr(t128)),
+                  binop( Iop_Sar64,
+                         unop(Iop_128to64, mkexpr(t128)),
+                         mkU8(63))
+                  );
+      break;
+   }
+      
    default: 
       vex_printf("set_XER_OV: op = %u\n", op);
       vpanic("set_XER_OV(ppc64)");
@@ -3483,7 +3499,7 @@ static Bool dis_int_arith ( UInt theInstr )
              rD_addr, rA_addr, rB_addr);
          assign( rD, binop(Iop_Mul64, mkexpr(rA), mkexpr(rB)) );
          if (flag_OE) {
-            set_XER_OV( ty, PPCG_FLAG_OP_MULLW
+            set_XER_OV( ty, PPCG_FLAG_OP_MULLD
                         mkexpr(rD), mkexpr(rA), mkexpr(rB) );
          }
          break;