@@ -35,6 +35,7 @@
#define TCG_CT_CONST_S32 0x100
#define TCG_CT_CONST_N32 0x200
+#define TCG_CT_CONST_MULI 0x400
#define TCG_TMP0 TCG_REG_R14
@@ -344,6 +345,10 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
ct->ct &= ~TCG_CT_REG;
ct->ct |= TCG_CT_CONST_N32;
break;
+ case 'K':
+ ct->ct &= ~TCG_CT_REG;
+ ct->ct |= TCG_CT_CONST_MULI;
+ break;
default:
break;
}
@@ -365,6 +370,16 @@ static inline int tcg_target_const_match(tcg_target_long val,
return val == (int32_t)val;
} else if (ct & TCG_CT_CONST_N32) {
return -val == (int32_t)-val;
+ } else if (ct & TCG_CT_CONST_MULI) {
+ /* Immediates that may be used with multiply. If we have the
+ general-instruction-extensions, then we have MULTIPLY SINGLE
+ IMMEDIATE with a signed 32-bit, otherwise we have only
+ MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
+ if (facilities & FACILITY_GEN_INST_EXT) {
+ return val == (int32_t)val;
+ } else {
+ return val == (int16_t)val;
+ }
}
return 0;
@@ -559,18 +574,21 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
static void tcg_out_ld_abs(TCGContext *s, TCGType type, TCGReg dest, void *abs)
{
tcg_target_long addr = (tcg_target_long)abs;
- tcg_target_long disp = (addr - (tcg_target_long)s->code_ptr) >> 1;
- if (disp == (int32_t)disp) {
- if (type == TCG_TYPE_I32) {
- tcg_out_insn(s, RIL, LRL, dest, disp);
- } else {
- tcg_out_insn(s, RIL, LGRL, dest, disp);
+ if (facilities & FACILITY_GEN_INST_EXT) {
+ tcg_target_long disp = (addr - (tcg_target_long)s->code_ptr) >> 1;
+ if (disp == (int32_t)disp) {
+ if (type == TCG_TYPE_I32) {
+ tcg_out_insn(s, RIL, LRL, dest, disp);
+ } else {
+ tcg_out_insn(s, RIL, LGRL, dest, disp);
+ }
+ return;
}
- } else {
- tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
- tcg_out_ld(s, type, dest, dest, addr & 0xffff);
}
+
+ tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
+ tcg_out_ld(s, type, dest, dest, addr & 0xffff);
}
static inline void tgen_ext8s(TCGContext *s, TCGReg dest, TCGReg src)
@@ -1322,7 +1340,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_mul_i32:
if (const_args[2]) {
- if (args[2] == (int16_t)args[2]) {
+ if ((int32_t)args[2] == (int16_t)args[2]) {
tcg_out_insn(s, RI, MHI, args[0], args[2]);
} else {
tcg_out_insn(s, RIL, MSFI, args[0], args[2]);
@@ -1573,7 +1591,7 @@ static const TCGTargetOpDef s390_op_defs[] = {
{ INDEX_op_add_i32, { "r", "0", "ri" } },
{ INDEX_op_sub_i32, { "r", "0", "ri" } },
- { INDEX_op_mul_i32, { "r", "0", "ri" } },
+ { INDEX_op_mul_i32, { "r", "0", "rK" } },
{ INDEX_op_div2_i32, { "b", "a", "0", "1", "r" } },
{ INDEX_op_divu2_i32, { "b", "a", "0", "1", "r" } },
@@ -1634,7 +1652,7 @@ static const TCGTargetOpDef s390_op_defs[] = {
{ INDEX_op_add_i64, { "r", "0", "rI" } },
{ INDEX_op_sub_i64, { "r", "0", "rJ" } },
- { INDEX_op_mul_i64, { "r", "0", "rI" } },
+ { INDEX_op_mul_i64, { "r", "0", "rK" } },
{ INDEX_op_div2_i64, { "b", "a", "0", "1", "r" } },
{ INDEX_op_divu2_i64, { "b", "a", "0", "1", "r" } },
@@ -1752,9 +1770,7 @@ static void query_facilities(void)
sigaction(SIGILL, &sa_old, NULL);
- /* ??? The translator currently uses all of these extensions
- unconditionally. This list could be pruned back to just
- z/Arch and long displacement with some work. */
+ /* The translator currently uses these extensions unconditionally. */
fail = 0;
if ((facilities & FACILITY_ZARCH_ACTIVE) == 0) {
fprintf(stderr, "TCG: z/Arch facility is required\n");
@@ -1768,11 +1784,6 @@ static void query_facilities(void)
fprintf(stderr, "TCG: extended-immediate facility is required\n");
fail = 1;
}
- if ((facilities & FACILITY_GEN_INST_EXT) == 0) {
- fprintf(stderr, "TCG: general-instructions-extension "
- "facility is required\n");
- fail = 1;
- }
if (fail) {
exit(-1);
}
The LOAD RELATIVE and MULTIPLY SINGLE IMMEDIATE instructions are currently the only insns from that extension. It's easy enough to test for that facility and avoid emitting them. Signed-off-by: Richard Henderson <rth@twiddle.net> --- tcg/s390/tcg-target.c | 51 +++++++++++++++++++++++++++++------------------- 1 files changed, 31 insertions(+), 20 deletions(-)