target/arm: Add v8M stack checks for T32 load/store single

Add v8M stack checks for the instructions in the T32
"load/store single" encoding class: these are the
"immediate pre-indexed" and "immediate, post-indexed"
LDR and STR instructions.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20181002163556.10279-11-peter.maydell@linaro.org
master
Peter Maydell 2018-10-08 14:55:04 +01:00
parent 7c0ed88e7d
commit 0bc003bad9
1 changed files with 22 additions and 1 deletions

View File

@ -11624,7 +11624,6 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
imm = -imm;
/* Fall through. */
case 0xf: /* Pre-increment. */
tcg_gen_addi_i32(addr, addr, imm);
writeback = 1;
break;
default:
@ -11636,6 +11635,28 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
issinfo = writeback ? ISSInvalid : rs;
if (s->v8m_stackcheck && rn == 13 && writeback) {
/*
* Stackcheck. Here we know 'addr' is the current SP;
* if imm is +ve we're moving SP up, else down. It is
* UNKNOWN whether the limit check triggers when SP starts
* below the limit and ends up above it; we chose to do so.
*/
if ((int32_t)imm < 0) {
TCGv_i32 newsp = tcg_temp_new_i32();
tcg_gen_addi_i32(newsp, addr, imm);
gen_helper_v8m_stackcheck(cpu_env, newsp);
tcg_temp_free_i32(newsp);
} else {
gen_helper_v8m_stackcheck(cpu_env, addr);
}
}
if (writeback && !postinc) {
tcg_gen_addi_i32(addr, addr, imm);
}
if (insn & (1 << 20)) {
/* Load. */
tmp = tcg_temp_new_i32();