diff options
author | Richard Henderson <rth@twiddle.net> | 2017-06-05 12:12:59 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2017-06-19 11:10:59 -0700 |
commit | cc74d332ff9a78684374847375ef63fc4bd10436 (patch) | |
tree | 156d936740ff1674439c5b1533db5fb99c91eed4 /tcg/aarch64 | |
parent | 2b48e10f888059a98043b4816769fa2a326a1d2c (diff) |
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.
Tested-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'tcg/aarch64')
-rw-r--r-- | tcg/aarch64/tcg-target.inc.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c index 5f185458f1..1fa3bccc89 100644 --- a/tcg/aarch64/tcg-target.inc.c +++ b/tcg/aarch64/tcg-target.inc.c @@ -616,7 +616,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) { |