|
From: <sv...@va...> - 2016-02-16 21:20:32
|
Author: carll
Date: Tue Feb 16 21:20:24 2016
New Revision: 3209
Log:
128bit modulo and carry instruction fix
This patch fixes an issue with caculating the carry to the next 32-bit
chunk for the 128-bit add and subract instructions: vaddcuq, vadduqm,
vsubcuq, vsubuqm, vaddecuq, vaddeuqm, vsubecuq, vsubeuqm
Valgrind Bugzilla 359472
Modified:
trunk/priv/guest_ppc_toIR.c
Modified: trunk/priv/guest_ppc_toIR.c
==============================================================================
--- trunk/priv/guest_ppc_toIR.c (original)
+++ trunk/priv/guest_ppc_toIR.c Tue Feb 16 21:20:24 2016
@@ -17968,6 +17968,7 @@
IRTemp _vecA_32 = IRTemp_INVALID;
IRTemp _vecB_32 = IRTemp_INVALID;
IRTemp res_32 = IRTemp_INVALID;
+ IRTemp res_64 = IRTemp_INVALID;
IRTemp result = IRTemp_INVALID;
IRTemp tmp_result = IRTemp_INVALID;
IRTemp carry = IRTemp_INVALID;
@@ -17977,10 +17978,15 @@
IRExpr * _vecA_high64 = unop( Iop_V128HIto64, vecA );
IRExpr * _vecB_high64 = unop( Iop_V128HIto64, vecB );
+ carry = newTemp(Ity_I32);
+ assign( carry, cin );
+
for (i = 0; i < 4; i++) {
_vecA_32 = newTemp(Ity_I32);
_vecB_32 = newTemp(Ity_I32);
res_32 = newTemp(Ity_I32);
+ res_64 = newTemp(Ity_I64);
+
switch (i) {
case 0:
assign(_vecA_32, unop( Iop_64to32, _vecA_low64 ) );
@@ -18000,13 +18006,25 @@
break;
}
- assign(res_32, binop( Iop_Add32,
- binop( Iop_Add32,
- binop ( Iop_Add32,
- mkexpr(_vecA_32),
- mkexpr(_vecB_32) ),
- (i == 0) ? mkU32(0) : mkexpr(carry) ),
- (i == 0) ? cin : mkU32(0) ) );
+ assign( res_64, binop( Iop_Add64,
+ binop ( Iop_Add64,
+ binop( Iop_32HLto64,
+ mkU32( 0 ),
+ mkexpr(_vecA_32) ),
+ binop( Iop_32HLto64,
+ mkU32( 0 ),
+ mkexpr(_vecB_32) ) ),
+ binop( Iop_32HLto64,
+ mkU32( 0 ),
+ mkexpr( carry ) ) ) );
+
+ /* Calculate the carry to the next higher 32 bits. */
+ carry = newTemp(Ity_I32);
+ assign(carry, unop( Iop_64HIto32, mkexpr( res_64 ) ) );
+
+ /* result is the lower 32-bits */
+ assign(res_32, unop( Iop_64to32, mkexpr( res_64 ) ) );
+
if (modulo) {
result = newTemp(Ity_V128);
assign(result, binop( Iop_OrV128,
@@ -18023,10 +18041,6 @@
tmp_result = newTemp(Ity_V128);
assign(tmp_result, mkexpr(result));
}
- carry = newTemp(Ity_I32);
- assign(carry, unop(Iop_1Uto32, binop( Iop_CmpLT32U,
- mkexpr(res_32),
- mkexpr(_vecA_32 ) ) ) );
}
if (modulo)
return result;
|