From: Mark Wielaard Date: Sat, 8 Dec 2018 23:55:42 +0000 (+0100) Subject: Implement ppc64 lxvd2x as 128-bit load with double word swap for ppc64le. X-Git-Tag: VALGRIND_3_15_0~126 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=98a73de1c0c83918a63e736b62d428bc2f98c943;p=thirdparty%2Fvalgrind.git Implement ppc64 lxvd2x as 128-bit load with double word swap for ppc64le. This makes it possible for memcheck to know which part of the 128bit vector is defined, even if the load is partly beyond an addressable block. Partially resolves bug 386945. --- diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c index 10f6daa184..72c9c137bb 100644 --- a/VEX/priv/guest_ppc_toIR.c +++ b/VEX/priv/guest_ppc_toIR.c @@ -20590,16 +20590,22 @@ dis_vx_load ( UInt theInstr ) } case 0x34C: // lxvd2x { - IROp addOp = ty == Ity_I64 ? Iop_Add64 : Iop_Add32; - IRExpr * high, *low; - ULong ea_off = 8; - IRExpr* high_addr; + IRExpr *t128; DIP("lxvd2x %d,r%u,r%u\n", XT, rA_addr, rB_addr); - high = load( Ity_I64, mkexpr( EA ) ); - high_addr = binop( addOp, mkexpr( EA ), ty == Ity_I64 ? mkU64( ea_off ) - : mkU32( ea_off ) ); - low = load( Ity_I64, high_addr ); - putVSReg( XT, binop( Iop_64HLtoV128, high, low ) ); + t128 = load( Ity_V128, mkexpr( EA ) ); + + /* The data in the vec register should be in big endian order. + So if we just did a little endian load then swap around the + high and low double words. */ + if (host_endness == VexEndnessLE) { + IRTemp high = newTemp(Ity_I64); + IRTemp low = newTemp(Ity_I64); + assign( high, unop(Iop_V128HIto64, t128) ); + assign( low, unop(Iop_V128to64, t128) ); + t128 = binop( Iop_64HLtoV128, mkexpr (low), mkexpr (high) ); + } + + putVSReg( XT, t128 ); break; } case 0x14C: // lxvdsx