aboutsummaryrefslogtreecommitdiff
path: root/target-mips
diff options
context:
space:
mode:
authorLeon Alrae <leon.alrae@imgtec.com>2014-07-11 16:11:35 +0100
committerLeon Alrae <leon.alrae@imgtec.com>2014-11-03 11:48:34 +0000
commitf31b035a9f10dc9b57f01c426110af845d453ce2 (patch)
treeed772e97f451b594713583a7ce103dbe76638fef /target-mips
parentba801af429aaa68f6cc03842c8b6be81a6ede65a (diff)
target-mips: correctly handle access to unimplemented CP0 register
Release 6 limits the number of cases where software can cause UNDEFINED or UNPREDICTABLE behaviour. In this case, when accessing reserved / unimplemented CP0 register, writes are ignored and reads return 0. In pre-R6 the behaviour is not specified, but generating RI exception is not what the real HW does. Additionally, remove CP0 Random register as it became reserved in Release 6. Signed-off-by: Leon Alrae <leon.alrae@imgtec.com> Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>
Diffstat (limited to 'target-mips')
-rw-r--r--target-mips/translate.c538
1 files changed, 260 insertions, 278 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c
index a383a5ce4a..9a8f5c93f4 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -4584,6 +4584,13 @@ static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
}
}
+#define CP0_CHECK(c) \
+ do { \
+ if (!(c)) { \
+ goto cp0_unimplemented; \
+ } \
+ } while (0)
+
static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
{
const char *rn = "invalid";
@@ -4599,67 +4606,68 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "Index";
break;
case 1:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_mvpcontrol(arg, cpu_env);
rn = "MVPControl";
break;
case 2:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_mvpconf0(arg, cpu_env);
rn = "MVPConf0";
break;
case 3:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_mvpconf1(arg, cpu_env);
rn = "MVPConf1";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 1:
switch (sel) {
case 0:
+ CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
gen_helper_mfc0_random(arg, cpu_env);
rn = "Random";
break;
case 1:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
rn = "VPEControl";
break;
case 2:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
rn = "VPEConf0";
break;
case 3:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
rn = "VPEConf1";
break;
case 4:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
rn = "YQMask";
break;
case 5:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
rn = "VPESchedule";
break;
case 6:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
rn = "VPEScheFBack";
break;
case 7:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
rn = "VPEOpt";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 2:
@@ -4679,42 +4687,42 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EntryLo0";
break;
case 1:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tcstatus(arg, cpu_env);
rn = "TCStatus";
break;
case 2:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tcbind(arg, cpu_env);
rn = "TCBind";
break;
case 3:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tcrestart(arg, cpu_env);
rn = "TCRestart";
break;
case 4:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tchalt(arg, cpu_env);
rn = "TCHalt";
break;
case 5:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tccontext(arg, cpu_env);
rn = "TCContext";
break;
case 6:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tcschedule(arg, cpu_env);
rn = "TCSchedule";
break;
case 7:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tcschefback(arg, cpu_env);
rn = "TCScheFBack";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 3:
@@ -4734,7 +4742,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EntryLo1";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 4:
@@ -4747,20 +4755,16 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
case 1:
// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
rn = "ContextConfig";
- goto die;
+ goto cp0_unimplemented;
// break;
case 2:
- if (ctx->ulri) {
- tcg_gen_ld32s_tl(arg, cpu_env,
- offsetof(CPUMIPSState,
- active_tc.CP0_UserLocal));
- rn = "UserLocal";
- } else {
- tcg_gen_movi_tl(arg, 0);
- }
+ CP0_CHECK(ctx->ulri);
+ tcg_gen_ld32s_tl(arg, cpu_env,
+ offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
+ rn = "UserLocal";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 5:
@@ -4775,7 +4779,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "PageGrain";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 6:
@@ -4810,7 +4814,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "SRSConf4";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 7:
@@ -4821,7 +4825,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "HWREna";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 8:
@@ -4832,23 +4836,17 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "BadVAddr";
break;
case 1:
- if (ctx->bi) {
- gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
- rn = "BadInstr";
- } else {
- gen_mfc0_unimplemented(ctx, arg);
- }
+ CP0_CHECK(ctx->bi);
+ gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
+ rn = "BadInstr";
break;
case 2:
- if (ctx->bp) {
- gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
- rn = "BadInstrP";
- } else {
- gen_mfc0_unimplemented(ctx, arg);
- }
+ CP0_CHECK(ctx->bp);
+ gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
+ rn = "BadInstrP";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 9:
@@ -4868,7 +4866,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
break;
/* 6,7 are implementation dependent */
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 10:
@@ -4879,7 +4877,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EntryHi";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 11:
@@ -4890,7 +4888,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
break;
/* 6,7 are implementation dependent */
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 12:
@@ -4915,7 +4913,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "SRSMap";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 13:
@@ -4925,7 +4923,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "Cause";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 14:
@@ -4936,7 +4934,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EPC";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 15:
@@ -4951,7 +4949,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EBase";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 16:
@@ -4990,7 +4988,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "Config7";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 17:
@@ -5000,7 +4998,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "LLAddr";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 18:
@@ -5010,7 +5008,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "WatchLo";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 19:
@@ -5020,7 +5018,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "WatchHi";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 20:
@@ -5034,18 +5032,19 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
break;
#endif
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 21:
/* Officially reserved, but sel 0 is used for R1x000 framemask */
+ CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
rn = "Framemask";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 22:
@@ -5075,7 +5074,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "TraceBPC";
// break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 24:
@@ -5087,7 +5086,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "DEPC";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 25:
@@ -5125,7 +5124,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "Performance7";
// break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 26:
@@ -5139,7 +5138,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "CacheErr";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 28:
@@ -5159,7 +5158,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "DataLo";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 29:
@@ -5179,7 +5178,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "DataHi";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 30:
@@ -5190,7 +5189,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "ErrorEPC";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 31:
@@ -5201,29 +5200,26 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "DESAVE";
break;
case 2 ... 7:
- if (ctx->kscrexist & (1 << sel)) {
- tcg_gen_ld_tl(arg, cpu_env,
- offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
- tcg_gen_ext32s_tl(arg, arg);
- rn = "KScratch";
- } else {
- gen_mfc0_unimplemented(ctx, arg);
- }
+ CP0_CHECK(ctx->kscrexist & (1 << sel));
+ tcg_gen_ld_tl(arg, cpu_env,
+ offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
+ tcg_gen_ext32s_tl(arg, arg);
+ rn = "KScratch";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
(void)rn; /* avoid a compiler warning */
LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
return;
-die:
+cp0_unimplemented:
LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
- generate_exception(ctx, EXCP_RI);
+ gen_mfc0_unimplemented(ctx, arg);
}
static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
@@ -5244,22 +5240,22 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "Index";
break;
case 1:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_mvpcontrol(cpu_env, arg);
rn = "MVPControl";
break;
case 2:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
/* ignored */
rn = "MVPConf0";
break;
case 3:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
/* ignored */
rn = "MVPConf1";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 1:
@@ -5269,42 +5265,42 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "Random";
break;
case 1:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_vpecontrol(cpu_env, arg);
rn = "VPEControl";
break;
case 2:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_vpeconf0(cpu_env, arg);
rn = "VPEConf0";
break;
case 3:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_vpeconf1(cpu_env, arg);
rn = "VPEConf1";
break;
case 4:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_yqmask(cpu_env, arg);
rn = "YQMask";
break;
case 5:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
rn = "VPESchedule";
break;
case 6:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
rn = "VPEScheFBack";
break;
case 7:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_vpeopt(cpu_env, arg);
rn = "VPEOpt";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 2:
@@ -5314,42 +5310,42 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EntryLo0";
break;
case 1:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcstatus(cpu_env, arg);
rn = "TCStatus";
break;
case 2:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcbind(cpu_env, arg);
rn = "TCBind";
break;
case 3:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcrestart(cpu_env, arg);
rn = "TCRestart";
break;
case 4:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tchalt(cpu_env, arg);
rn = "TCHalt";
break;
case 5:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tccontext(cpu_env, arg);
rn = "TCContext";
break;
case 6:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcschedule(cpu_env, arg);
rn = "TCSchedule";
break;
case 7:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcschefback(cpu_env, arg);
rn = "TCScheFBack";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 3:
@@ -5359,7 +5355,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EntryLo1";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 4:
@@ -5371,17 +5367,16 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
case 1:
// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
rn = "ContextConfig";
- goto die;
+ goto cp0_unimplemented;
// break;
case 2:
- if (ctx->ulri) {
- tcg_gen_st_tl(arg, cpu_env,
- offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
- rn = "UserLocal";
- }
+ CP0_CHECK(ctx->ulri);
+ tcg_gen_st_tl(arg, cpu_env,
+ offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
+ rn = "UserLocal";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 5:
@@ -5396,7 +5391,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "PageGrain";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 6:
@@ -5431,7 +5426,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "SRSConf4";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 7:
@@ -5443,7 +5438,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "HWREna";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 8:
@@ -5461,7 +5456,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "BadInstrP";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 9:
@@ -5472,7 +5467,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
break;
/* 6,7 are implementation dependent */
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 10:
@@ -5482,7 +5477,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EntryHi";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 11:
@@ -5493,7 +5488,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
break;
/* 6,7 are implementation dependent */
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 12:
@@ -5528,7 +5523,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "SRSMap";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 13:
@@ -5539,7 +5534,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "Cause";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 14:
@@ -5549,7 +5544,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EPC";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 15:
@@ -5564,7 +5559,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EBase";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 16:
@@ -5611,7 +5606,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
break;
default:
rn = "Invalid config selector";
- goto die;
+ goto cp0_unimplemented;
}
break;
case 17:
@@ -5621,7 +5616,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "LLAddr";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 18:
@@ -5631,7 +5626,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "WatchLo";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 19:
@@ -5641,7 +5636,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "WatchHi";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 20:
@@ -5654,18 +5649,19 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
break;
#endif
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 21:
/* Officially reserved, but sel 0 is used for R1x000 framemask */
+ CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
switch (sel) {
case 0:
gen_helper_mtc0_framemask(cpu_env, arg);
rn = "Framemask";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 22:
@@ -5708,7 +5704,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "TraceBPC";
// break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 24:
@@ -5719,7 +5715,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "DEPC";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 25:
@@ -5757,7 +5753,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "Performance7";
// break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 26:
@@ -5771,7 +5767,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "CacheErr";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 28:
@@ -5791,7 +5787,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "DataLo";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 29:
@@ -5812,7 +5808,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
break;
default:
rn = "invalid sel";
- goto die;
+ goto cp0_unimplemented;
}
break;
case 30:
@@ -5822,7 +5818,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "ErrorEPC";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 31:
@@ -5833,20 +5829,19 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "DESAVE";
break;
case 2 ... 7:
- if (ctx->kscrexist & (1 << sel)) {
- tcg_gen_st_tl(arg, cpu_env,
- offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
- rn = "KScratch";
- }
+ CP0_CHECK(ctx->kscrexist & (1 << sel));
+ tcg_gen_st_tl(arg, cpu_env,
+ offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
+ rn = "KScratch";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
/* Stop translation as we may have switched the execution mode */
ctx->bstate = BS_STOP;
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
(void)rn; /* avoid a compiler warning */
LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
@@ -5857,9 +5852,8 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
}
return;
-die:
+cp0_unimplemented:
LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
- generate_exception(ctx, EXCP_RI);
}
#if defined(TARGET_MIPS64)
@@ -5878,67 +5872,68 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "Index";
break;
case 1:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_mvpcontrol(arg, cpu_env);
rn = "MVPControl";
break;
case 2:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_mvpconf0(arg, cpu_env);
rn = "MVPConf0";
break;
case 3:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_mvpconf1(arg, cpu_env);
rn = "MVPConf1";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 1:
switch (sel) {
case 0:
+ CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
gen_helper_mfc0_random(arg, cpu_env);
rn = "Random";
break;
case 1:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
rn = "VPEControl";
break;
case 2:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
rn = "VPEConf0";
break;
case 3:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
rn = "VPEConf1";
break;
case 4:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
rn = "YQMask";
break;
case 5:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
rn = "VPESchedule";
break;
case 6:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
rn = "VPEScheFBack";
break;
case 7:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
rn = "VPEOpt";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 2:
@@ -5948,42 +5943,42 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EntryLo0";
break;
case 1:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tcstatus(arg, cpu_env);
rn = "TCStatus";
break;
case 2:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mfc0_tcbind(arg, cpu_env);
rn = "TCBind";
break;
case 3:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_dmfc0_tcrestart(arg, cpu_env);
rn = "TCRestart";
break;
case 4:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_dmfc0_tchalt(arg, cpu_env);
rn = "TCHalt";
break;
case 5:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_dmfc0_tccontext(arg, cpu_env);
rn = "TCContext";
break;
case 6:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_dmfc0_tcschedule(arg, cpu_env);
rn = "TCSchedule";
break;
case 7:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_dmfc0_tcschefback(arg, cpu_env);
rn = "TCScheFBack";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 3:
@@ -5993,7 +5988,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EntryLo1";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 4:
@@ -6005,19 +6000,16 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
case 1:
// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
rn = "ContextConfig";
- goto die;
+ goto cp0_unimplemented;
// break;
case 2:
- if (ctx->ulri) {
- tcg_gen_ld_tl(arg, cpu_env,
- offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
- rn = "UserLocal";
- } else {
- tcg_gen_movi_tl(arg, 0);
- }
+ CP0_CHECK(ctx->ulri);
+ tcg_gen_ld_tl(arg, cpu_env,
+ offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
+ rn = "UserLocal";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 5:
@@ -6032,7 +6024,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "PageGrain";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 6:
@@ -6067,7 +6059,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "SRSConf4";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 7:
@@ -6078,7 +6070,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "HWREna";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 8:
@@ -6088,23 +6080,17 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "BadVAddr";
break;
case 1:
- if (ctx->bi) {
- gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
- rn = "BadInstr";
- } else {
- gen_mfc0_unimplemented(ctx, arg);
- }
+ CP0_CHECK(ctx->bi);
+ gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
+ rn = "BadInstr";
break;
case 2:
- if (ctx->bp) {
- gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
- rn = "BadInstrP";
- } else {
- gen_mfc0_unimplemented(ctx, arg);
- }
+ CP0_CHECK(ctx->bp);
+ gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
+ rn = "BadInstrP";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 9:
@@ -6124,7 +6110,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
break;
/* 6,7 are implementation dependent */
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 10:
@@ -6134,7 +6120,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EntryHi";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 11:
@@ -6145,7 +6131,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
break;
/* 6,7 are implementation dependent */
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 12:
@@ -6170,7 +6156,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "SRSMap";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 13:
@@ -6180,7 +6166,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "Cause";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 14:
@@ -6190,7 +6176,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EPC";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 15:
@@ -6205,7 +6191,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EBase";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 16:
@@ -6244,7 +6230,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "Config7";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 17:
@@ -6254,7 +6240,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "LLAddr";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 18:
@@ -6264,7 +6250,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "WatchLo";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 19:
@@ -6274,7 +6260,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "WatchHi";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 20:
@@ -6285,18 +6271,19 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "XContext";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 21:
/* Officially reserved, but sel 0 is used for R1x000 framemask */
+ CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
switch (sel) {
case 0:
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
rn = "Framemask";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 22:
@@ -6326,7 +6313,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "TraceBPC";
// break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 24:
@@ -6337,7 +6324,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "DEPC";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 25:
@@ -6375,7 +6362,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "Performance7";
// break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 26:
@@ -6390,7 +6377,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "CacheErr";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 28:
@@ -6410,7 +6397,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "DataLo";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 29:
@@ -6430,7 +6417,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "DataHi";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 30:
@@ -6440,7 +6427,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "ErrorEPC";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 31:
@@ -6451,28 +6438,25 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "DESAVE";
break;
case 2 ... 7:
- if (ctx->kscrexist & (1 << sel)) {
- tcg_gen_ld_tl(arg, cpu_env,
- offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
- rn = "KScratch";
- } else {
- gen_mfc0_unimplemented(ctx, arg);
- }
+ CP0_CHECK(ctx->kscrexist & (1 << sel));
+ tcg_gen_ld_tl(arg, cpu_env,
+ offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
+ rn = "KScratch";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
(void)rn; /* avoid a compiler warning */
LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
return;
-die:
+cp0_unimplemented:
LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
- generate_exception(ctx, EXCP_RI);
+ gen_mfc0_unimplemented(ctx, arg);
}
static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
@@ -6493,22 +6477,22 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "Index";
break;
case 1:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_mvpcontrol(cpu_env, arg);
rn = "MVPControl";
break;
case 2:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
/* ignored */
rn = "MVPConf0";
break;
case 3:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
/* ignored */
rn = "MVPConf1";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 1:
@@ -6518,42 +6502,42 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "Random";
break;
case 1:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_vpecontrol(cpu_env, arg);
rn = "VPEControl";
break;
case 2:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_vpeconf0(cpu_env, arg);
rn = "VPEConf0";
break;
case 3:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_vpeconf1(cpu_env, arg);
rn = "VPEConf1";
break;
case 4:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_yqmask(cpu_env, arg);
rn = "YQMask";
break;
case 5:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
rn = "VPESchedule";
break;
case 6:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
rn = "VPEScheFBack";
break;
case 7:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_vpeopt(cpu_env, arg);
rn = "VPEOpt";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 2:
@@ -6563,42 +6547,42 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EntryLo0";
break;
case 1:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcstatus(cpu_env, arg);
rn = "TCStatus";
break;
case 2:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcbind(cpu_env, arg);
rn = "TCBind";
break;
case 3:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcrestart(cpu_env, arg);
rn = "TCRestart";
break;
case 4:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tchalt(cpu_env, arg);
rn = "TCHalt";
break;
case 5:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tccontext(cpu_env, arg);
rn = "TCContext";
break;
case 6:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcschedule(cpu_env, arg);
rn = "TCSchedule";
break;
case 7:
- check_insn(ctx, ASE_MT);
+ CP0_CHECK(ctx->insn_flags & ASE_MT);
gen_helper_mtc0_tcschefback(cpu_env, arg);
rn = "TCScheFBack";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 3:
@@ -6608,7 +6592,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EntryLo1";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 4:
@@ -6620,17 +6604,16 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
case 1:
// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
rn = "ContextConfig";
- goto die;
+ goto cp0_unimplemented;
// break;
case 2:
- if (ctx->ulri) {
- tcg_gen_st_tl(arg, cpu_env,
- offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
- rn = "UserLocal";
- }
+ CP0_CHECK(ctx->ulri);
+ tcg_gen_st_tl(arg, cpu_env,
+ offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
+ rn = "UserLocal";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 5:
@@ -6645,7 +6628,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "PageGrain";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 6:
@@ -6680,7 +6663,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "SRSConf4";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 7:
@@ -6692,7 +6675,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "HWREna";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 8:
@@ -6710,7 +6693,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "BadInstrP";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 9:
@@ -6721,7 +6704,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
break;
/* 6,7 are implementation dependent */
default:
- goto die;
+ goto cp0_unimplemented;
}
/* Stop translation as we may have switched the execution mode */
ctx->bstate = BS_STOP;
@@ -6733,7 +6716,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EntryHi";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 11:
@@ -6744,7 +6727,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
break;
/* 6,7 are implementation dependent */
default:
- goto die;
+ goto cp0_unimplemented;
}
/* Stop translation as we may have switched the execution mode */
ctx->bstate = BS_STOP;
@@ -6781,7 +6764,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "SRSMap";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 13:
@@ -6802,7 +6785,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "Cause";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 14:
@@ -6812,7 +6795,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EPC";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 15:
@@ -6827,7 +6810,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "EBase";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 16:
@@ -6865,7 +6848,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
/* 6,7 are implementation dependent */
default:
rn = "Invalid config selector";
- goto die;
+ goto cp0_unimplemented;
}
break;
case 17:
@@ -6875,7 +6858,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "LLAddr";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 18:
@@ -6885,7 +6868,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "WatchLo";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 19:
@@ -6895,7 +6878,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "WatchHi";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 20:
@@ -6906,18 +6889,19 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "XContext";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 21:
/* Officially reserved, but sel 0 is used for R1x000 framemask */
+ CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
switch (sel) {
case 0:
gen_helper_mtc0_framemask(cpu_env, arg);
rn = "Framemask";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 22:
@@ -6958,7 +6942,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "TraceBPC";
// break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 24:
@@ -6969,7 +6953,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "DEPC";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 25:
@@ -7007,7 +6991,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "Performance7";
// break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 26:
@@ -7021,7 +7005,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "CacheErr";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 28:
@@ -7041,7 +7025,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "DataLo";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 29:
@@ -7062,7 +7046,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
break;
default:
rn = "invalid sel";
- goto die;
+ goto cp0_unimplemented;
}
break;
case 30:
@@ -7072,7 +7056,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "ErrorEPC";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
break;
case 31:
@@ -7083,20 +7067,19 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
rn = "DESAVE";
break;
case 2 ... 7:
- if (ctx->kscrexist & (1 << sel)) {
- tcg_gen_st_tl(arg, cpu_env,
- offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
- rn = "KScratch";
- }
+ CP0_CHECK(ctx->kscrexist & (1 << sel));
+ tcg_gen_st_tl(arg, cpu_env,
+ offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
+ rn = "KScratch";
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
/* Stop translation as we may have switched the execution mode */
ctx->bstate = BS_STOP;
break;
default:
- goto die;
+ goto cp0_unimplemented;
}
(void)rn; /* avoid a compiler warning */
LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
@@ -7107,9 +7090,8 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
}
return;
-die:
+cp0_unimplemented:
LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
- generate_exception(ctx, EXCP_RI);
}
#endif /* TARGET_MIPS64 */