!(env->hflags & MIPS_HFLAG_DM) &&
(val & (1 << CP0St_UM)))
env->hflags |= MIPS_HFLAG_UM;
- env->CP0_Status = val;
+ env->CP0_Status = (env->CP0_Status & ~0xF878FF17) | val;
if (loglevel & CPU_LOG_EXEC)
CALL_FROM_TB2(do_mtc0_status_debug, old, val);
CALL_FROM_TB1(cpu_mips_update_irq, env);
RETURN();
}
+void op_interrupt_restart (void)
+{
+ if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
+ !(env->CP0_Status & (1 << CP0St_ERL)) &&
+ !(env->hflags & MIPS_HFLAG_DM) &&
+ (env->CP0_Status & (1 << CP0St_IE)) &&
+ (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask)) {
+ env->CP0_Cause &= ~(0x1f << CP0Ca_EC);
+ CALL_FROM_TB1(do_raise_exception, EXCP_EXT_INTERRUPT);
+ }
+ RETURN();
+}
+
void op_raise_exception (void)
{
CALL_FROM_TB1(do_raise_exception, PARAM1);
if (env->singlestep_enabled) {
save_cpu_state(ctxp, ctx.bstate == BS_NONE);
gen_op_debug();
- goto done_generating;
- }
- else if (ctx.bstate != BS_BRANCH && ctx.bstate != BS_EXCP) {
- save_cpu_state(ctxp, 0);
- gen_goto_tb(&ctx, 0, ctx.pc);
+ } else {
+ switch (ctx.bstate) {
+ case BS_EXCP:
+ gen_op_interrupt_restart();
+ break;
+ case BS_STOP:
+ gen_op_interrupt_restart();
+ /* Fall through. */
+ case BS_NONE:
+ save_cpu_state(ctxp, 0);
+ gen_goto_tb(&ctx, 0, ctx.pc);
+ break;
+ case BS_BRANCH:
+ default:
+ break;
+ }
+ gen_op_reset_T0();
+ /* Generate the return instruction. */
+ gen_op_exit_tb();
}
- gen_op_reset_T0();
- /* Generate the return instruction */
- gen_op_exit_tb();
done_generating:
*gen_opc_ptr = INDEX_op_end;
if (search_pc) {