提交 a7d3970d 编写于 作者: P Peter Maydell 提交者: Aurelien Jarno

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: NPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: NAurelien Jarno <aurelien@aurel32.net>
上级 5856d44e
......@@ -9454,7 +9454,10 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
break;
case 12:
{
/* load/store multiple */
TCGv loaded_var;
TCGV_UNUSED(loaded_var);
rn = (insn >> 8) & 0x7;
addr = load_reg(s, rn);
for (i = 0; i < 8; i++) {
......@@ -9462,7 +9465,11 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
if (insn & (1 << 11)) {
/* load */
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 {
/* store */
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);
}
}
/* Base register writeback. */
if ((insn & (1 << rn)) == 0) {
/* base reg not in list: base register writeback */
store_reg(s, rn, addr);
} 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);
}
break;
}
case 13:
/* conditional branch or swi */
cond = (insn >> 8) & 0xf;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册