|
From: <sv...@va...> - 2014-08-20 10:53:07
|
Author: sewardj
Date: Wed Aug 20 10:52:58 2014
New Revision: 2930
Log:
Merge, from trunk:
r2754 (fix overflow detection for mulldo)
r2929 (fix partial updates of FPSCR.{RN,DRN})
Modified:
branches/VEX_3_8_BRANCH_BGQ/priv/guest_ppc_defs.h
branches/VEX_3_8_BRANCH_BGQ/priv/guest_ppc_toIR.c
Modified: branches/VEX_3_8_BRANCH_BGQ/priv/guest_ppc_defs.h
==============================================================================
--- branches/VEX_3_8_BRANCH_BGQ/priv/guest_ppc_defs.h (original)
+++ branches/VEX_3_8_BRANCH_BGQ/priv/guest_ppc_defs.h Wed Aug 20 10:52:58 2014
@@ -129,6 +129,7 @@
/* 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
};
Modified: branches/VEX_3_8_BRANCH_BGQ/priv/guest_ppc_toIR.c
==============================================================================
--- branches/VEX_3_8_BRANCH_BGQ/priv/guest_ppc_toIR.c (original)
+++ branches/VEX_3_8_BRANCH_BGQ/priv/guest_ppc_toIR.c Wed Aug 20 10:52:58 2014
@@ -2222,6 +2222,22 @@
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)");
@@ -2797,21 +2813,59 @@
switch (reg) {
case PPC_GST_FPSCR: {
/* Allow writes to either binary or decimal floating point
- * Rounding Mode
- */
+ Rounding Mode.
+ */
+ /* If any part of |mask| covers FPSCR.RN, update the bits of
+ FPSCR.RN by copying in |src| for locations where the
+ corresponding bit in |mask| is 1, and leaving it unchanged
+ for corresponding |mask| zero bits. */
if (mask & MASK_FPSCR_RN) {
- stmt( IRStmt_Put( OFFB_FPROUND,
- unop( Iop_32to8,
- binop( Iop_And32,
- unop( Iop_64to32, src ),
- mkU32( MASK_FPSCR_RN & mask ) ) ) ) );
- } else if (mask & MASK_FPSCR_DRN) {
- stmt( IRStmt_Put( OFFB_DFPROUND,
- unop( Iop_32to8,
- binop( Iop_And32,
- unop( Iop_64HIto32, src ),
- mkU32( ( MASK_FPSCR_DRN & mask )
- >> 32 ) ) ) ) );
+ stmt(
+ IRStmt_Put(
+ OFFB_FPROUND,
+ unop(
+ Iop_32to8,
+ binop(
+ Iop_Or32,
+ binop(
+ Iop_And32,
+ unop(Iop_64to32, src),
+ mkU32(MASK_FPSCR_RN & mask)
+ ),
+ binop(
+ Iop_And32,
+ unop(Iop_8Uto32, IRExpr_Get(OFFB_FPROUND,Ity_I8)),
+ mkU32(MASK_FPSCR_RN & ~mask)
+ )
+ )
+ )
+ )
+ );
+ }
+ /* Similarly, update FPSCR.DRN if any bits of |mask|
+ corresponding to FPSCR.DRN are set. */
+ if (mask & MASK_FPSCR_DRN) {
+ stmt(
+ IRStmt_Put(
+ OFFB_DFPROUND,
+ unop(
+ Iop_32to8,
+ binop(
+ Iop_Or32,
+ binop(
+ Iop_And32,
+ unop(Iop_64HIto32, src),
+ mkU32((MASK_FPSCR_DRN & mask) >> 32)
+ ),
+ binop(
+ Iop_And32,
+ unop(Iop_8Uto32, IRExpr_Get(OFFB_DFPROUND,Ity_I8)),
+ mkU32((MASK_FPSCR_DRN & ~mask) >> 32)
+ )
+ )
+ )
+ )
+ );
}
/* Give EmWarn for attempted writes to:
@@ -3583,7 +3637,7 @@
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;
|