aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-06-01 17:47:07 +0000
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-06-01 17:47:07 +0000
commit8487327a1dabd9ce8899d0e1af151b334980c575 (patch)
treeaa2f835c276f898ffae5ea58034249392be231b1
parent5b9693dcda3e6c19429a29f948ba3618f826f6cb (diff)
Make sure hflags are updated for CP0_Status changes.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2918 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--target-mips/translate.c50
1 files changed, 42 insertions, 8 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 08b760ba76..7ea7886ec8 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -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) {