mirror of
https://git.proxmox.com/git/qemu
synced 2025-08-15 10:10:13 +00:00
target-arm: Don't update base register on abort in Thumb T1 LDM
Make sure the base register isn't updated if it is in the load list for a Thumb LDM (T1 encoding) which aborts partway through the load. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
5856d44eb5
commit
a7d3970d06
@ -9454,7 +9454,10 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 12:
|
case 12:
|
||||||
|
{
|
||||||
/* load/store multiple */
|
/* load/store multiple */
|
||||||
|
TCGv loaded_var;
|
||||||
|
TCGV_UNUSED(loaded_var);
|
||||||
rn = (insn >> 8) & 0x7;
|
rn = (insn >> 8) & 0x7;
|
||||||
addr = load_reg(s, rn);
|
addr = load_reg(s, rn);
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
@ -9462,7 +9465,11 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
|
|||||||
if (insn & (1 << 11)) {
|
if (insn & (1 << 11)) {
|
||||||
/* load */
|
/* load */
|
||||||
tmp = gen_ld32(addr, IS_USER(s));
|
tmp = gen_ld32(addr, IS_USER(s));
|
||||||
store_reg(s, i, tmp);
|
if (i == rn) {
|
||||||
|
loaded_var = tmp;
|
||||||
|
} else {
|
||||||
|
store_reg(s, i, tmp);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* store */
|
/* store */
|
||||||
tmp = load_reg(s, i);
|
tmp = load_reg(s, i);
|
||||||
@ -9472,14 +9479,18 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
|
|||||||
tcg_gen_addi_i32(addr, addr, 4);
|
tcg_gen_addi_i32(addr, addr, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Base register writeback. */
|
|
||||||
if ((insn & (1 << rn)) == 0) {
|
if ((insn & (1 << rn)) == 0) {
|
||||||
|
/* base reg not in list: base register writeback */
|
||||||
store_reg(s, rn, addr);
|
store_reg(s, rn, addr);
|
||||||
} else {
|
} else {
|
||||||
|
/* base reg in list: if load, complete it now */
|
||||||
|
if (insn & (1 << 11)) {
|
||||||
|
store_reg(s, rn, loaded_var);
|
||||||
|
}
|
||||||
tcg_temp_free_i32(addr);
|
tcg_temp_free_i32(addr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 13:
|
case 13:
|
||||||
/* conditional branch or swi */
|
/* conditional branch or swi */
|
||||||
cond = (insn >> 8) & 0xf;
|
cond = (insn >> 8) & 0xf;
|
||||||
|
Loading…
Reference in New Issue
Block a user