Commit 0bc003ba authored by Peter Maydell's avatar Peter Maydell
Browse files

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: default avatarPeter Maydell <peter.maydell@linaro.org>
Reviewed-by: default avatarPhilippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-id: 20181002163556.10279-11-peter.maydell@linaro.org
parent 7c0ed88e
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -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();