]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
This patch makes the needed changes to the lxvw4x for Little Endian.
authorCarl Love <cel@us.ibm.com>
Thu, 9 Oct 2014 21:08:25 +0000 (21:08 +0000)
committerCarl Love <cel@us.ibm.com>
Thu, 9 Oct 2014 21:08:25 +0000 (21:08 +0000)
The data was being loaded in the Big Endian data order for most
cases.  The code in host_ppc_isel.c was changed to do a right
shift and to permute the hi and lo registers in the other order
to ensure the data was always loaded in BE order.  The lxvw4x
emulation in guest_ppc_toIR.c was changed to permute the data from
the BE order to LE order when running on an LE system.

bugzilla 339433

git-svn-id: svn://svn.valgrind.org/vex/trunk@2973

VEX/priv/guest_ppc_toIR.c
VEX/priv/host_ppc_isel.c

index 2461b6888ee9a756997aaad2fad18312415f8e48..f0ace0bdf1198360f8adea9e9227d24ede507763 100644 (file)
@@ -15323,7 +15323,22 @@ dis_vx_load ( UInt theInstr )
 
       DIP("lxvw4x %d,r%u,r%u\n", (UInt)XT, rA_addr, rB_addr);
 
-      t0 = load( Ity_V128, mkexpr( EA ) );
+      /* The load will result in the data being in BE order. */
+      if (host_endness == VexEndnessLE) {
+         IRExpr *t0_BE;
+         IRTemp perm_LE = newTemp(Ity_V128);
+
+         t0_BE = load( Ity_V128, mkexpr( EA ) );
+
+         /*  Permute the data to LE format */
+         assign( perm_LE, binop( Iop_64HLtoV128, mkU64(0x0c0d0e0f08090a0b),
+                                 mkU64(0x0405060700010203)));
+
+         t0 = binop( Iop_Perm8x16, t0_BE, mkexpr(perm_LE) );
+      } else {
+         t0 = load( Ity_V128, mkexpr( EA ) );
+      }
+
       putVSReg( XT, t0 );
       break;
    }
index 1a31b037ab7c2d6f5820e46a2f5b96e263b43cbb..7489b61935788a8637aec9391876260baaef4b00 100644 (file)
@@ -4871,9 +4871,9 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
    }
 
    if (e->tag == Iex_Load && e->Iex.Load.end == IEndianess) {
-      /* Need to be able to do V128 unaligned loads. The unaligned load can
-       * be accomplised using the following code sequece from the ISA.  It
-       * uses the lvx instruction that does two aligned loads and then
+      /* Need to be able to do V128 unaligned loads. The BE unaligned load
+       * can be accomplised using the following code sequece from the ISA.
+       * It uses the lvx instruction that does two aligned loads and then
        * permute the data to store the required data as if it had been an
        * unaligned load.
        *
@@ -4898,9 +4898,14 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
       addInstr(env, PPCInstr_AvLdSt( True/*load*/, 16, Vhi,
                                      PPCAMode_IR(0, rB)) );
 
-      // lvsl Vp, 0, Rb
-      addInstr(env, PPCInstr_AvSh( True/*left shift*/, Vp,
-                                   PPCAMode_IR(0, rB)) );
+      if (IEndianess == Iend_LE)
+         // lvsr Vp, 0, Rb
+         addInstr(env, PPCInstr_AvSh( False/*right shift*/, Vp,
+                                      PPCAMode_IR(0, rB)) );
+      else
+         // lvsl Vp, 0, Rb
+         addInstr(env, PPCInstr_AvSh( True/*left shift*/, Vp,
+                                      PPCAMode_IR(0, rB)) );
 
       // addi Rb_plus_15, Rb, 15
       addInstr(env, PPCInstr_Alu( Palu_ADD, rB_plus_15,
@@ -4910,8 +4915,13 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e, IREndness IEndianess )
       addInstr(env, PPCInstr_AvLdSt( True/*load*/, 16, Vlo,
                                      PPCAMode_IR(0, rB_plus_15)) );
 
-      // vperm Vt, Vhi, Vlo, Vp
-      addInstr(env, PPCInstr_AvPerm( v_dst, Vhi, Vlo, Vp ));
+      if (IEndianess == Iend_LE)
+         // vperm Vt, Vhi, Vlo, Vp
+         addInstr(env, PPCInstr_AvPerm( v_dst, Vlo, Vhi, Vp ));
+      else
+         // vperm Vt, Vhi, Vlo, Vp
+         addInstr(env, PPCInstr_AvPerm( v_dst, Vhi, Vlo, Vp ));
+
       return v_dst;
    }