Make sure hflags are updated for CP0_Status changes.
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 1 Jun 2007 17:47:07 +0000 (17:47 +0000)
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 1 Jun 2007 17:47:07 +0000 (17:47 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2918 c046a42c-6fe2-441c-8c8c-71466251a162

target-mips/translate.c

index 08b760b..7ea7886 100644 (file)
@@ -2627,25 +2627,32 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
         switch (sel) {
         case 0:
             gen_op_mtc0_status();
+            /* BS_STOP isn't good enough here, hflags may have changed. */
+            gen_save_pc(ctx->pc + 4);
+            ctx->bstate = BS_EXCP;
             rn = "Status";
             break;
         case 1:
             gen_op_mtc0_intctl();
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "IntCtl";
             break;
         case 2:
             gen_op_mtc0_srsctl();
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "SRSCtl";
             break;
         case 3:
             gen_op_mtc0_srsmap();
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "SRSMap";
             break;
         default:
             goto die;
         }
-        /* Stop translation as we may have switched the execution mode */
-        ctx->bstate = BS_STOP;
         break;
     case 13:
         switch (sel) {
@@ -2781,29 +2788,40 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
         switch (sel) {
         case 0:
             gen_op_mtc0_debug(); /* EJTAG support */
+            /* BS_STOP isn't good enough here, hflags may have changed. */
+            gen_save_pc(ctx->pc + 4);
+            ctx->bstate = BS_EXCP;
             rn = "Debug";
             break;
         case 1:
 //            gen_op_mtc0_tracecontrol(); /* PDtrace support */
             rn = "TraceControl";
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
 //            break;
         case 2:
 //            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
             rn = "TraceControl2";
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
 //            break;
         case 3:
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
 //            gen_op_mtc0_usertracedata(); /* PDtrace support */
             rn = "UserTraceData";
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
 //            break;
         case 4:
 //            gen_op_mtc0_debug(); /* PDtrace support */
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "TraceBPC";
 //            break;
         default:
             goto die;
         }
-        /* Stop translation as we may have switched the execution mode */
-        ctx->bstate = BS_STOP;
         break;
     case 24:
         switch (sel) {
@@ -3704,25 +3722,32 @@ static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
         switch (sel) {
         case 0:
             gen_op_mtc0_status();
+            /* BS_STOP isn't good enough here, hflags may have changed. */
+            gen_save_pc(ctx->pc + 4);
+            ctx->bstate = BS_EXCP;
             rn = "Status";
             break;
         case 1:
             gen_op_mtc0_intctl();
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "IntCtl";
             break;
         case 2:
             gen_op_mtc0_srsctl();
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "SRSCtl";
             break;
         case 3:
             gen_op_mtc0_srsmap();
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "SRSMap";
             break;
         default:
             goto die;
         }
-        /* Stop translation as we may have switched the execution mode */
-        ctx->bstate = BS_STOP;
         break;
     case 13:
         switch (sel) {
@@ -3849,29 +3874,38 @@ static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
         switch (sel) {
         case 0:
             gen_op_mtc0_debug(); /* EJTAG support */
+            /* BS_STOP isn't good enough here, hflags may have changed. */
+            gen_save_pc(ctx->pc + 4);
+            ctx->bstate = BS_EXCP;
             rn = "Debug";
             break;
         case 1:
 //            gen_op_mtc0_tracecontrol(); /* PDtrace support */
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "TraceControl";
 //            break;
         case 2:
 //            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "TraceControl2";
 //            break;
         case 3:
 //            gen_op_mtc0_usertracedata(); /* PDtrace support */
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "UserTraceData";
 //            break;
         case 4:
 //            gen_op_mtc0_debug(); /* PDtrace support */
+            /* Stop translation as we may have switched the execution mode */
+            ctx->bstate = BS_STOP;
             rn = "TraceBPC";
 //            break;
         default:
             goto die;
         }
-        /* Stop translation as we may have switched the execution mode */
-        ctx->bstate = BS_STOP;
         break;
     case 24:
         switch (sel) {