Skip to content

Commit

Permalink
target-arm: Don't update base register on abort in Thumb T1 LDM
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Aurelien Jarno <[email protected]>
  • Loading branch information
pm215 authored and aurel32 committed Apr 27, 2011
1 parent 5856d44 commit a7d3970
Showing 1 changed file with 14 additions and 3 deletions.
17 changes: 14 additions & 3 deletions target-arm/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -9454,15 +9454,22 @@ 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++) {
if (insn & (1 << i)) {
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);
Expand All @@ -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;
Expand Down

0 comments on commit a7d3970

Please sign in to comment.