Mark Wielaard edae2b
commit 6e08ee95f7f1b1c3fd434fa380cc5b2cc3e3f7c7
Mark Wielaard edae2b
Author: Carl Love <cel@us.ibm.com>
Mark Wielaard edae2b
Date:   Fri Oct 29 16:30:33 2021 -0500
Mark Wielaard edae2b
Mark Wielaard edae2b
    Bug 444571 - PPC, fix the lxsibzx and lxsihzx so they only load their respective sized data.
Mark Wielaard edae2b
    
Mark Wielaard edae2b
    The lxsibzx was doing a 64-bit load.  The result was initializing
Mark Wielaard edae2b
    additional bytes in the register that should not have been initialized.
Mark Wielaard edae2b
    The memcheck/tests/linux/dlclose_leak test detected the issue.  The
Mark Wielaard edae2b
    code generation uses lxsibzx and stxsibx with -mcpu=power9.  Previously
Mark Wielaard edae2b
    the lbz and stb instructions were generated.
Mark Wielaard edae2b
    
Mark Wielaard edae2b
    The same issue was noted and fixed with the lxsihzx instruction.  The
Mark Wielaard edae2b
    memcheck/tests/linux/badrw test now passes as well.
Mark Wielaard edae2b
    
Mark Wielaard edae2b
    https://bugs.kde.org/show_bug.cgi?id=444571
Mark Wielaard edae2b
Mark Wielaard edae2b
diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c
Mark Wielaard edae2b
index d90d566ed..8afd77490 100644
Mark Wielaard edae2b
--- a/VEX/priv/guest_ppc_toIR.c
Mark Wielaard edae2b
+++ b/VEX/priv/guest_ppc_toIR.c
Mark Wielaard edae2b
@@ -25359,19 +25359,17 @@ dis_vx_load ( UInt prefix, UInt theInstr )
Mark Wielaard edae2b
 
Mark Wielaard edae2b
       else
Mark Wielaard edae2b
          irx_addr = mkexpr( EA );
Mark Wielaard edae2b
-
Mark Wielaard edae2b
-      byte = load( Ity_I64, irx_addr );
Mark Wielaard edae2b
+      /* byte load */
Mark Wielaard edae2b
+      byte = load( Ity_I8, irx_addr );
Mark Wielaard edae2b
       putVSReg( XT, binop( Iop_64HLtoV128,
Mark Wielaard edae2b
-                            binop( Iop_And64,
Mark Wielaard edae2b
-                                   byte,
Mark Wielaard edae2b
-                                   mkU64( 0xFF ) ),
Mark Wielaard edae2b
+                           unop( Iop_8Uto64, byte ),
Mark Wielaard edae2b
                            mkU64( 0 ) ) );
Mark Wielaard edae2b
       break;
Mark Wielaard edae2b
    }
Mark Wielaard edae2b
 
Mark Wielaard edae2b
    case 0x32D: // lxsihzx
Mark Wielaard edae2b
    {
Mark Wielaard edae2b
-      IRExpr *byte;
Mark Wielaard edae2b
+      IRExpr *hword;
Mark Wielaard edae2b
       IRExpr* irx_addr;
Mark Wielaard edae2b
 
Mark Wielaard edae2b
       DIP("lxsihzx %u,r%u,r%u\n", (UInt)XT, rA_addr, rB_addr);
Mark Wielaard edae2b
@@ -25382,11 +25380,10 @@ dis_vx_load ( UInt prefix, UInt theInstr )
Mark Wielaard edae2b
       else
Mark Wielaard edae2b
          irx_addr = mkexpr( EA );
Mark Wielaard edae2b
 
Mark Wielaard edae2b
-      byte = load( Ity_I64, irx_addr );
Mark Wielaard edae2b
+      hword = load( Ity_I16, irx_addr );
Mark Wielaard edae2b
       putVSReg( XT, binop( Iop_64HLtoV128,
Mark Wielaard edae2b
-                            binop( Iop_And64,
Mark Wielaard edae2b
-                                   byte,
Mark Wielaard edae2b
-                                   mkU64( 0xFFFF ) ),
Mark Wielaard edae2b
+                            unop( Iop_16Uto64,
Mark Wielaard edae2b
+                                  hword ),
Mark Wielaard edae2b
                            mkU64( 0 ) ) );
Mark Wielaard edae2b
       break;
Mark Wielaard edae2b
    }