diff --git a/target-mips/op.c b/target-mips/op.c index d440896f3203daa79f895d1e65e22e1bf6aa6d04..5048bc0f9f41690b1237b4ae8837a16305c2f607 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -1360,9 +1360,14 @@ void op_mtc0_status (void) no 64bit addressing implemented. */ val = (int32_t)T0 & 0xF878FF17; old = env->CP0_Status; + if (!(val & (1 << CP0St_EXL)) && + !(val & (1 << CP0St_ERL)) && + !(env->hflags & MIPS_HFLAG_DM) && + (val & (1 << CP0St_UM))) + env->hflags |= MIPS_HFLAG_UM; env->CP0_Status = val; - if (loglevel & CPU_LOG_TB_IN_ASM) - CALL_FROM_TB2(do_mtc0_status_debug, old, val); + if (loglevel & CPU_LOG_EXEC) + CALL_FROM_TB2(do_mtc0_status_debug, old, val); CALL_FROM_TB1(cpu_mips_update_irq, env); RETURN(); } @@ -2077,10 +2082,12 @@ void op_set_lladdr (void) RETURN(); } -void debug_eret (void); +void debug_pre_eret (void); +void debug_post_eret (void); void op_eret (void) { - CALL_FROM_TB0(debug_eret); + if (loglevel & CPU_LOG_EXEC) + CALL_FROM_TB0(debug_pre_eret); if (env->CP0_Status & (1 << CP0St_ERL)) { env->PC = env->CP0_ErrorEPC; env->CP0_Status &= ~(1 << CP0St_ERL); @@ -2093,13 +2100,16 @@ void op_eret (void) !(env->hflags & MIPS_HFLAG_DM) && (env->CP0_Status & (1 << CP0St_UM))) env->hflags |= MIPS_HFLAG_UM; + if (loglevel & CPU_LOG_EXEC) + CALL_FROM_TB0(debug_post_eret); env->CP0_LLAddr = 1; RETURN(); } void op_deret (void) { - CALL_FROM_TB0(debug_eret); + if (loglevel & CPU_LOG_EXEC) + CALL_FROM_TB0(debug_pre_eret); env->PC = env->CP0_DEPC; env->hflags |= MIPS_HFLAG_DM; if (!(env->CP0_Status & (1 << CP0St_EXL)) && @@ -2107,6 +2117,8 @@ void op_deret (void) !(env->hflags & MIPS_HFLAG_DM) && (env->CP0_Status & (1 << CP0St_UM))) env->hflags |= MIPS_HFLAG_UM; + if (loglevel & CPU_LOG_EXEC) + CALL_FROM_TB0(debug_post_eret); env->CP0_LLAddr = 1; RETURN(); } diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index ba02f0d84f6a1899883a01f3a7cb970542938734..92712a8994356215bc9090f294d36e67b180ac2b 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -329,10 +329,12 @@ void do_mfc0_count (void) void do_mtc0_status_debug(uint32_t old, uint32_t val) { - const uint32_t mask = 0x0000FF00; - fprintf(logfile, "Status %08x => %08x Cause %08x (%08x %08x %08x)\n", - old, val, env->CP0_Cause, old & mask, val & mask, - env->CP0_Cause & mask); + fprintf(logfile, "Status %08x (%08x) => %08x (%08x) Cause %08x", + old, old & env->CP0_Cause & CP0Ca_IP_mask, + val, val & env->CP0_Cause & CP0Ca_IP_mask, + env->CP0_Cause); + (env->hflags & MIPS_HFLAG_UM) ? fputs(", UM\n", logfile) + : fputs("\n", logfile); } void do_mtc0_status_irqraise_debug(void) @@ -508,15 +510,29 @@ void dump_sc (void) } } -void debug_eret (void) +void debug_pre_eret (void) { - if (loglevel) { - fprintf(logfile, "ERET: pc " TARGET_FMT_lx " EPC " TARGET_FMT_lx, - env->PC, env->CP0_EPC); - if (env->CP0_Status & (1 << CP0St_ERL)) - fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC); + fprintf(logfile, "ERET: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx, + env->PC, env->CP0_EPC); + if (env->CP0_Status & (1 << CP0St_ERL)) + fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC); + if (env->hflags & MIPS_HFLAG_DM) + fprintf(logfile, " DEPC " TARGET_FMT_lx, env->CP0_DEPC); + fputs("\n", logfile); +} + +void debug_post_eret (void) +{ + fprintf(logfile, " => PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx, + env->PC, env->CP0_EPC); + if (env->CP0_Status & (1 << CP0St_ERL)) + fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC); + if (env->hflags & MIPS_HFLAG_DM) + fprintf(logfile, " DEPC " TARGET_FMT_lx, env->CP0_DEPC); + if (env->hflags & MIPS_HFLAG_UM) + fputs(", UM\n", logfile); + else fputs("\n", logfile); - } } void do_pmon (int function) diff --git a/target-mips/translate.c b/target-mips/translate.c index 8da8cc40347fbbdaaa5d01076320215b98065935..f3b2de446eedf2f5011a0053650521ea90be8b60 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -4880,6 +4880,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) } break; case OPC_CP0: + save_cpu_state(ctx, 1); gen_op_cp0_enabled(); op1 = MASK_CP0(ctx->opcode); switch (op1) {