aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2025-01-18 13:26:43 -0800
committerRichard Henderson <richard.henderson@linaro.org>2025-04-28 13:40:17 -0700
commit1b6e25e300e78cf8d8581245c2f8339c5b423d30 (patch)
tree6fdae20648c283d0abaf18dcf3cf1e734cecd234
parent2329da9605b0f1b7bd59f58afb5ab2154d0af137 (diff)
downloadqemu-1b6e25e300e78cf8d8581245c2f8339c5b423d30.zip
qemu-1b6e25e300e78cf8d8581245c2f8339c5b423d30.tar.gz
qemu-1b6e25e300e78cf8d8581245c2f8339c5b423d30.tar.bz2
tcg/s390x: Honor carry_live in tcg_out_movi
Do not clobber flags if they're live. Required in order to perform register allocation on add/sub carry opcodes. LA and AGHI are the same size, so use LA unconditionally. Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r--tcg/s390x/tcg-target.c.inc35
1 files changed, 21 insertions, 14 deletions
diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc
index a30afb4..e262876 100644
--- a/tcg/s390x/tcg-target.c.inc
+++ b/tcg/s390x/tcg-target.c.inc
@@ -951,25 +951,32 @@ static void tcg_out_movi(TCGContext *s, TCGType type,
if (pc_off == (int32_t)pc_off) {
tcg_out_insn(s, RIL, LARL, ret, pc_off);
if (sval & 1) {
- tcg_out_insn(s, RI, AGHI, ret, 1);
+ tcg_out_insn(s, RX, LA, ret, ret, TCG_REG_NONE, 1);
}
return;
}
- /* Otherwise, load it by parts. */
- i = is_const_p16((uint32_t)uval);
- if (i >= 0) {
- tcg_out_insn_RI(s, li_insns[i], ret, uval >> (i * 16));
- } else {
- tcg_out_insn(s, RIL, LLILF, ret, uval);
- }
- uval >>= 32;
- i = is_const_p16(uval);
- if (i >= 0) {
- tcg_out_insn_RI(s, oi_insns[i + 2], ret, uval >> (i * 16));
- } else {
- tcg_out_insn(s, RIL, OIHF, ret, uval);
+ if (!s->carry_live) {
+ /* Load by parts, at most 2 instructions. */
+ i = is_const_p16((uint32_t)uval);
+ if (i >= 0) {
+ tcg_out_insn_RI(s, li_insns[i], ret, uval >> (i * 16));
+ } else {
+ tcg_out_insn(s, RIL, LLILF, ret, uval);
+ }
+ uval >>= 32;
+ i = is_const_p16(uval);
+ if (i >= 0) {
+ tcg_out_insn_RI(s, oi_insns[i + 2], ret, uval >> (i * 16));
+ } else {
+ tcg_out_insn(s, RIL, OIHF, ret, uval);
+ }
+ return;
}
+
+ /* Otherwise, stuff it in the constant pool. */
+ tcg_out_insn(s, RIL, LGRL, ret, 0);
+ new_pool_label(s, sval, R_390_PC32DBL, s->code_ptr - 2, 2);
}
/* Emit a load/store type instruction. Inputs are: