Save state for all CP0 instructions, they may throw a CPU exception.
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 6 Apr 2007 18:46:01 +0000 (18:46 +0000)
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 6 Apr 2007 18:46:01 +0000 (18:46 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2622 c046a42c-6fe2-441c-8c8c-71466251a162

target-mips/op.c
target-mips/op_helper.c
target-mips/translate.c

index d440896..5048bc0 100644 (file)
@@ -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();
 }
index ba02f0d..92712a8 100644 (file)
@@ -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)
index 8da8cc4..f3b2de4 100644 (file)
@@ -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) {