From 9a85cb0a26a443eb268e9117ed89b58d27ba2dc3 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 3 Mar 2018 17:09:33 -0500 Subject: [PATCH] tcg/aarch64: Use ADR in tcg_out_movi The new placement of the TB means that we can use one insn to load the return value for exit_tb returning the TB pointer. Backports commit cc74d332ff9a78684374847375ef63fc4bd10436 from qemu --- qemu/tcg/aarch64/tcg-target.inc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qemu/tcg/aarch64/tcg-target.inc.c b/qemu/tcg/aarch64/tcg-target.inc.c index a62d1fc3..33453671 100644 --- a/qemu/tcg/aarch64/tcg-target.inc.c +++ b/qemu/tcg/aarch64/tcg-target.inc.c @@ -620,7 +620,12 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, /* Look for host pointer values within 4G of the PC. This happens often when loading pointers to QEMU's own data structures. */ if (type == TCG_TYPE_I64) { - tcg_target_long disp = (value >> 12) - ((intptr_t)s->code_ptr >> 12); + tcg_target_long disp = value - (intptr_t)s->code_ptr; + if (disp == sextract64(disp, 0, 21)) { + tcg_out_insn(s, 3406, ADR, rd, disp); + return; + } + disp = (value >> 12) - ((intptr_t)s->code_ptr >> 12); if (disp == sextract64(disp, 0, 21)) { tcg_out_insn(s, 3406, ADRP, rd, disp); if (value & 0xfff) {