aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2012-03-14 12:26:11 +0000
committerPeter Maydell <peter.maydell@linaro.org>2012-03-15 17:00:55 +0000
commitd9e028c1d9c2a8d2ad42f2aeb502b71086a52d4d (patch)
treee54746b5f4004930b264fd12cfe1e1b22b1a76c5
parentc98d174c24b915e9908785feb63eb3b5abe33818 (diff)
target-arm: Decode SETEND correctly in Thumb
Decode the SETEND instruction correctly in Thumb mode, rather than accidentally treating it like CPS. We don't support BE8 mode, but this change brings the Thumb mode in to line with behaviour in ARM mode: 'SETEND BE' is not supported and will provoke an UNDEF exception, but 'SETEND LE' is correctly handled as a no-op. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reported-by: Daniel Forsgren <daniel.forsgren@enea.com> Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
-rw-r--r--target-arm/translate.c63
1 files changed, 40 insertions, 23 deletions
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 2709010f4..81725d168 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9704,32 +9704,49 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
store_reg(s, rd, tmp);
break;
- case 6: /* cps */
- ARCH(6);
- if (IS_USER(s))
+ case 6:
+ switch ((insn >> 5) & 7) {
+ case 2:
+ /* setend */
+ ARCH(6);
+ if (insn & (1 << 3)) {
+ /* BE8 mode not implemented. */
+ goto illegal_op;
+ }
break;
- if (IS_M(env)) {
- tmp = tcg_const_i32((insn & (1 << 4)) != 0);
- /* FAULTMASK */
- if (insn & 1) {
- addr = tcg_const_i32(19);
- gen_helper_v7m_msr(cpu_env, addr, tmp);
- tcg_temp_free_i32(addr);
+ case 3:
+ /* cps */
+ ARCH(6);
+ if (IS_USER(s)) {
+ break;
}
- /* PRIMASK */
- if (insn & 2) {
- addr = tcg_const_i32(16);
- gen_helper_v7m_msr(cpu_env, addr, tmp);
- tcg_temp_free_i32(addr);
+ if (IS_M(env)) {
+ tmp = tcg_const_i32((insn & (1 << 4)) != 0);
+ /* FAULTMASK */
+ if (insn & 1) {
+ addr = tcg_const_i32(19);
+ gen_helper_v7m_msr(cpu_env, addr, tmp);
+ tcg_temp_free_i32(addr);
+ }
+ /* PRIMASK */
+ if (insn & 2) {
+ addr = tcg_const_i32(16);
+ gen_helper_v7m_msr(cpu_env, addr, tmp);
+ tcg_temp_free_i32(addr);
+ }
+ tcg_temp_free_i32(tmp);
+ gen_lookup_tb(s);
+ } else {
+ if (insn & (1 << 4)) {
+ shift = CPSR_A | CPSR_I | CPSR_F;
+ } else {
+ shift = 0;
+ }
+ gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
}
- tcg_temp_free_i32(tmp);
- gen_lookup_tb(s);
- } else {
- if (insn & (1 << 4))
- shift = CPSR_A | CPSR_I | CPSR_F;
- else
- shift = 0;
- gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
+ break;
+ default:
+ goto undef;
}
break;