Blame valgrind-3.14.0-s390x-fix-reg-alloc-vr-vs-fpr.patch

Mark Wielaard 8e0b80
commit 71002d8a5111d02ce8049c55017a8d948c820e35
Mark Wielaard 8e0b80
Author: Andreas Arnez <arnez@linux.ibm.com>
Mark Wielaard 8e0b80
Date:   Thu Oct 25 13:47:12 2018 +0200
Mark Wielaard 8e0b80
Mark Wielaard 8e0b80
    Bug 400490 s390x: Fix register allocation for VRs vs FPRs
Mark Wielaard 8e0b80
    
Mark Wielaard 8e0b80
    On s390x, if vector registers are available, they are fed to the register
Mark Wielaard 8e0b80
    allocator as if they were separate from the floating-point registers.  But
Mark Wielaard 8e0b80
    in fact the FPRs are embedded in the VRs.  So for instance, if both f3 and
Mark Wielaard 8e0b80
    v3 are allocated and used at the same time, corruption will result.
Mark Wielaard 8e0b80
    
Mark Wielaard 8e0b80
    This is fixed by offering only the non-overlapping VRs, v16 to v31, to the
Mark Wielaard 8e0b80
    register allocator instead.
Mark Wielaard 8e0b80
Mark Wielaard 8e0b80
diff --git a/VEX/priv/host_s390_defs.c b/VEX/priv/host_s390_defs.c
Mark Wielaard 8e0b80
index 6c22ac8..98ac938 100644
Mark Wielaard 8e0b80
--- a/VEX/priv/host_s390_defs.c
Mark Wielaard 8e0b80
+++ b/VEX/priv/host_s390_defs.c
Mark Wielaard 8e0b80
@@ -59,7 +59,6 @@ static UInt s390_tchain_load64_len(void);
Mark Wielaard 8e0b80
 
Mark Wielaard 8e0b80
 /* A mapping from register number to register index */
Mark Wielaard 8e0b80
 static Int gpr_index[16];  // GPR regno -> register index
Mark Wielaard 8e0b80
-static Int fpr_index[16];  // FPR regno -> register index
Mark Wielaard 8e0b80
 static Int vr_index[32];   // VR regno -> register index
Mark Wielaard 8e0b80
 
Mark Wielaard 8e0b80
 HReg
Mark Wielaard 8e0b80
@@ -73,7 +72,7 @@ s390_hreg_gpr(UInt regno)
Mark Wielaard 8e0b80
 HReg
Mark Wielaard 8e0b80
 s390_hreg_fpr(UInt regno)
Mark Wielaard 8e0b80
 {
Mark Wielaard 8e0b80
-   Int ix = fpr_index[regno];
Mark Wielaard 8e0b80
+   Int ix = vr_index[regno];
Mark Wielaard 8e0b80
    vassert(ix >= 0);
Mark Wielaard 8e0b80
    return mkHReg(/*virtual*/False, HRcFlt64, regno, ix);
Mark Wielaard 8e0b80
 }
Mark Wielaard 8e0b80
@@ -463,11 +462,9 @@ getRRegUniverse_S390(void)
Mark Wielaard 8e0b80
 
Mark Wielaard 8e0b80
    RRegUniverse__init(ru);
Mark Wielaard 8e0b80
 
Mark Wielaard 8e0b80
-   /* Assign invalid values to the gpr/fpr/vr_index */
Mark Wielaard 8e0b80
+   /* Assign invalid values to the gpr/vr_index */
Mark Wielaard 8e0b80
    for (UInt i = 0; i < sizeof gpr_index / sizeof gpr_index[0]; ++i)
Mark Wielaard 8e0b80
       gpr_index[i] = -1;
Mark Wielaard 8e0b80
-   for (UInt i = 0; i < sizeof fpr_index / sizeof fpr_index[0]; ++i)
Mark Wielaard 8e0b80
-      fpr_index[i] = -1;
Mark Wielaard 8e0b80
    for (UInt i = 0; i < sizeof vr_index / sizeof vr_index[0]; ++i)
Mark Wielaard 8e0b80
       vr_index[i] = -1;
Mark Wielaard 8e0b80
 
Mark Wielaard 8e0b80
@@ -494,17 +491,17 @@ getRRegUniverse_S390(void)
Mark Wielaard 8e0b80
 
Mark Wielaard 8e0b80
    ru->allocable_start[HRcFlt64] = ru->size;
Mark Wielaard 8e0b80
    for (UInt regno = 8; regno <= 15; ++regno) {
Mark Wielaard 8e0b80
-      fpr_index[regno] = ru->size;
Mark Wielaard 8e0b80
+      vr_index[regno] = ru->size;
Mark Wielaard 8e0b80
       ru->regs[ru->size++] = s390_hreg_fpr(regno);
Mark Wielaard 8e0b80
    }
Mark Wielaard 8e0b80
    for (UInt regno = 0; regno <= 7; ++regno) {
Mark Wielaard 8e0b80
-      fpr_index[regno] = ru->size;
Mark Wielaard 8e0b80
+      vr_index[regno] = ru->size;
Mark Wielaard 8e0b80
       ru->regs[ru->size++] = s390_hreg_fpr(regno);
Mark Wielaard 8e0b80
    }
Mark Wielaard 8e0b80
    ru->allocable_end[HRcFlt64] = ru->size - 1;
Mark Wielaard 8e0b80
 
Mark Wielaard 8e0b80
    ru->allocable_start[HRcVec128] = ru->size;
Mark Wielaard 8e0b80
-   for (UInt regno = 0; regno <= 31; ++regno) {
Mark Wielaard 8e0b80
+   for (UInt regno = 16; regno <= 31; ++regno) {
Mark Wielaard 8e0b80
       vr_index[regno] = ru->size;
Mark Wielaard 8e0b80
       ru->regs[ru->size++] = s390_hreg_vr(regno);
Mark Wielaard 8e0b80
    }
Mark Wielaard 8e0b80
@@ -527,12 +524,12 @@ getRRegUniverse_S390(void)
Mark Wielaard 8e0b80
    /* Sanity checking */
Mark Wielaard 8e0b80
    for (UInt i = 0; i < sizeof gpr_index / sizeof gpr_index[0]; ++i)
Mark Wielaard 8e0b80
       vassert(gpr_index[i] >= 0);
Mark Wielaard 8e0b80
-   for (UInt i = 0; i < sizeof fpr_index / sizeof fpr_index[0]; ++i)
Mark Wielaard 8e0b80
-      vassert(fpr_index[i] >= 0);
Mark Wielaard 8e0b80
    for (UInt i = 0; i < sizeof vr_index / sizeof vr_index[0]; ++i)
Mark Wielaard 8e0b80
       vassert(vr_index[i] >= 0);
Mark Wielaard 8e0b80
                  
Mark Wielaard 8e0b80
    initialised = True;
Mark Wielaard 8e0b80
+
Mark Wielaard 8e0b80
+   RRegUniverse__check_is_sane(ru);
Mark Wielaard 8e0b80
    return ru;
Mark Wielaard 8e0b80
 }
Mark Wielaard 8e0b80