Mark Wielaard 1b2d1f
commit dc1523fb3550b4ed9dd4c178741626daaa474da7
Mark Wielaard 1b2d1f
Author: Mark Wielaard <mark@klomp.org>
Mark Wielaard 1b2d1f
Date:   Mon Dec 10 17:18:20 2018 +0100
Mark Wielaard 1b2d1f
Mark Wielaard 1b2d1f
    PR386945 set_AV_CR6 patch
Mark Wielaard 1b2d1f
    
Mark Wielaard 1b2d1f
    https://bugs.kde.org/show_bug.cgi?id=386945#c62
Mark Wielaard 1b2d1f
Mark Wielaard 1b2d1f
diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c
Mark Wielaard 1b2d1f
index ec2f90a..c3cc6d0 100644
Mark Wielaard 1b2d1f
--- a/VEX/priv/guest_ppc_toIR.c
Mark Wielaard 1b2d1f
+++ b/VEX/priv/guest_ppc_toIR.c
Mark Wielaard 1b2d1f
@@ -2062,45 +2062,88 @@ static void set_CR0 ( IRExpr* result )
Mark Wielaard 1b2d1f
 static void set_AV_CR6 ( IRExpr* result, Bool test_all_ones )
Mark Wielaard 1b2d1f
 {
Mark Wielaard 1b2d1f
    /* CR6[0:3] = {all_ones, 0, all_zeros, 0}
Mark Wielaard 1b2d1f
-      all_ones  = (v[0] && v[1] && v[2] && v[3])
Mark Wielaard 1b2d1f
-      all_zeros = ~(v[0] || v[1] || v[2] || v[3])
Mark Wielaard 1b2d1f
+      32 bit: all_zeros =  (v[0] || v[1] || v[2] || v[3]) == 0x0000'0000
Mark Wielaard 1b2d1f
+              all_ones  = ~(v[0] && v[1] && v[2] && v[3]) == 0x0000'0000
Mark Wielaard 1b2d1f
+              where v[] denotes 32-bit lanes
Mark Wielaard 1b2d1f
+      or
Mark Wielaard 1b2d1f
+      64 bit: all_zeros =  (v[0] || v[1]) == 0x0000'0000'0000'0000
Mark Wielaard 1b2d1f
+              all_ones  = ~(v[0] && v[1]) == 0x0000'0000'0000'0000
Mark Wielaard 1b2d1f
+              where v[] denotes 64-bit lanes
Mark Wielaard 1b2d1f
+
Mark Wielaard 1b2d1f
+      The 32- and 64-bit versions compute the same thing, but the 64-bit one
Mark Wielaard 1b2d1f
+      tries to be a bit more efficient.
Mark Wielaard 1b2d1f
    */
Mark Wielaard 1b2d1f
-   IRTemp v0 = newTemp(Ity_V128);
Mark Wielaard 1b2d1f
-   IRTemp v1 = newTemp(Ity_V128);
Mark Wielaard 1b2d1f
-   IRTemp v2 = newTemp(Ity_V128);
Mark Wielaard 1b2d1f
-   IRTemp v3 = newTemp(Ity_V128);
Mark Wielaard 1b2d1f
-   IRTemp rOnes  = newTemp(Ity_I8);
Mark Wielaard 1b2d1f
-   IRTemp rZeros = newTemp(Ity_I8);
Mark Wielaard 1b2d1f
-
Mark Wielaard 1b2d1f
    vassert(typeOfIRExpr(irsb->tyenv,result) == Ity_V128);
Mark Wielaard 1b2d1f
 
Mark Wielaard 1b2d1f
-   assign( v0, result );
Mark Wielaard 1b2d1f
-   assign( v1, binop(Iop_ShrV128, result, mkU8(32)) );
Mark Wielaard 1b2d1f
-   assign( v2, binop(Iop_ShrV128, result, mkU8(64)) );
Mark Wielaard 1b2d1f
-   assign( v3, binop(Iop_ShrV128, result, mkU8(96)) );
Mark Wielaard 1b2d1f
+   IRTemp overlappedOred  = newTemp(Ity_V128);
Mark Wielaard 1b2d1f
+   IRTemp overlappedAnded = newTemp(Ity_V128);
Mark Wielaard 1b2d1f
+
Mark Wielaard 1b2d1f
+   if (mode64) {
Mark Wielaard 1b2d1f
+      IRTemp v0 = newTemp(Ity_V128);
Mark Wielaard 1b2d1f
+      IRTemp v1 = newTemp(Ity_V128);
Mark Wielaard 1b2d1f
+      assign( v0, result );
Mark Wielaard 1b2d1f
+      assign( v1, binop(Iop_ShrV128, result, mkU8(64)) );
Mark Wielaard 1b2d1f
+      assign(overlappedOred,
Mark Wielaard 1b2d1f
+             binop(Iop_OrV128, mkexpr(v0), mkexpr(v1)));
Mark Wielaard 1b2d1f
+      assign(overlappedAnded,
Mark Wielaard 1b2d1f
+             binop(Iop_AndV128, mkexpr(v0), mkexpr(v1)));
Mark Wielaard 1b2d1f
+   } else {
Mark Wielaard 1b2d1f
+      IRTemp v0 = newTemp(Ity_V128);
Mark Wielaard 1b2d1f
+      IRTemp v1 = newTemp(Ity_V128);
Mark Wielaard 1b2d1f
+      IRTemp v2 = newTemp(Ity_V128);
Mark Wielaard 1b2d1f
+      IRTemp v3 = newTemp(Ity_V128);
Mark Wielaard 1b2d1f
+      assign( v0, result );
Mark Wielaard 1b2d1f
+      assign( v1, binop(Iop_ShrV128, result, mkU8(32)) );
Mark Wielaard 1b2d1f
+      assign( v2, binop(Iop_ShrV128, result, mkU8(64)) );
Mark Wielaard 1b2d1f
+      assign( v3, binop(Iop_ShrV128, result, mkU8(96)) );
Mark Wielaard 1b2d1f
+      assign(overlappedOred,
Mark Wielaard 1b2d1f
+             binop(Iop_OrV128,
Mark Wielaard 1b2d1f
+                   binop(Iop_OrV128, mkexpr(v0), mkexpr(v1)),
Mark Wielaard 1b2d1f
+                   binop(Iop_OrV128, mkexpr(v2), mkexpr(v3))));
Mark Wielaard 1b2d1f
+      assign(overlappedAnded,
Mark Wielaard 1b2d1f
+             binop(Iop_AndV128,
Mark Wielaard 1b2d1f
+                   binop(Iop_AndV128, mkexpr(v0), mkexpr(v1)),
Mark Wielaard 1b2d1f
+                   binop(Iop_AndV128, mkexpr(v2), mkexpr(v3))));
Mark Wielaard 1b2d1f
+   }
Mark Wielaard 1b2d1f
+
Mark Wielaard 1b2d1f
+   IRTemp rOnes   = newTemp(Ity_I8);
Mark Wielaard 1b2d1f
+   IRTemp rZeroes = newTemp(Ity_I8);
Mark Wielaard 1b2d1f
 
Mark Wielaard 1b2d1f
-   assign( rZeros, unop(Iop_1Uto8,
Mark Wielaard 1b2d1f
-       binop(Iop_CmpEQ32, mkU32(0xFFFFFFFF),
Mark Wielaard 1b2d1f
-             unop(Iop_Not32,
Mark Wielaard 1b2d1f
-                  unop(Iop_V128to32,
Mark Wielaard 1b2d1f
-                       binop(Iop_OrV128,
Mark Wielaard 1b2d1f
-                             binop(Iop_OrV128, mkexpr(v0), mkexpr(v1)),
Mark Wielaard 1b2d1f
-                             binop(Iop_OrV128, mkexpr(v2), mkexpr(v3))))
Mark Wielaard 1b2d1f
-                  ))) );
Mark Wielaard 1b2d1f
+   if (mode64) {
Mark Wielaard 1b2d1f
+      assign(rZeroes,
Mark Wielaard 1b2d1f
+             unop(Iop_1Uto8,
Mark Wielaard 1b2d1f
+                  binop(Iop_CmpEQ64,
Mark Wielaard 1b2d1f
+                        mkU64(0),
Mark Wielaard 1b2d1f
+                        unop(Iop_V128to64, mkexpr(overlappedOred)))));
Mark Wielaard 1b2d1f
+      assign(rOnes,
Mark Wielaard 1b2d1f
+             unop(Iop_1Uto8,
Mark Wielaard 1b2d1f
+                  binop(Iop_CmpEQ64,
Mark Wielaard 1b2d1f
+                        mkU64(0),
Mark Wielaard 1b2d1f
+                        unop(Iop_Not64,
Mark Wielaard 1b2d1f
+                             unop(Iop_V128to64, mkexpr(overlappedAnded))))));
Mark Wielaard 1b2d1f
+   } else {
Mark Wielaard 1b2d1f
+      assign(rZeroes,
Mark Wielaard 1b2d1f
+             unop(Iop_1Uto8,
Mark Wielaard 1b2d1f
+                  binop(Iop_CmpEQ32,
Mark Wielaard 1b2d1f
+                        mkU32(0),
Mark Wielaard 1b2d1f
+                        unop(Iop_V128to32, mkexpr(overlappedOred)))));
Mark Wielaard 1b2d1f
+      assign(rOnes,
Mark Wielaard 1b2d1f
+             unop(Iop_1Uto8,
Mark Wielaard 1b2d1f
+                  binop(Iop_CmpEQ32,
Mark Wielaard 1b2d1f
+                        mkU32(0),
Mark Wielaard 1b2d1f
+                        unop(Iop_Not32,
Mark Wielaard 1b2d1f
+                             unop(Iop_V128to32, mkexpr(overlappedAnded))))));
Mark Wielaard 1b2d1f
+   }
Mark Wielaard 1b2d1f
+
Mark Wielaard 1b2d1f
+   // rOnes might not be used below.  But iropt will remove it, so there's no
Mark Wielaard 1b2d1f
+   // inefficiency as a result.
Mark Wielaard 1b2d1f
 
Mark Wielaard 1b2d1f
    if (test_all_ones) {
Mark Wielaard 1b2d1f
-      assign( rOnes, unop(Iop_1Uto8,
Mark Wielaard 1b2d1f
-         binop(Iop_CmpEQ32, mkU32(0xFFFFFFFF),
Mark Wielaard 1b2d1f
-               unop(Iop_V128to32,
Mark Wielaard 1b2d1f
-                    binop(Iop_AndV128,
Mark Wielaard 1b2d1f
-                          binop(Iop_AndV128, mkexpr(v0), mkexpr(v1)),
Mark Wielaard 1b2d1f
-                          binop(Iop_AndV128, mkexpr(v2), mkexpr(v3)))
Mark Wielaard 1b2d1f
-                    ))) );
Mark Wielaard 1b2d1f
       putCR321( 6, binop(Iop_Or8,
Mark Wielaard 1b2d1f
                          binop(Iop_Shl8, mkexpr(rOnes),  mkU8(3)),
Mark Wielaard 1b2d1f
-                         binop(Iop_Shl8, mkexpr(rZeros), mkU8(1))) );
Mark Wielaard 1b2d1f
+                         binop(Iop_Shl8, mkexpr(rZeroes), mkU8(1))) );
Mark Wielaard 1b2d1f
    } else {
Mark Wielaard 1b2d1f
-      putCR321( 6, binop(Iop_Shl8, mkexpr(rZeros), mkU8(1)) );
Mark Wielaard 1b2d1f
+      putCR321( 6, binop(Iop_Shl8, mkexpr(rZeroes), mkU8(1)) );
Mark Wielaard 1b2d1f
    }
Mark Wielaard 1b2d1f
    putCR0( 6, mkU8(0) );
Mark Wielaard 1b2d1f
 } 
Mark Wielaard 1b2d1f
diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c
Mark Wielaard 1b2d1f
index c24db91..7f69ee3 100644
Mark Wielaard 1b2d1f
--- a/memcheck/mc_translate.c
Mark Wielaard 1b2d1f
+++ b/memcheck/mc_translate.c
Mark Wielaard 1b2d1f
@@ -8322,6 +8322,9 @@ IRSB* MC_(instrument) ( VgCallbackClosure* closure,
Mark Wielaard 1b2d1f
 #     elif defined(VGA_amd64)
Mark Wielaard 1b2d1f
       mce.dlbo.dl_Add64           = DLauto;
Mark Wielaard 1b2d1f
       mce.dlbo.dl_CmpEQ32_CmpNE32 = DLexpensive;
Mark Wielaard 1b2d1f
+#     elif defined(VGA_ppc64le)
Mark Wielaard 1b2d1f
+      // Needed by (at least) set_AV_CR6() in the front end.
Mark Wielaard 1b2d1f
+      mce.dlbo.dl_CmpEQ64_CmpNE64 = DLexpensive;
Mark Wielaard 1b2d1f
 #     endif
Mark Wielaard 1b2d1f
 
Mark Wielaard 1b2d1f
       /* preInstrumentationAnalysis() will allocate &mce.tmpHowUsed and then