cb589a
commit b7d65cab4f3e9a6f66a496e723e53ed736c4d2e7
cb589a
Author: Mark Wielaard <mark@klomp.org>
cb589a
Date:   Sun Dec 9 00:55:42 2018 +0100
cb589a
cb589a
    Implement ppc64 lxvd2x as 128-bit load with double word swap for ppc64le.
cb589a
    
cb589a
    This makes it possible for memcheck to know which part of the 128bit
cb589a
    vector is defined, even if the load is partly beyond an addressable block.
cb589a
    
cb589a
    Partially resolves bug 386945.
cb589a
cb589a
diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c
cb589a
index a81dace..7af4973 100644
cb589a
--- a/VEX/priv/guest_ppc_toIR.c
cb589a
+++ b/VEX/priv/guest_ppc_toIR.c
cb589a
@@ -20590,16 +20590,22 @@ dis_vx_load ( UInt theInstr )
cb589a
    }
cb589a
    case 0x34C: // lxvd2x
cb589a
    {
cb589a
-      IROp addOp = ty == Ity_I64 ? Iop_Add64 : Iop_Add32;
cb589a
-      IRExpr * high, *low;
cb589a
-      ULong ea_off = 8;
cb589a
-      IRExpr* high_addr;
cb589a
+      IRExpr *t128;
cb589a
       DIP("lxvd2x %d,r%u,r%u\n", XT, rA_addr, rB_addr);
cb589a
-      high = load( Ity_I64, mkexpr( EA ) );
cb589a
-      high_addr = binop( addOp, mkexpr( EA ), ty == Ity_I64 ? mkU64( ea_off )
cb589a
-            : mkU32( ea_off ) );
cb589a
-      low = load( Ity_I64, high_addr );
cb589a
-      putVSReg( XT, binop( Iop_64HLtoV128, high, low ) );
cb589a
+      t128 = load( Ity_V128, mkexpr( EA ) );
cb589a
+
cb589a
+      /* The data in the vec register should be in big endian order.
cb589a
+         So if we just did a little endian load then swap around the
cb589a
+         high and low double words. */
cb589a
+      if (host_endness == VexEndnessLE) {
cb589a
+         IRTemp high = newTemp(Ity_I64);
cb589a
+         IRTemp low = newTemp(Ity_I64);
cb589a
+         assign( high, unop(Iop_V128HIto64, t128) );
cb589a
+         assign( low, unop(Iop_V128to64, t128) );
cb589a
+         t128 = binop( Iop_64HLtoV128, mkexpr (low), mkexpr (high) );
cb589a
+      }
cb589a
+
cb589a
+      putVSReg( XT, t128 );
cb589a
       break;
cb589a
    }
cb589a
    case 0x14C: // lxvdsx