diff options
Diffstat (limited to 'target/arm/translate.c')
-rw-r--r-- | target/arm/translate.c | 84 |
1 files changed, 38 insertions, 46 deletions
diff --git a/target/arm/translate.c b/target/arm/translate.c index 09c05de..ce394dd 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -7496,6 +7496,11 @@ static int negate(DisasContext *s, int x) return -x; } +static int plus_2(DisasContext *s, int x) +{ + return x + 2; +} + static int times_2(DisasContext *s, int x) { return x * 2; @@ -10268,7 +10273,7 @@ static bool trans_CPS(DisasContext *s, arg_CPS *a) { uint32_t mask, val; - if (arm_dc_feature(s, ARM_FEATURE_M)) { + if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) { return false; } if (IS_USER(s)) { @@ -10302,6 +10307,36 @@ static bool trans_CPS(DisasContext *s, arg_CPS *a) return true; } +static bool trans_CPS_v7m(DisasContext *s, arg_CPS_v7m *a) +{ + TCGv_i32 tmp, addr; + + if (!arm_dc_feature(s, ARM_FEATURE_M)) { + return false; + } + if (IS_USER(s)) { + /* Implemented as NOP in user mode. */ + return true; + } + + tmp = tcg_const_i32(a->im); + /* FAULTMASK */ + if (a->F) { + addr = tcg_const_i32(19); + gen_helper_v7m_msr(cpu_env, addr, tmp); + tcg_temp_free_i32(addr); + } + /* PRIMASK */ + if (a->I) { + 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); + return true; +} + /* * Clear-Exclusive, Barriers */ @@ -10908,51 +10943,8 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) break; } - case 6: - switch ((insn >> 5) & 7) { - case 2: - /* setend */ - ARCH(6); - if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) { - gen_helper_setend(cpu_env); - s->base.is_jmp = DISAS_UPDATE; - } - break; - case 3: - /* cps */ - ARCH(6); - if (IS_USER(s)) { - break; - } - if (arm_dc_feature(s, ARM_FEATURE_M)) { - 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); - } - break; - default: - goto undef; - } - break; + case 6: /* setend, cps; in decodetree */ + goto illegal_op; default: goto undef; |