{
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);
}
}
+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");
- }
}
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
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;