From: Andreas Arnez Date: Tue, 23 Mar 2021 13:55:09 +0000 (+0100) Subject: s390x: Improve handling of amodes without base register X-Git-Tag: VALGRIND_3_18_0~125 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a0bb049ace14ab52d386bb1d49a399f39eec4986;p=thirdparty%2Fvalgrind.git s390x: Improve handling of amodes without base register 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. --- diff --git a/VEX/priv/host_s390_defs.c b/VEX/priv/host_s390_defs.c index 6e0734ae0a..2587f81a18 100644 --- a/VEX/priv/host_s390_defs.c +++ b/VEX/priv/host_s390_defs.c @@ -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 , */ + 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- , */ if (insn->tag == S390_INSN_UNOP && insn->variant.unop.src.tag == S390_OPND_REG diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c index 5f79280c04..ceca6836e5 100644 --- a/VEX/priv/host_s390_isel.c +++ b/VEX/priv/host_s390_isel.c @@ -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;