diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-12-13 17:59:24 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-12-13 17:59:24 +0000 |
commit | 5158de241b0fb344a6c948dfcbc4e611ab5fafbe (patch) | |
tree | ac6982199c30ad6e17316e8dcdd972d3270599cf /target/arm/translate.c | |
parent | 54317c0ff3a3c0f6b2c3a1d3c8b5d93686a86d24 (diff) |
target/arm: Implement TT instruction
Implement the TT instruction which queries the security
state and access permissions of a memory location.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 1512153879-5291-8-git-send-email-peter.maydell@linaro.org
Diffstat (limited to 'target/arm/translate.c')
-rw-r--r-- | target/arm/translate.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/target/arm/translate.c b/target/arm/translate.c index 50339e7bdd..e15192d5d6 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -9810,7 +9810,7 @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn) if (insn & (1 << 22)) { /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx * - load/store doubleword, load/store exclusive, ldacq/strel, - * table branch. + * table branch, TT. */ if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) && arm_dc_feature(s, ARM_FEATURE_V8)) { @@ -9887,8 +9887,35 @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn) } else if ((insn & (1 << 23)) == 0) { /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx * - load/store exclusive word + * - TT (v8M only) */ if (rs == 15) { + if (!(insn & (1 << 20)) && + arm_dc_feature(s, ARM_FEATURE_M) && + arm_dc_feature(s, ARM_FEATURE_V8)) { + /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx + * - TT (v8M only) + */ + bool alt = insn & (1 << 7); + TCGv_i32 addr, op, ttresp; + + if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) { + /* we UNDEF for these UNPREDICTABLE cases */ + goto illegal_op; + } + + if (alt && !s->v8m_secure) { + goto illegal_op; + } + + addr = load_reg(s, rn); + op = tcg_const_i32(extract32(insn, 6, 2)); + ttresp = tcg_temp_new_i32(); + gen_helper_v7m_tt(ttresp, cpu_env, addr, op); + tcg_temp_free_i32(addr); + tcg_temp_free_i32(op); + store_reg(s, rd, ttresp); + } goto illegal_op; } addr = tcg_temp_local_new_i32(); |