]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Powerpc 32bit, fix the vbpermq support
authorCarl Love <cel@us.ibm.com>
Tue, 5 Apr 2022 01:31:33 +0000 (21:31 -0400)
committerCarl Love <cel@us.ibm.com>
Tue, 5 Apr 2022 01:45:50 +0000 (01:45 +0000)
Passing the two 128-bit vA and vB arguments doesn't work in 32-bit mode.
The clean helper was changed to compute the result for 8 indexes.  The
helper is then called twice to get the result for the upper 64-bits of the
vB register and the lower 64-bits of the vB register.

The patch is an additional fix for bugzilla 451827.

VEX/priv/guest_ppc_defs.h
VEX/priv/guest_ppc_helpers.c
VEX/priv/guest_ppc_toIR.c

index e79b86cd76ca8d7d3b4428740527f1a90c3c7c25..220fbf1395ec364fdc991dbb2c66fd2029a59ae0 100644 (file)
@@ -164,8 +164,7 @@ extern UInt count_bits_under_mask_helper( ULong src, ULong mask,
                                           UInt flag );
 extern ULong deposit_bits_under_mask_helper( ULong src, ULong mask );
 extern ULong population_count64_helper( ULong src );
-extern ULong vbpermq_clean_helper( ULong vA_high, ULong vA_low,
-                                   ULong vB_high, ULong vB_low );
+extern UInt vbpermq_clean_helper( ULong vA_high, ULong vA_low, ULong vB);
 extern ULong vector_evaluate64_helper( ULong srcA, ULong srcB, ULong srcC,
                                        ULong IMM );
 void write_ACC_entry (VexGuestPPC64State* gst, UInt offset, UInt acc,
index a6f63f5d26f425338f9bc7be33dd18c7ac49470b..2914667514684bcdb9e5df3099fbe03cf976359a 100644 (file)
@@ -704,17 +704,13 @@ ULong vector_evaluate64_helper( ULong srcA, ULong srcB, ULong srcC,
 /*---------------------------------------------------------------*/
 /* --- Clean helper for vbpermq instruction                   ---*/
 /*---------------------------------------------------------------*/
-ULong vbpermq_clean_helper( ULong vA_high, ULong vA_low,
-                            ULong vB_high, ULong vB_low) {
+UInt vbpermq_clean_helper( ULong vA_high, ULong vA_low, ULong vB) {
    ULong bit, result = 0x0;
    UInt i, index;
 
    /* IBM numbering bit 0 on is MSB, bit 63 is LSB */
-   for ( i = 0; i < 16; i++) {
-      if (i < 8)
-         index = 0xFFULL & (vB_high >> (56 - 8*i) );
-      else
-         index = 0xFFULL & (vB_low  >> (56 - 8*(i-8)));
+   for ( i = 0; i < 8; i++) {
+      index = 0xFFULL & (vB >> (56 - 8*i) );
 
       if (index < 64) {
          bit = 0x1 & (vA_high >> (63 - index));
@@ -725,7 +721,7 @@ ULong vbpermq_clean_helper( ULong vA_high, ULong vA_low,
       } else
          bit = 0;
 
-      result |= bit << (15 - i);
+      result |= bit << (7 - i);
    }
    return result;
 }
index 94bf79872609e3b433788f73ac8fc10d26c49077..3f813358ae9e94664fb597b8295955a567211b20 100644 (file)
@@ -31830,22 +31830,42 @@ static Bool dis_av_quad ( UInt prefix, UInt theInstr, const VexAbiInfo* vbi )
    {
       /* The original supports was done with Iops but it caused the internal
          temorary storage to be exhausted if there were three or more vbpermq
-         instructions in a row. Changed to a clean helper on 3/24/2022  */
+         instructions in a row. Changed to a clean helper on 3/24/2022.  For
+         Powerpc 32-bit support, passing two 128-bit arguments doesn't work.
+         Hence, the helper is called twice to calculate the result for the
+         upper and lower 64-bit vB register indicies.  */
       IRTemp res_hi = newTemp( Ity_I64 );
+      IRTemp res_0 = newTemp( Ity_I32 );
+      IRTemp res_1 = newTemp( Ity_I32 );
       IRExpr * res_low = mkU64(0);
-      assign( res_hi,
-              mkIRExprCCall( Ity_I64, 0 /*regparms*/,
+      assign( res_0,
+              mkIRExprCCall( Ity_I32, 0 /*regparms*/,
                              "vbpermq_clean_helper",
                              fnptr_to_fnentry( vbi,
                                                &vbpermq_clean_helper ),
-                             mkIRExprVec_4( unop( Iop_V128HIto64,
+                             mkIRExprVec_3( unop( Iop_V128HIto64,
                                                   mkexpr(vA) ),
                                             unop( Iop_V128to64,
                                                   mkexpr(vA) ),
                                             unop( Iop_V128HIto64,
-                                                  mkexpr(vB) ),
+                                                  mkexpr(vB) ) ) ) );
+      assign( res_1,
+              mkIRExprCCall( Ity_I32, 0 /*regparms*/,
+                             "vbpermq_clean_helper",
+                             fnptr_to_fnentry( vbi,
+                                               &vbpermq_clean_helper ),
+                             mkIRExprVec_3( unop( Iop_V128HIto64,
+                                                  mkexpr(vA) ),
+                                            unop( Iop_V128to64,
+                                                  mkexpr(vA) ),
                                             unop( Iop_V128to64,
                                                   mkexpr(vB) ) ) ) );
+      assign( res_hi, binop( Iop_32HLto64,
+                             mkU32( 0 ),
+                             binop( Iop_Or32,
+                                    binop( Iop_Shl32, mkexpr( res_0 ),
+                                           mkU8( 8 ) ),
+                                    mkexpr( res_1 ) ) ) );
 
       putVReg( vRT_addr, binop( Iop_64HLtoV128, mkexpr( res_hi ), res_low ) );
       return True;