diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-12-27 14:56:47 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-12-27 14:56:47 +0000 |
commit | e5fdf663cf01f824f0e29701551a2c29554d80a4 (patch) | |
tree | 2f9281a43bc583f588f27bff3c5a739a7c791d56 | |
parent | a470b33259bf82ef2336bfcd5d07640562d3f63b (diff) | |
parent | e45d4ef6e345831c8d67a5bffe0d057efc20f4ff (diff) |
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20161223' into staging
queued s390 host fixes
# gpg: Signature made Sat 24 Dec 2016 03:41:40 GMT
# gpg: using RSA key 0xAD1270CC4DD0279B
# gpg: Good signature from "Richard Henderson <rth7680@gmail.com>"
# gpg: aka "Richard Henderson <rth@redhat.com>"
# gpg: aka "Richard Henderson <rth@twiddle.net>"
# Primary key fingerprint: 9CB1 8DDA F8E8 49AD 2AFC 16A4 AD12 70CC 4DD0 279B
* remotes/rth/tags/pull-tcg-20161223:
tcg/s390: Remove 'R' constraint
tcg/s390: Fix setcond expansion
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | tcg/s390/tcg-target.inc.c | 75 |
1 files changed, 40 insertions, 35 deletions
diff --git a/tcg/s390/tcg-target.inc.c b/tcg/s390/tcg-target.inc.c index 253d4a0a0b..8d5d2bd300 100644 --- a/tcg/s390/tcg-target.inc.c +++ b/tcg/s390/tcg-target.inc.c @@ -378,11 +378,6 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) ct->ct |= TCG_CT_REG; tcg_regset_set32(ct->u.regs, 0, 0xffff); break; - case 'R': /* not R0 */ - ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, 0xffff); - tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0); - break; case 'L': /* qemu_ld/st constraint */ ct->ct |= TCG_CT_REG; tcg_regset_set32(ct->u.regs, 0, 0xffff); @@ -1093,33 +1088,43 @@ static void tgen64_xori(TCGContext *s, TCGReg dest, tcg_target_ulong val) } static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1, - TCGArg c2, int c2const) + TCGArg c2, bool c2const, bool need_carry) { bool is_unsigned = is_unsigned_cond(c); if (c2const) { if (c2 == 0) { + if (!(is_unsigned && need_carry)) { + if (type == TCG_TYPE_I32) { + tcg_out_insn(s, RR, LTR, r1, r1); + } else { + tcg_out_insn(s, RRE, LTGR, r1, r1); + } + return tcg_cond_to_ltr_cond[c]; + } + /* If we only got here because of load-and-test, + and we couldn't use that, then we need to load + the constant into a register. */ + if (!(facilities & FACILITY_EXT_IMM)) { + c2 = TCG_TMP0; + tcg_out_movi(s, type, c2, 0); + goto do_reg; + } + } + if (is_unsigned) { if (type == TCG_TYPE_I32) { - tcg_out_insn(s, RR, LTR, r1, r1); + tcg_out_insn(s, RIL, CLFI, r1, c2); } else { - tcg_out_insn(s, RRE, LTGR, r1, r1); + tcg_out_insn(s, RIL, CLGFI, r1, c2); } - return tcg_cond_to_ltr_cond[c]; } else { - if (is_unsigned) { - if (type == TCG_TYPE_I32) { - tcg_out_insn(s, RIL, CLFI, r1, c2); - } else { - tcg_out_insn(s, RIL, CLGFI, r1, c2); - } + if (type == TCG_TYPE_I32) { + tcg_out_insn(s, RIL, CFI, r1, c2); } else { - if (type == TCG_TYPE_I32) { - tcg_out_insn(s, RIL, CFI, r1, c2); - } else { - tcg_out_insn(s, RIL, CGFI, r1, c2); - } + tcg_out_insn(s, RIL, CGFI, r1, c2); } } } else { + do_reg: if (is_unsigned) { if (type == TCG_TYPE_I32) { tcg_out_insn(s, RR, CLR, r1, c2); @@ -1148,7 +1153,7 @@ static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond, do_greater: /* The result of a compare has CC=2 for GT and CC=3 unused. ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit. */ - tgen_cmp(s, type, cond, c1, c2, c2const); + tgen_cmp(s, type, cond, c1, c2, c2const, true); tcg_out_movi(s, type, dest, 0); tcg_out_insn(s, RRE, ALCGR, dest, dest); return; @@ -1219,7 +1224,7 @@ static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond, break; } - cc = tgen_cmp(s, type, cond, c1, c2, c2const); + cc = tgen_cmp(s, type, cond, c1, c2, c2const, false); if (facilities & FACILITY_LOAD_ON_COND) { /* Emit: d = 0, t = 1, d = (cc ? t : d). */ tcg_out_movi(s, TCG_TYPE_I64, dest, 0); @@ -1238,11 +1243,11 @@ static void tgen_movcond(TCGContext *s, TCGType type, TCGCond c, TCGReg dest, { int cc; if (facilities & FACILITY_LOAD_ON_COND) { - cc = tgen_cmp(s, type, c, c1, c2, c2const); + cc = tgen_cmp(s, type, c, c1, c2, c2const, false); tcg_out_insn(s, RRF, LOCGR, dest, r3, cc); } else { c = tcg_invert_cond(c); - cc = tgen_cmp(s, type, c, c1, c2, c2const); + cc = tgen_cmp(s, type, c, c1, c2, c2const, false); /* Emit: if (cc) goto over; dest = r3; over: */ tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1); @@ -1374,7 +1379,7 @@ static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c, } } - cc = tgen_cmp(s, type, c, r1, c2, c2const); + cc = tgen_cmp(s, type, c, r1, c2, c2const, false); tgen_branch(s, cc, l); } @@ -2216,12 +2221,12 @@ static const TCGTargetOpDef s390_op_defs[] = { { INDEX_op_neg_i32, { "r", "r" } }, - { INDEX_op_shl_i32, { "r", "0", "Ri" } }, - { INDEX_op_shr_i32, { "r", "0", "Ri" } }, - { INDEX_op_sar_i32, { "r", "0", "Ri" } }, + { INDEX_op_shl_i32, { "r", "0", "ri" } }, + { INDEX_op_shr_i32, { "r", "0", "ri" } }, + { INDEX_op_sar_i32, { "r", "0", "ri" } }, - { INDEX_op_rotl_i32, { "r", "r", "Ri" } }, - { INDEX_op_rotr_i32, { "r", "r", "Ri" } }, + { INDEX_op_rotl_i32, { "r", "r", "ri" } }, + { INDEX_op_rotr_i32, { "r", "r", "ri" } }, { INDEX_op_ext8s_i32, { "r", "r" } }, { INDEX_op_ext8u_i32, { "r", "r" } }, @@ -2271,12 +2276,12 @@ static const TCGTargetOpDef s390_op_defs[] = { { INDEX_op_neg_i64, { "r", "r" } }, - { INDEX_op_shl_i64, { "r", "r", "Ri" } }, - { INDEX_op_shr_i64, { "r", "r", "Ri" } }, - { INDEX_op_sar_i64, { "r", "r", "Ri" } }, + { INDEX_op_shl_i64, { "r", "r", "ri" } }, + { INDEX_op_shr_i64, { "r", "r", "ri" } }, + { INDEX_op_sar_i64, { "r", "r", "ri" } }, - { INDEX_op_rotl_i64, { "r", "r", "Ri" } }, - { INDEX_op_rotr_i64, { "r", "r", "Ri" } }, + { INDEX_op_rotl_i64, { "r", "r", "ri" } }, + { INDEX_op_rotr_i64, { "r", "r", "ri" } }, { INDEX_op_ext8s_i64, { "r", "r" } }, { INDEX_op_ext8u_i64, { "r", "r" } }, |