From afb67fc0023d4e8b671e503219107ac765955047 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 8 Feb 2018 08:28:43 -0500 Subject: [PATCH] target/arm: Fix aa64 ldp register writeback Backports commit 3e4d91b94ce400326fae0850578d9e9f30a71adb from qemu --- qemu/target-arm/translate-a64.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/qemu/target-arm/translate-a64.c b/qemu/target-arm/translate-a64.c index 6103db58..a984b0e5 100644 --- a/qemu/target-arm/translate-a64.c +++ b/qemu/target-arm/translate-a64.c @@ -1986,29 +1986,34 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn) } else { do_fp_st(s, rt, tcg_addr, size); } - } else { - TCGv_i64 tcg_rt = cpu_reg(s, rt); - if (is_load) { - do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false); - } else { - do_gpr_st(s, tcg_rt, tcg_addr, size); - } - } - tcg_gen_addi_i64(tcg_ctx, tcg_addr, tcg_addr, 1ULL << size); - if (is_vector) { + tcg_gen_addi_i64(tcg_ctx, tcg_addr, tcg_addr, 1 << size); if (is_load) { do_fp_ld(s, rt2, tcg_addr, size); } else { do_fp_st(s, rt2, tcg_addr, size); } } else { + TCGv_i64 tcg_rt = cpu_reg(s, rt); TCGv_i64 tcg_rt2 = cpu_reg(s, rt2); + if (is_load) { + TCGv_i64 tmp = tcg_temp_new_i64(tcg_ctx); + + /* Do not modify tcg_rt before recognizing any exception + * from the second load. + */ + do_gpr_ld(s, tmp, tcg_addr, size, is_signed, false); + tcg_gen_addi_i64(tcg_ctx, tcg_addr, tcg_addr, 1 << size); do_gpr_ld(s, tcg_rt2, tcg_addr, size, is_signed, false); + + tcg_gen_mov_i64(tcg_ctx, tcg_rt, tmp); + tcg_temp_free_i64(tcg_ctx, tmp); } else { + do_gpr_st(s, tcg_rt, tcg_addr, size); + tcg_gen_addi_i64(tcg_ctx, tcg_addr, tcg_addr, 1 << size); do_gpr_st(s, tcg_rt2, tcg_addr, size); } - } +} if (wback) { if (postindex) {