s390_amode_get_reg_usage(u, insn->variant.mzero.dst);
break;
+ case S390_INSN_MADD:
+ s390_amode_get_reg_usage(u, insn->variant.madd.dst);
+ break;
+
case S390_INSN_MFENCE:
- case S390_INSN_GADD:
break;
case S390_INSN_SET_FPC_BFPRM:
s390_amode_map_regs(m, insn->variant.mzero.dst);
break;
+ case S390_INSN_MADD:
+ s390_amode_map_regs(m, insn->variant.madd.dst);
+ break;
+
case S390_INSN_MFENCE:
- case S390_INSN_GADD:
break;
case S390_INSN_SET_FPC_BFPRM:
s390_insn *
-s390_insn_gadd(UChar size, UInt offset, UChar delta, ULong value)
+s390_insn_madd(UChar size, s390_amode *dst, UChar delta, ULong value)
{
s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
- insn->tag = S390_INSN_GADD;
+ vassert(size == 4 || size == 8);
+
+ /* This insn will be mapped to an ASI or AGSI so we can only allow base
+ register plus 12-bit / 20-bit displacement. */
+ vassert(dst->tag == S390_AMODE_B12 || dst->tag == S390_AMODE_B20);
+
+ insn->tag = S390_INSN_MADD;
insn->size = size;
- insn->variant.gadd.offset = offset;
- insn->variant.gadd.delta = delta;
- insn->variant.gadd.value = value;
+ insn->variant.madd.dst = dst;
+ insn->variant.madd.delta = delta;
+ insn->variant.madd.value = value;
return insn;
}
s390_sprintf(buf, "%M %A", "v-mzero", insn->variant.mzero.dst);
break;
- case S390_INSN_GADD:
- s390_sprintf(buf, "%M %G += %I (= %I)", "v-gadd",
- insn->variant.gadd.offset,
- (Long)(Char)insn->variant.gadd.delta,
- insn->variant.gadd.value);
+ case S390_INSN_MADD:
+ s390_sprintf(buf, "%M %A += %I (= %I)", "v-madd",
+ insn->variant.madd.dst,
+ (Long)(Char)insn->variant.madd.delta,
+ insn->variant.madd.value);
break;
case S390_INSN_SET_FPC_BFPRM:
static UChar *
-s390_insn_gadd_emit(UChar *buf, const s390_insn *insn)
+s390_insn_madd_emit(UChar *buf, const s390_insn *insn)
{
- return s390_emit_AGSI(buf, insn->variant.gadd.delta,
- S390_REGNO_GUEST_STATE_POINTER,
- DISP20(insn->variant.gadd.offset));
+ s390_amode *am = insn->variant.madd.dst;
+
+ if (insn->size == 4) {
+ return s390_emit_ASI(buf, insn->variant.madd.delta, am->b,
+ DISP20(am->d));
+ }
+
+ return s390_emit_AGSI(buf, insn->variant.madd.delta, am->b, DISP20(am->d));
}
end = s390_insn_mzero_emit(buf, insn);
break;
- case S390_INSN_GADD:
- end = s390_insn_gadd_emit(buf, insn);
+ case S390_INSN_MADD:
+ end = s390_insn_madd_emit(buf, insn);
break;
case S390_INSN_SET_FPC_BFPRM:
S390_INSN_DFP_CONVERT,
S390_INSN_MFENCE,
S390_INSN_MZERO, /* Assign zero to a memory location */
- S390_INSN_GADD, /* Add a value to a guest register */
+ S390_INSN_MADD, /* Add a value to a memory location */
S390_INSN_SET_FPC_BFPRM, /* Set the bfp rounding mode in the FPC */
S390_INSN_SET_FPC_DFPRM, /* Set the dfp rounding mode in the FPC */
/* The following 5 insns are mandated by translation chaining */
s390_amode *dst;
} mzero;
struct {
- UInt offset;
+ s390_amode *dst;
UChar delta;
ULong value; /* for debugging only */
- } gadd;
+ } madd;
struct {
HReg mode;
} set_fpc_bfprm;
s390_dfp_round_t);
s390_insn *s390_insn_mfence(void);
s390_insn *s390_insn_mzero(UChar size, s390_amode *dst);
-s390_insn *s390_insn_gadd(UChar size, UInt offset, UChar delta, ULong value);
+s390_insn *s390_insn_madd(UChar size, s390_amode *dst, UChar delta,
+ ULong value);
s390_insn *s390_insn_set_fpc_bfprm(UChar size, HReg mode);
s390_insn *s390_insn_set_fpc_dfprm(UChar size, HReg mode);
case Ity_I16:
case Ity_I32:
case Ity_I64:
+ /* fixs390: We could check for INSN_MADD here. */
if (am->tag == S390_AMODE_B12 &&
s390_expr_is_const_zero(stmt->Ist.Store.data)) {
addInstr(env, s390_insn_mzero(sizeofIRType(tyd), am));
difference = new_value - old_value;
if (s390_host_has_gie && ulong_fits_signed_8bit(difference)) {
- addInstr(env, s390_insn_gadd(sizeofIRType(tyd), offset,
+ am = s390_amode_for_guest_state(offset);
+ addInstr(env, s390_insn_madd(sizeofIRType(tyd), am,
(difference & 0xFF), new_value));
return;
}
Use R0 as a scratch reg. */
if ((old_value >> 32) == (new_value >> 32)) {
HReg r0 = make_gpr(0);
- HReg gsp = make_gpr(S390_REGNO_GUEST_STATE_POINTER);
- s390_amode *gam;
- gam = s390_amode_b12(offset + 4, gsp);
+ am = s390_amode_for_guest_state(offset + 4);
addInstr(env, s390_insn_load_immediate(4, r0,
new_value & 0xFFFFFFFF));
- addInstr(env, s390_insn_store(4, gam, r0));
+ addInstr(env, s390_insn_store(4, am, r0));
return;
}