summaryrefslogtreecommitdiff
path: root/target/arm/translate.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-10-09 14:48:33 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-10-12 13:23:14 +0100
commit3e3fa230e3b8ffe119f14ba57a6bc677a411be57 (patch)
treea8cc93817f1869fdb324a0dea95981e8005e0c12 /target/arm/translate.c
parent333e10c51ef5876ced26f77b61b69ce0f83161a9 (diff)
downloadqemu-3e3fa230e3b8ffe119f14ba57a6bc677a411be57.tar.gz
target/arm: Implement BLXNS
Implement the BLXNS instruction, which allows secure code to call non-secure code. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1507556919-24992-4-git-send-email-peter.maydell@linaro.org
Diffstat (limited to 'target/arm/translate.c')
-rw-r--r--target/arm/translate.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 61fd0ef6b5..caf0d5849a 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -1017,6 +1017,20 @@ static inline void gen_bxns(DisasContext *s, int rm)
s->base.is_jmp = DISAS_EXIT;
}
+static inline void gen_blxns(DisasContext *s, int rm)
+{
+ TCGv_i32 var = load_reg(s, rm);
+
+ /* We don't need to sync condexec state, for the same reason as bxns.
+ * We do however need to set the PC, because the blxns helper reads it.
+ * The blxns helper may throw an exception.
+ */
+ gen_set_pc_im(s, s->pc);
+ gen_helper_v7m_blxns(cpu_env, var);
+ tcg_temp_free_i32(var);
+ s->base.is_jmp = DISAS_EXIT;
+}
+
/* Variant of store_reg which uses branch&exchange logic when storing
to r15 in ARM architecture v7 and above. The source must be a temporary
and will be marked as dead. */
@@ -11222,8 +11236,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
goto undef;
}
if (link) {
- /* BLXNS: not yet implemented */
- goto undef;
+ gen_blxns(s, rm);
} else {
gen_bxns(s, rm);
}