mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-02 14:31:12 +00:00
target/arm: Fix aa64 ldp register writeback
For "ldp x0, x1, [x0]", if the second load is on a second page and the second page is unmapped, the exception would be raised with x0 already modified. This means the instruction couldn't be restarted. Backports commit 2d1bbf51c2cb948da4b6fd5f91cf3ecc80b28156 from qemu
This commit is contained in:
parent
c27870520a
commit
13242af398
|
@ -2242,29 +2242,34 @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
|
||||||
} else {
|
} else {
|
||||||
do_fp_st(s, rt, tcg_addr, size);
|
do_fp_st(s, rt, tcg_addr, size);
|
||||||
}
|
}
|
||||||
} else {
|
tcg_gen_addi_i64(tcg_ctx, tcg_addr, tcg_addr, 1 << size);
|
||||||
TCGv_i64 tcg_rt = cpu_reg(s, rt);
|
|
||||||
if (is_load) {
|
|
||||||
do_gpr_ld(s, tcg_rt, tcg_addr, size, is_signed, false,
|
|
||||||
false, 0, false, false);
|
|
||||||
} else {
|
|
||||||
do_gpr_st(s, tcg_rt, tcg_addr, size,
|
|
||||||
false, 0, false, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tcg_gen_addi_i64(tcg_ctx, tcg_addr, tcg_addr, 1 << size);
|
|
||||||
if (is_vector) {
|
|
||||||
if (is_load) {
|
if (is_load) {
|
||||||
do_fp_ld(s, rt2, tcg_addr, size);
|
do_fp_ld(s, rt2, tcg_addr, size);
|
||||||
} else {
|
} else {
|
||||||
do_fp_st(s, rt2, tcg_addr, size);
|
do_fp_st(s, rt2, tcg_addr, size);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
TCGv_i64 tcg_rt = cpu_reg(s, rt);
|
||||||
TCGv_i64 tcg_rt2 = cpu_reg(s, rt2);
|
TCGv_i64 tcg_rt2 = cpu_reg(s, rt2);
|
||||||
|
|
||||||
if (is_load) {
|
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,
|
||||||
|
false, 0, false, 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,
|
do_gpr_ld(s, tcg_rt2, tcg_addr, size, is_signed, false,
|
||||||
false, 0, false, false);
|
false, 0, false, false);
|
||||||
|
|
||||||
|
tcg_gen_mov_i64(tcg_ctx, tcg_rt, tmp);
|
||||||
|
tcg_temp_free_i64(tcg_ctx, tmp);
|
||||||
} else {
|
} else {
|
||||||
|
do_gpr_st(s, tcg_rt, tcg_addr, size,
|
||||||
|
false, 0, false, false);
|
||||||
|
tcg_gen_addi_i64(tcg_ctx, tcg_addr, tcg_addr, 1 << size);
|
||||||
do_gpr_st(s, tcg_rt2, tcg_addr, size,
|
do_gpr_st(s, tcg_rt2, tcg_addr, size,
|
||||||
false, 0, false, false);
|
false, 0, false, false);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue