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) {