]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390x: Improve handling of amodes without base register
authorAndreas Arnez <arnez@linux.ibm.com>
Tue, 23 Mar 2021 13:55:09 +0000 (14:55 +0100)
committerAndreas Arnez <arnez@linux.ibm.com>
Fri, 7 May 2021 15:17:09 +0000 (17:17 +0200)
Addressing modes without a base or index register represent constants.
They can occur in some special cases such as shift operations and when
accessing individual vector elements.  Perform some minor improvements to
the handling of such amodes.

VEX/priv/host_s390_defs.c
VEX/priv/host_s390_isel.c

index 6e0734ae0a260a8c6389a3c13c00427bc857292b..2587f81a184580c6fe43e2864e9a14c267274231 100644 (file)
@@ -360,7 +360,8 @@ s390_amode_is_sane(const s390_amode *am)
 {
    switch (am->tag) {
    case S390_AMODE_B12:
-      return is_virtual_gpr(am->b) && fits_unsigned_12bit(am->d);
+      return (is_virtual_gpr(am->b) || sameHReg(am->b, s390_hreg_gpr(0))) &&
+             fits_unsigned_12bit(am->d);
 
    case S390_AMODE_B20:
       return is_virtual_gpr(am->b) && fits_signed_20bit(am->d);
@@ -378,47 +379,31 @@ s390_amode_is_sane(const s390_amode *am)
    }
 }
 
+static Bool
+s390_amode_is_constant(const s390_amode *am)
+{
+   return am->tag == S390_AMODE_B12 && sameHReg(am->b, s390_hreg_gpr(0));
+}
+
 
 /* Record the register use of an amode */
 static void
 s390_amode_get_reg_usage(HRegUsage *u, const s390_amode *am)
 {
-   switch (am->tag) {
-   case S390_AMODE_B12:
-   case S390_AMODE_B20:
-      addHRegUse(u, HRmRead, am->b);
-      return;
-
-   case S390_AMODE_BX12:
-   case S390_AMODE_BX20:
+   if (!sameHReg(am->b, s390_hreg_gpr(0)))
       addHRegUse(u, HRmRead, am->b);
+   if (!sameHReg(am->x, s390_hreg_gpr(0)))
       addHRegUse(u, HRmRead, am->x);
-      return;
-
-   default:
-      vpanic("s390_amode_get_reg_usage");
-   }
 }
 
 
 static void
 s390_amode_map_regs(HRegRemap *m, s390_amode *am)
 {
-   switch (am->tag) {
-   case S390_AMODE_B12:
-   case S390_AMODE_B20:
-      am->b = lookupHRegRemap(m, am->b);
-      return;
-
-   case S390_AMODE_BX12:
-   case S390_AMODE_BX20:
+   if (!sameHReg(am->b, s390_hreg_gpr(0)))
       am->b = lookupHRegRemap(m, am->b);
+   if (!sameHReg(am->x, s390_hreg_gpr(0)))
       am->x = lookupHRegRemap(m, am->x);
-      return;
-
-   default:
-      vpanic("s390_amode_map_regs");
-   }
 }
 
 
@@ -653,6 +638,16 @@ directReload_S390(HInstr* i, HReg vreg, Short spill_off)
                            insn->variant.alu.dst, vreg_opnd);
    }
 
+   /* v-vgetelem <reg>,<vreg> */
+   if (insn->tag == S390_INSN_VEC_AMODEOP
+       && insn->variant.vec_amodeop.tag == S390_VEC_GET_ELEM
+       && insn->size == 8
+       && sameHReg(insn->variant.vec_amodeop.op1, vreg)
+       && s390_amode_is_constant(insn->variant.vec_amodeop.op2)) {
+      vreg_am->d += 8 * insn->variant.vec_amodeop.op2->d;
+      return s390_insn_load(insn->size, insn->variant.vec_amodeop.dst, vreg_am);
+   }
+
    /* v-<unop> <reg>,<vreg> */
    if (insn->tag == S390_INSN_UNOP
        && insn->variant.unop.src.tag == S390_OPND_REG
index 5f79280c04233b3579b0ec6926d6f1adb937eea9..ceca6836e5c537d3076833691f3f686795e5ecd7 100644 (file)
@@ -312,7 +312,18 @@ s390_isel_amode_wrk(ISelEnv *env, IRExpr *expr,
                     Bool no_index __attribute__((unused)),
                     Bool short_displacement)
 {
-   if (expr->tag == Iex_Binop && expr->Iex.Binop.op == Iop_Add64) {
+   if (expr->tag == Iex_Unop && expr->Iex.Unop.op == Iop_8Uto64 &&
+       expr->Iex.Unop.arg->tag == Iex_Const) {
+      UChar value = expr->Iex.Unop.arg->Iex.Const.con->Ico.U8;
+      return s390_amode_b12((Int)value, s390_hreg_gpr(0));
+
+   } else if (expr->tag == Iex_Const) {
+      ULong value = expr->Iex.Const.con->Ico.U64;
+      if (ulong_fits_unsigned_12bit(value)) {
+         return s390_amode_b12((Int)value, s390_hreg_gpr(0));
+      }
+
+   } else if (expr->tag == Iex_Binop && expr->Iex.Binop.op == Iop_Add64) {
       IRExpr *arg1 = expr->Iex.Binop.arg1;
       IRExpr *arg2 = expr->Iex.Binop.arg2;