Generalise S390_INSN_GZERO which only worked on the guest
state to S390_INSN_MZERO which works for any memory location
addressable with base reg + 12-bit displacement.
git-svn-id: svn://svn.valgrind.org/vex/trunk@2587 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/host_s390_defs.c b/priv/host_s390_defs.c
index ef79095..91a201f 100644
--- a/priv/host_s390_defs.c
+++ b/priv/host_s390_defs.c
@@ -714,8 +714,11 @@
}
break;
+ case S390_INSN_MZERO:
+ s390_amode_get_reg_usage(u, insn->variant.mzero.dst);
+ break;
+
case S390_INSN_MFENCE:
- case S390_INSN_GZERO:
case S390_INSN_GADD:
break;
@@ -963,8 +966,11 @@
}
break;
+ case S390_INSN_MZERO:
+ s390_amode_map_regs(m, insn->variant.mzero.dst);
+ break;
+
case S390_INSN_MFENCE:
- case S390_INSN_GZERO:
case S390_INSN_GADD:
break;
@@ -5078,13 +5084,17 @@
s390_insn *
-s390_insn_gzero(UChar size, UInt offset)
+s390_insn_mzero(UChar size, s390_amode *dst)
{
s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn));
- insn->tag = S390_INSN_GZERO;
+ /* This insn will be mapped to an XC so we can only allow base register
+ plus 12-bit displacement */
+ vassert(dst->tag == S390_AMODE_B12);
+
+ insn->tag = S390_INSN_MZERO;
insn->size = size;
- insn->variant.gzero.offset = offset;
+ insn->variant.mzero.dst = dst;
return insn;
}
@@ -5643,8 +5653,8 @@
s390_sprintf(buf, "%M", "v-mfence");
return buf; /* avoid printing "size = ..." which is meaningless */
- case S390_INSN_GZERO:
- s390_sprintf(buf, "%M %G", "v-gzero", insn->variant.gzero.offset);
+ case S390_INSN_MZERO:
+ s390_sprintf(buf, "%M %A", "v-mzero", insn->variant.mzero.dst);
break;
case S390_INSN_GADD:
@@ -7788,11 +7798,11 @@
static UChar *
-s390_insn_gzero_emit(UChar *buf, const s390_insn *insn)
+s390_insn_mzero_emit(UChar *buf, const s390_insn *insn)
{
- return s390_emit_XC(buf, insn->size - 1,
- S390_REGNO_GUEST_STATE_POINTER, insn->variant.gzero.offset,
- S390_REGNO_GUEST_STATE_POINTER, insn->variant.gzero.offset);
+ s390_amode *am = insn->variant.mzero.dst;
+
+ return s390_emit_XC(buf, insn->size - 1, am->b, am->d, am->b, am->d);
}
@@ -8377,8 +8387,8 @@
end = s390_insn_mfence_emit(buf, insn);
break;
- case S390_INSN_GZERO:
- end = s390_insn_gzero_emit(buf, insn);
+ case S390_INSN_MZERO:
+ end = s390_insn_mzero_emit(buf, insn);
break;
case S390_INSN_GADD:
diff --git a/priv/host_s390_defs.h b/priv/host_s390_defs.h
index 2a24d5c..2e93b2f 100644
--- a/priv/host_s390_defs.h
+++ b/priv/host_s390_defs.h
@@ -139,7 +139,7 @@
S390_INSN_BFP_CONVERT,
S390_INSN_DFP_BINOP, /* Decimal floating point */
S390_INSN_MFENCE,
- S390_INSN_GZERO, /* Assign zero to a guest register */
+ S390_INSN_MZERO, /* Assign zero to a memory location */
S390_INSN_GADD, /* Add a value to a guest register */
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 */
@@ -510,8 +510,8 @@
/* Miscellaneous */
struct {
- UInt offset;
- } gzero;
+ s390_amode *dst;
+ } mzero;
struct {
UInt offset;
UChar delta;
@@ -616,7 +616,7 @@
HReg op2, HReg op3,
s390_dfp_round_t rounding_mode);
s390_insn *s390_insn_mfence(void);
-s390_insn *s390_insn_gzero(UChar size, UInt offset);
+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_set_fpc_bfprm(UChar size, HReg mode);
s390_insn *s390_insn_set_fpc_dfprm(UChar size, HReg mode);
diff --git a/priv/host_s390_isel.c b/priv/host_s390_isel.c
index f5010a4..0289baf 100644
--- a/priv/host_s390_isel.c
+++ b/priv/host_s390_isel.c
@@ -2564,6 +2564,11 @@
case Ity_I16:
case Ity_I32:
case Ity_I64:
+ if (am->tag == S390_AMODE_B12 &&
+ s390_expr_is_const_zero(stmt->Ist.Store.data)) {
+ addInstr(env, s390_insn_mzero(sizeofIRType(tyd), am));
+ return;
+ }
src = s390_isel_int_expr(env, stmt->Ist.Store.data);
break;
@@ -2649,7 +2654,8 @@
/* guest register = 0 */
if (new_value == 0) {
- addInstr(env, s390_insn_gzero(sizeofIRType(tyd), offset));
+ am = s390_amode_for_guest_state(offset);
+ addInstr(env, s390_insn_mzero(sizeofIRType(tyd), am));
return;
}
@@ -2689,6 +2695,11 @@
case Ity_I16:
case Ity_I32:
case Ity_I64:
+ if (am->tag == S390_AMODE_B12 &&
+ s390_expr_is_const_zero(stmt->Ist.Put.data)) {
+ addInstr(env, s390_insn_mzero(sizeofIRType(tyd), am));
+ return;
+ }
src = s390_isel_int_expr(env, stmt->Ist.Put.data);
break;