aboutsummaryrefslogtreecommitdiff
path: root/target-mips/translate.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r--target-mips/translate.c1205
1 files changed, 1203 insertions, 2 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c
index a501a178f5..3cc8a55d4e 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -2827,6 +2827,1181 @@ die:
generate_exception(ctx, EXCP_RI);
}
+static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
+{
+ const char *rn = "invalid";
+
+ switch (reg) {
+ case 0:
+ switch (sel) {
+ case 0:
+ gen_op_mfc0_index();
+ rn = "Index";
+ break;
+ case 1:
+// gen_op_dmfc0_mvpcontrol(); /* MT ASE */
+ rn = "MVPControl";
+// break;
+ case 2:
+// gen_op_dmfc0_mvpconf0(); /* MT ASE */
+ rn = "MVPConf0";
+// break;
+ case 3:
+// gen_op_dmfc0_mvpconf1(); /* MT ASE */
+ rn = "MVPConf1";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 1:
+ switch (sel) {
+ case 0:
+ gen_op_mfc0_random();
+ rn = "Random";
+ break;
+ case 1:
+// gen_op_dmfc0_vpecontrol(); /* MT ASE */
+ rn = "VPEControl";
+// break;
+ case 2:
+// gen_op_dmfc0_vpeconf0(); /* MT ASE */
+ rn = "VPEConf0";
+// break;
+ case 3:
+// gen_op_dmfc0_vpeconf1(); /* MT ASE */
+ rn = "VPEConf1";
+// break;
+ case 4:
+// gen_op_dmfc0_YQMask(); /* MT ASE */
+ rn = "YQMask";
+// break;
+ case 5:
+// gen_op_dmfc0_vpeschedule(); /* MT ASE */
+ rn = "VPESchedule";
+// break;
+ case 6:
+// gen_op_dmfc0_vpeschefback(); /* MT ASE */
+ rn = "VPEScheFBack";
+// break;
+ case 7:
+// gen_op_dmfc0_vpeopt(); /* MT ASE */
+ rn = "VPEOpt";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 2:
+ switch (sel) {
+ case 0:
+ gen_op_dmfc0_entrylo0();
+ rn = "EntryLo0";
+ break;
+ case 1:
+// gen_op_dmfc0_tcstatus(); /* MT ASE */
+ rn = "TCStatus";
+// break;
+ case 2:
+// gen_op_dmfc0_tcbind(); /* MT ASE */
+ rn = "TCBind";
+// break;
+ case 3:
+// gen_op_dmfc0_tcrestart(); /* MT ASE */
+ rn = "TCRestart";
+// break;
+ case 4:
+// gen_op_dmfc0_tchalt(); /* MT ASE */
+ rn = "TCHalt";
+// break;
+ case 5:
+// gen_op_dmfc0_tccontext(); /* MT ASE */
+ rn = "TCContext";
+// break;
+ case 6:
+// gen_op_dmfc0_tcschedule(); /* MT ASE */
+ rn = "TCSchedule";
+// break;
+ case 7:
+// gen_op_dmfc0_tcschefback(); /* MT ASE */
+ rn = "TCScheFBack";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 3:
+ switch (sel) {
+ case 0:
+ gen_op_dmfc0_entrylo1();
+ rn = "EntryLo1";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 4:
+ switch (sel) {
+ case 0:
+ gen_op_dmfc0_context();
+ rn = "Context";
+ break;
+ case 1:
+// gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
+ rn = "ContextConfig";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 5:
+ switch (sel) {
+ case 0:
+ gen_op_mfc0_pagemask();
+ rn = "PageMask";
+ break;
+ case 1:
+ gen_op_mfc0_pagegrain();
+ rn = "PageGrain";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 6:
+ switch (sel) {
+ case 0:
+ gen_op_mfc0_wired();
+ rn = "Wired";
+ break;
+ case 1:
+// gen_op_dmfc0_srsconf0(); /* shadow registers */
+ rn = "SRSConf0";
+// break;
+ case 2:
+// gen_op_dmfc0_srsconf1(); /* shadow registers */
+ rn = "SRSConf1";
+// break;
+ case 3:
+// gen_op_dmfc0_srsconf2(); /* shadow registers */
+ rn = "SRSConf2";
+// break;
+ case 4:
+// gen_op_dmfc0_srsconf3(); /* shadow registers */
+ rn = "SRSConf3";
+// break;
+ case 5:
+// gen_op_dmfc0_srsconf4(); /* shadow registers */
+ rn = "SRSConf4";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 7:
+ switch (sel) {
+ case 0:
+ gen_op_mfc0_hwrena();
+ rn = "HWREna";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 8:
+ switch (sel) {
+ case 0:
+ gen_op_dmfc0_badvaddr();
+ rn = "BadVaddr";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 9:
+ switch (sel) {
+ case 0:
+ gen_op_mfc0_count();
+ rn = "Count";
+ break;
+ /* 6,7 are implementation dependent */
+ default:
+ goto die;
+ }
+ break;
+ case 10:
+ switch (sel) {
+ case 0:
+ gen_op_dmfc0_entryhi();
+ rn = "EntryHi";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 11:
+ switch (sel) {
+ case 0:
+ gen_op_mfc0_compare();
+ rn = "Compare";
+ break;
+ /* 6,7 are implementation dependent */
+ default:
+ goto die;
+ }
+ break;
+ case 12:
+ switch (sel) {
+ case 0:
+ gen_op_mfc0_status();
+ rn = "Status";
+ break;
+ case 1:
+ gen_op_mfc0_intctl();
+ rn = "IntCtl";
+ break;
+ case 2:
+ gen_op_mfc0_srsctl();
+ rn = "SRSCtl";
+ break;
+ case 3:
+ gen_op_mfc0_srsmap(); /* shadow registers */
+ rn = "SRSMap";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 13:
+ switch (sel) {
+ case 0:
+ gen_op_mfc0_cause();
+ rn = "Cause";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 14:
+ switch (sel) {
+ case 0:
+ gen_op_dmfc0_epc();
+ rn = "EPC";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 15:
+ switch (sel) {
+ case 0:
+ gen_op_mfc0_prid();
+ rn = "PRid";
+ break;
+ case 1:
+ gen_op_dmfc0_ebase();
+ rn = "EBase";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 16:
+ switch (sel) {
+ case 0:
+ gen_op_mfc0_config0();
+ rn = "Config";
+ break;
+ case 1:
+ gen_op_mfc0_config1();
+ rn = "Config1";
+ break;
+ case 2:
+ gen_op_mfc0_config2();
+ rn = "Config2";
+ break;
+ case 3:
+ gen_op_mfc0_config3();
+ rn = "Config3";
+ break;
+ /* 6,7 are implementation dependent */
+ default:
+ goto die;
+ }
+ break;
+ case 17:
+ switch (sel) {
+ case 0:
+ gen_op_dmfc0_lladdr();
+ rn = "LLAddr";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 18:
+ switch (sel) {
+ case 0:
+ gen_op_dmfc0_watchlo0();
+ rn = "WatchLo";
+ break;
+ case 1:
+// gen_op_dmfc0_watchlo1();
+ rn = "WatchLo1";
+// break;
+ case 2:
+// gen_op_dmfc0_watchlo2();
+ rn = "WatchLo2";
+// break;
+ case 3:
+// gen_op_dmfc0_watchlo3();
+ rn = "WatchLo3";
+// break;
+ case 4:
+// gen_op_dmfc0_watchlo4();
+ rn = "WatchLo4";
+// break;
+ case 5:
+// gen_op_dmfc0_watchlo5();
+ rn = "WatchLo5";
+// break;
+ case 6:
+// gen_op_dmfc0_watchlo6();
+ rn = "WatchLo6";
+// break;
+ case 7:
+// gen_op_dmfc0_watchlo7();
+ rn = "WatchLo7";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 19:
+ switch (sel) {
+ case 0:
+ gen_op_mfc0_watchhi0();
+ rn = "WatchHi";
+ break;
+ case 1:
+// gen_op_mfc0_watchhi1();
+ rn = "WatchHi1";
+// break;
+ case 2:
+// gen_op_mfc0_watchhi2();
+ rn = "WatchHi2";
+// break;
+ case 3:
+// gen_op_mfc0_watchhi3();
+ rn = "WatchHi3";
+// break;
+ case 4:
+// gen_op_mfc0_watchhi4();
+ rn = "WatchHi4";
+// break;
+ case 5:
+// gen_op_mfc0_watchhi5();
+ rn = "WatchHi5";
+// break;
+ case 6:
+// gen_op_mfc0_watchhi6();
+ rn = "WatchHi6";
+// break;
+ case 7:
+// gen_op_mfc0_watchhi7();
+ rn = "WatchHi7";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 20:
+ switch (sel) {
+ case 0:
+ /* 64 bit MMU only */
+ gen_op_dmfc0_xcontext();
+ rn = "XContext";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 21:
+ /* Officially reserved, but sel 0 is used for R1x000 framemask */
+ switch (sel) {
+ case 0:
+ gen_op_mfc0_framemask();
+ rn = "Framemask";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 22:
+ /* ignored */
+ rn = "'Diagnostic"; /* implementation dependent */
+ break;
+ case 23:
+ switch (sel) {
+ case 0:
+ gen_op_mfc0_debug(); /* EJTAG support */
+ rn = "Debug";
+ break;
+ case 1:
+// gen_op_dmfc0_tracecontrol(); /* PDtrace support */
+ rn = "TraceControl";
+// break;
+ case 2:
+// gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
+ rn = "TraceControl2";
+// break;
+ case 3:
+// gen_op_dmfc0_usertracedata(); /* PDtrace support */
+ rn = "UserTraceData";
+// break;
+ case 4:
+// gen_op_dmfc0_debug(); /* PDtrace support */
+ rn = "TraceBPC";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 24:
+ switch (sel) {
+ case 0:
+ gen_op_dmfc0_depc(); /* EJTAG support */
+ rn = "DEPC";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 25:
+ switch (sel) {
+ case 0:
+ gen_op_mfc0_performance0();
+ rn = "Performance0";
+ break;
+ case 1:
+// gen_op_dmfc0_performance1();
+ rn = "Performance1";
+// break;
+ case 2:
+// gen_op_dmfc0_performance2();
+ rn = "Performance2";
+// break;
+ case 3:
+// gen_op_dmfc0_performance3();
+ rn = "Performance3";
+// break;
+ case 4:
+// gen_op_dmfc0_performance4();
+ rn = "Performance4";
+// break;
+ case 5:
+// gen_op_dmfc0_performance5();
+ rn = "Performance5";
+// break;
+ case 6:
+// gen_op_dmfc0_performance6();
+ rn = "Performance6";
+// break;
+ case 7:
+// gen_op_dmfc0_performance7();
+ rn = "Performance7";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 26:
+ rn = "ECC";
+ break;
+ case 27:
+ switch (sel) {
+ /* ignored */
+ case 0 ... 3:
+ rn = "CacheErr";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 28:
+ switch (sel) {
+ case 0:
+ case 2:
+ case 4:
+ case 6:
+ gen_op_mfc0_taglo();
+ rn = "TagLo";
+ break;
+ case 1:
+ case 3:
+ case 5:
+ case 7:
+ gen_op_mfc0_datalo();
+ rn = "DataLo";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 29:
+ switch (sel) {
+ case 0:
+ case 2:
+ case 4:
+ case 6:
+ gen_op_mfc0_taghi();
+ rn = "TagHi";
+ break;
+ case 1:
+ case 3:
+ case 5:
+ case 7:
+ gen_op_mfc0_datahi();
+ rn = "DataHi";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 30:
+ switch (sel) {
+ case 0:
+ gen_op_dmfc0_errorepc();
+ rn = "ErrorEPC";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 31:
+ switch (sel) {
+ case 0:
+ gen_op_mfc0_desave(); /* EJTAG support */
+ rn = "DESAVE";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ default:
+ goto die;
+ }
+#if defined MIPS_DEBUG_DISAS
+ if (loglevel & CPU_LOG_TB_IN_ASM) {
+ fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
+ rn, reg, sel);
+ }
+#endif
+ return;
+
+die:
+#if defined MIPS_DEBUG_DISAS
+ if (loglevel & CPU_LOG_TB_IN_ASM) {
+ fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
+ rn, reg, sel);
+ }
+#endif
+ generate_exception(ctx, EXCP_RI);
+}
+
+static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
+{
+ const char *rn = "invalid";
+
+ switch (reg) {
+ case 0:
+ switch (sel) {
+ case 0:
+ gen_op_mtc0_index();
+ rn = "Index";
+ break;
+ case 1:
+// gen_op_dmtc0_mvpcontrol(); /* MT ASE */
+ rn = "MVPControl";
+// break;
+ case 2:
+// gen_op_dmtc0_mvpconf0(); /* MT ASE */
+ rn = "MVPConf0";
+// break;
+ case 3:
+// gen_op_dmtc0_mvpconf1(); /* MT ASE */
+ rn = "MVPConf1";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 1:
+ switch (sel) {
+ case 0:
+ /* ignored */
+ rn = "Random";
+ break;
+ case 1:
+// gen_op_dmtc0_vpecontrol(); /* MT ASE */
+ rn = "VPEControl";
+// break;
+ case 2:
+// gen_op_dmtc0_vpeconf0(); /* MT ASE */
+ rn = "VPEConf0";
+// break;
+ case 3:
+// gen_op_dmtc0_vpeconf1(); /* MT ASE */
+ rn = "VPEConf1";
+// break;
+ case 4:
+// gen_op_dmtc0_YQMask(); /* MT ASE */
+ rn = "YQMask";
+// break;
+ case 5:
+// gen_op_dmtc0_vpeschedule(); /* MT ASE */
+ rn = "VPESchedule";
+// break;
+ case 6:
+// gen_op_dmtc0_vpeschefback(); /* MT ASE */
+ rn = "VPEScheFBack";
+// break;
+ case 7:
+// gen_op_dmtc0_vpeopt(); /* MT ASE */
+ rn = "VPEOpt";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 2:
+ switch (sel) {
+ case 0:
+ gen_op_dmtc0_entrylo0();
+ rn = "EntryLo0";
+ break;
+ case 1:
+// gen_op_dmtc0_tcstatus(); /* MT ASE */
+ rn = "TCStatus";
+// break;
+ case 2:
+// gen_op_dmtc0_tcbind(); /* MT ASE */
+ rn = "TCBind";
+// break;
+ case 3:
+// gen_op_dmtc0_tcrestart(); /* MT ASE */
+ rn = "TCRestart";
+// break;
+ case 4:
+// gen_op_dmtc0_tchalt(); /* MT ASE */
+ rn = "TCHalt";
+// break;
+ case 5:
+// gen_op_dmtc0_tccontext(); /* MT ASE */
+ rn = "TCContext";
+// break;
+ case 6:
+// gen_op_dmtc0_tcschedule(); /* MT ASE */
+ rn = "TCSchedule";
+// break;
+ case 7:
+// gen_op_dmtc0_tcschefback(); /* MT ASE */
+ rn = "TCScheFBack";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 3:
+ switch (sel) {
+ case 0:
+ gen_op_dmtc0_entrylo1();
+ rn = "EntryLo1";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 4:
+ switch (sel) {
+ case 0:
+ gen_op_dmtc0_context();
+ rn = "Context";
+ break;
+ case 1:
+// gen_op_dmtc0_contextconfig(); /* SmartMIPS ASE */
+ rn = "ContextConfig";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 5:
+ switch (sel) {
+ case 0:
+ gen_op_mtc0_pagemask();
+ rn = "PageMask";
+ break;
+ case 1:
+ gen_op_mtc0_pagegrain();
+ rn = "PageGrain";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 6:
+ switch (sel) {
+ case 0:
+ gen_op_mtc0_wired();
+ rn = "Wired";
+ break;
+ case 1:
+// gen_op_dmtc0_srsconf0(); /* shadow registers */
+ rn = "SRSConf0";
+// break;
+ case 2:
+// gen_op_dmtc0_srsconf1(); /* shadow registers */
+ rn = "SRSConf1";
+// break;
+ case 3:
+// gen_op_dmtc0_srsconf2(); /* shadow registers */
+ rn = "SRSConf2";
+// break;
+ case 4:
+// gen_op_dmtc0_srsconf3(); /* shadow registers */
+ rn = "SRSConf3";
+// break;
+ case 5:
+// gen_op_dmtc0_srsconf4(); /* shadow registers */
+ rn = "SRSConf4";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 7:
+ switch (sel) {
+ case 0:
+ gen_op_mtc0_hwrena();
+ rn = "HWREna";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 8:
+ /* ignored */
+ rn = "BadVaddr";
+ break;
+ case 9:
+ switch (sel) {
+ case 0:
+ gen_op_mtc0_count();
+ rn = "Count";
+ break;
+ /* 6,7 are implementation dependent */
+ default:
+ goto die;
+ }
+ /* Stop translation as we may have switched the execution mode */
+ ctx->bstate = BS_STOP;
+ break;
+ case 10:
+ switch (sel) {
+ case 0:
+ gen_op_mtc0_entryhi();
+ rn = "EntryHi";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 11:
+ switch (sel) {
+ case 0:
+ gen_op_mtc0_compare();
+ rn = "Compare";
+ break;
+ /* 6,7 are implementation dependent */
+ default:
+ goto die;
+ }
+ /* Stop translation as we may have switched the execution mode */
+ ctx->bstate = BS_STOP;
+ break;
+ case 12:
+ switch (sel) {
+ case 0:
+ gen_op_mtc0_status();
+ rn = "Status";
+ break;
+ case 1:
+ gen_op_mtc0_intctl();
+ rn = "IntCtl";
+ break;
+ case 2:
+ gen_op_mtc0_srsctl();
+ rn = "SRSCtl";
+ break;
+ case 3:
+ gen_op_mtc0_srsmap(); /* shadow registers */
+ 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) {
+ case 0:
+ gen_op_mtc0_cause();
+ rn = "Cause";
+ break;
+ default:
+ goto die;
+ }
+ /* Stop translation as we may have switched the execution mode */
+ ctx->bstate = BS_STOP;
+ break;
+ case 14:
+ switch (sel) {
+ case 0:
+ gen_op_dmtc0_epc();
+ rn = "EPC";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 15:
+ switch (sel) {
+ case 0:
+ /* ignored */
+ rn = "PRid";
+ break;
+ case 1:
+ gen_op_dmtc0_ebase();
+ rn = "EBase";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 16:
+ switch (sel) {
+ case 0:
+ gen_op_mtc0_config0();
+ rn = "Config";
+ break;
+ case 1:
+ /* ignored */
+ rn = "Config1";
+ break;
+ case 2:
+ gen_op_mtc0_config2();
+ rn = "Config2";
+ break;
+ case 3:
+ /* ignored */
+ rn = "Config3";
+ break;
+ /* 6,7 are implementation dependent */
+ default:
+ rn = "Invalid config selector";
+ goto die;
+ }
+ /* Stop translation as we may have switched the execution mode */
+ ctx->bstate = BS_STOP;
+ break;
+ case 17:
+ switch (sel) {
+ case 0:
+ /* ignored */
+ rn = "LLAddr";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 18:
+ switch (sel) {
+ case 0:
+ gen_op_dmtc0_watchlo0();
+ rn = "WatchLo";
+ break;
+ case 1:
+// gen_op_dmtc0_watchlo1();
+ rn = "WatchLo1";
+// break;
+ case 2:
+// gen_op_dmtc0_watchlo2();
+ rn = "WatchLo2";
+// break;
+ case 3:
+// gen_op_dmtc0_watchlo3();
+ rn = "WatchLo3";
+// break;
+ case 4:
+// gen_op_dmtc0_watchlo4();
+ rn = "WatchLo4";
+// break;
+ case 5:
+// gen_op_dmtc0_watchlo5();
+ rn = "WatchLo5";
+// break;
+ case 6:
+// gen_op_dmtc0_watchlo6();
+ rn = "WatchLo6";
+// break;
+ case 7:
+// gen_op_dmtc0_watchlo7();
+ rn = "WatchLo7";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 19:
+ switch (sel) {
+ case 0:
+ gen_op_mtc0_watchhi0();
+ rn = "WatchHi";
+ break;
+ case 1:
+// gen_op_dmtc0_watchhi1();
+ rn = "WatchHi1";
+// break;
+ case 2:
+// gen_op_dmtc0_watchhi2();
+ rn = "WatchHi2";
+// break;
+ case 3:
+// gen_op_dmtc0_watchhi3();
+ rn = "WatchHi3";
+// break;
+ case 4:
+// gen_op_dmtc0_watchhi4();
+ rn = "WatchHi4";
+// break;
+ case 5:
+// gen_op_dmtc0_watchhi5();
+ rn = "WatchHi5";
+// break;
+ case 6:
+// gen_op_dmtc0_watchhi6();
+ rn = "WatchHi6";
+// break;
+ case 7:
+// gen_op_dmtc0_watchhi7();
+ rn = "WatchHi7";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 20:
+ switch (sel) {
+ case 0:
+ /* 64 bit MMU only */
+ gen_op_dmtc0_xcontext();
+ rn = "XContext";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 21:
+ /* Officially reserved, but sel 0 is used for R1x000 framemask */
+ switch (sel) {
+ case 0:
+ gen_op_mtc0_framemask();
+ rn = "Framemask";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 22:
+ /* ignored */
+ rn = "Diagnostic"; /* implementation dependent */
+ break;
+ case 23:
+ switch (sel) {
+ case 0:
+ gen_op_mtc0_debug(); /* EJTAG support */
+ rn = "Debug";
+ break;
+ case 1:
+// gen_op_dmtc0_tracecontrol(); /* PDtrace support */
+ rn = "TraceControl";
+// break;
+ case 2:
+// gen_op_dmtc0_tracecontrol2(); /* PDtrace support */
+ rn = "TraceControl2";
+// break;
+ case 3:
+// gen_op_dmtc0_usertracedata(); /* PDtrace support */
+ rn = "UserTraceData";
+// break;
+ case 4:
+// gen_op_dmtc0_debug(); /* PDtrace support */
+ 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) {
+ case 0:
+ gen_op_dmtc0_depc(); /* EJTAG support */
+ rn = "DEPC";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 25:
+ switch (sel) {
+ case 0:
+ gen_op_mtc0_performance0();
+ rn = "Performance0";
+ break;
+ case 1:
+// gen_op_dmtc0_performance1();
+ rn = "Performance1";
+// break;
+ case 2:
+// gen_op_dmtc0_performance2();
+ rn = "Performance2";
+// break;
+ case 3:
+// gen_op_dmtc0_performance3();
+ rn = "Performance3";
+// break;
+ case 4:
+// gen_op_dmtc0_performance4();
+ rn = "Performance4";
+// break;
+ case 5:
+// gen_op_dmtc0_performance5();
+ rn = "Performance5";
+// break;
+ case 6:
+// gen_op_dmtc0_performance6();
+ rn = "Performance6";
+// break;
+ case 7:
+// gen_op_dmtc0_performance7();
+ rn = "Performance7";
+// break;
+ default:
+ goto die;
+ }
+ break;
+ case 26:
+ /* ignored */
+ rn = "ECC";
+ break;
+ case 27:
+ switch (sel) {
+ case 0 ... 3:
+ /* ignored */
+ rn = "CacheErr";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 28:
+ switch (sel) {
+ case 0:
+ case 2:
+ case 4:
+ case 6:
+ gen_op_mtc0_taglo();
+ rn = "TagLo";
+ break;
+ case 1:
+ case 3:
+ case 5:
+ case 7:
+ gen_op_mtc0_datalo();
+ rn = "DataLo";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 29:
+ switch (sel) {
+ case 0:
+ case 2:
+ case 4:
+ case 6:
+ gen_op_mtc0_taghi();
+ rn = "TagHi";
+ break;
+ case 1:
+ case 3:
+ case 5:
+ case 7:
+ gen_op_mtc0_datahi();
+ rn = "DataHi";
+ break;
+ default:
+ rn = "invalid sel";
+ goto die;
+ }
+ break;
+ case 30:
+ switch (sel) {
+ case 0:
+ gen_op_dmtc0_errorepc();
+ rn = "ErrorEPC";
+ break;
+ default:
+ goto die;
+ }
+ break;
+ case 31:
+ switch (sel) {
+ case 0:
+ gen_op_mtc0_desave(); /* EJTAG support */
+ rn = "DESAVE";
+ break;
+ default:
+ goto die;
+ }
+ /* Stop translation as we may have switched the execution mode */
+ ctx->bstate = BS_STOP;
+ break;
+ default:
+ goto die;
+ }
+#if defined MIPS_DEBUG_DISAS
+ if (loglevel & CPU_LOG_TB_IN_ASM) {
+ fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
+ rn, reg, sel);
+ }
+#endif
+ return;
+
+die:
+#if defined MIPS_DEBUG_DISAS
+ if (loglevel & CPU_LOG_TB_IN_ASM) {
+ fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
+ rn, reg, sel);
+ }
+#endif
+ generate_exception(ctx, EXCP_RI);
+}
+
static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
{
const char *opn = "unk";
@@ -2854,7 +4029,7 @@ static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
break;
case OPC_MTC0:
/* If we get an exception, we want to restart at next instruction */
- /* XXX: breaks for mtc in delay slot */
+ /* XXX: breaks for mtc in delay slot */
ctx->pc += 4;
save_cpu_state(ctx, 1);
ctx->pc -= 4;
@@ -2862,6 +4037,25 @@ static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
gen_mtc0(ctx, rd, ctx->opcode & 0x7);
opn = "mtc0";
break;
+ case OPC_DMFC0:
+ if (rt == 0) {
+ /* Treat as NOP */
+ return;
+ }
+ gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
+ gen_op_store_T0_gpr(rt);
+ opn = "dmfc0";
+ break;
+ case OPC_DMTC0:
+ /* If we get an exception, we want to restart at next instruction */
+ /* XXX: breaks for dmtc in delay slot */
+ ctx->pc += 4;
+ save_cpu_state(ctx, 1);
+ ctx->pc -= 4;
+ GEN_LOAD_REG_TN(T0, rt);
+ gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
+ opn = "dmtc0";
+ break;
#if defined(MIPS_USES_R4K_TLB)
case OPC_TLBWI:
gen_op_tlbwi();
@@ -3002,6 +4196,9 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
gen_op_ctc1();
opn = "ctc1";
break;
+ case OPC_DMFC1:
+ case OPC_DMTC1:
+ /* Not implemented, fallthrough. */
default:
if (loglevel & CPU_LOG_TB_IN_ASM) {
fprintf(logfile, "Invalid CP1 opcode: %08x %03x %03x %03x\n",
@@ -3703,6 +4900,10 @@ static void decode_opc (DisasContext *ctx)
case OPC_CFC1:
case OPC_MTC1:
case OPC_CTC1:
+#ifdef MIPS_HAS_MIPS64
+ case OPC_DMFC1:
+ case OPC_DMTC1:
+#endif
gen_cp1(ctx, op1, rt, rd);
break;
case OPC_BC1:
@@ -4099,7 +5300,7 @@ void cpu_reset (CPUMIPSState *env)
}
env->PC = (int32_t)0xBFC00000;
#if defined (MIPS_USES_R4K_TLB)
- env->CP0_random = MIPS_TLB_NB - 1;
+ env->CP0_Random = MIPS_TLB_NB - 1;
env->tlb_in_use = MIPS_TLB_NB;
#endif
env->CP0_Wired = 0;