From: Carl Love Date: Fri, 6 Sep 2013 22:27:34 +0000 (+0000) Subject: The existing overflow detection in VEX/priv/guest_ppc_toIR.c/set_XER_OV_64() X-Git-Tag: svn/VALGRIND_3_9_0^2~41 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0459c0f18a39b93b2684ab4788b165b84368f23d;p=thirdparty%2Fvalgrind.git The existing overflow detection in VEX/priv/guest_ppc_toIR.c/set_XER_OV_64() 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 --- diff --git a/VEX/priv/guest_ppc_defs.h b/VEX/priv/guest_ppc_defs.h index 11844b10df..0ac45748c3 100644 --- a/VEX/priv/guest_ppc_defs.h +++ b/VEX/priv/guest_ppc_defs.h @@ -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 }; diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c index ab13815f44..34166b0491 100644 --- a/VEX/priv/guest_ppc_toIR.c +++ b/VEX/priv/guest_ppc_toIR.c @@ -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;