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