Merge branch 'target-arm.for-upstream' of git://git.linaro.org/people/pmaydell/qemu-arm

* 'target-arm.for-upstream' of git://git.linaro.org/people/pmaydell/qemu-arm:
  target-arm: Decode SETEND correctly in Thumb
  target-arm: Clear IT bits when taking exceptions in v7M
  target-arm: Fix typo in ARM946 cp15 c5 handling
This commit is contained in:
Blue Swirl 2012-03-17 12:59:41 +00:00
commit 6344d922a1
2 changed files with 43 additions and 25 deletions

View file

@ -877,7 +877,8 @@ static void do_interrupt_v7m(CPUARMState *env)
v7m_push(env, env->regs[1]);
v7m_push(env, env->regs[0]);
switch_v7m_sp(env, 0);
env->uncached_cpsr &= ~CPSR_IT;
/* Clear IT bits */
env->condexec_bits = 0;
env->regs[14] = lr;
addr = ldl_phys(env->v7m.vecbase + env->v7m.exception * 4);
env->regs[15] = addr & 0xfffffffe;
@ -2025,7 +2026,7 @@ uint32_t HELPER(get_cp15)(CPUARMState *env, uint32_t insn)
return env->cp15.c5_data;
case 1:
if (arm_feature(env, ARM_FEATURE_MPU))
return simple_mpu_ap_bits(env->cp15.c5_data);
return simple_mpu_ap_bits(env->cp15.c5_insn);
return env->cp15.c5_insn;
case 2:
if (!arm_feature(env, ARM_FEATURE_MPU))

View file

@ -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;