tcg/aarch64: Fix tcg_out_qemu_{ld, st} for guest_base == 0

In ffc6372851d8631a9f9fa56ec613b3244dc635b9, we swapped the guest
base to the address base register from the address index register.
Except that 31 in the base slot is SP not XZR, so we need to be
more intelligent about which reg gets placed in which slot.

Backports commit 352bcb0a2b816ff9ab9d75d0f2384650d9e9ab19 from qemu
This commit is contained in:
Richard Henderson 2018-02-10 23:33:02 -05:00 committed by Lioncash
parent 7d57c2e4ce
commit 352f93a119
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -56,6 +56,11 @@ static const int tcg_target_call_oarg_regs[1] = {
#define TCG_REG_TMP TCG_REG_X30 #define TCG_REG_TMP TCG_REG_X30
#ifndef CONFIG_SOFTMMU #ifndef CONFIG_SOFTMMU
/* Note that XZR cannot be encoded in the address base register slot,
as that actaully encodes SP. So if we need to zero-extend the guest
address, via the address index register slot, we need to load even
a zero guest base into a register. */
#define USE_GUEST_BASE (guest_base != 0 || TARGET_LONG_BITS == 32)
# ifdef CONFIG_USE_GUEST_BASE # ifdef CONFIG_USE_GUEST_BASE
# define TCG_REG_GUEST_BASE TCG_REG_X28 # define TCG_REG_GUEST_BASE TCG_REG_X28
# else # else
@ -1228,9 +1233,13 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg,
add_qemu_ldst_label(s, true, oi, ext, data_reg, addr_reg, add_qemu_ldst_label(s, true, oi, ext, data_reg, addr_reg,
s->code_ptr, label_ptr); s->code_ptr, label_ptr);
#else /* !CONFIG_SOFTMMU */ #else /* !CONFIG_SOFTMMU */
tcg_out_qemu_ld_direct(s, memop, ext, data_reg, if (USE_GUEST_BASE) {
GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR, tcg_out_qemu_ld_direct(s, memop, ext, data_reg,
otype, addr_reg); TCG_REG_GUEST_BASE, otype, addr_reg);
} else {
tcg_out_qemu_ld_direct(s, memop, ext, data_reg,
addr_reg, TCG_TYPE_I64, TCG_REG_XZR);
}
#endif /* CONFIG_SOFTMMU */ #endif /* CONFIG_SOFTMMU */
} }
@ -1249,9 +1258,13 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg,
add_qemu_ldst_label(s, false, oi, (memop & MO_SIZE)== MO_64, add_qemu_ldst_label(s, false, oi, (memop & MO_SIZE)== MO_64,
data_reg, addr_reg, s->code_ptr, label_ptr); data_reg, addr_reg, s->code_ptr, label_ptr);
#else /* !CONFIG_SOFTMMU */ #else /* !CONFIG_SOFTMMU */
tcg_out_qemu_st_direct(s, memop, data_reg, if (USE_GUEST_BASE) {
GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR, tcg_out_qemu_st_direct(s, memop, data_reg,
otype, addr_reg); TCG_REG_GUEST_BASE, otype, addr_reg);
} else {
tcg_out_qemu_st_direct(s, memop, data_reg,
addr_reg, TCG_TYPE_I64, TCG_REG_XZR);
}
#endif /* CONFIG_SOFTMMU */ #endif /* CONFIG_SOFTMMU */
} }