diff options
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r-- | target-mips/translate.c | 50 |
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) { |