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