aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--target-mips/cpu.h67
-rw-r--r--target-mips/op.c236
-rw-r--r--target-mips/op_helper.c12
-rw-r--r--target-mips/translate.c1205
4 files changed, 1434 insertions, 86 deletions
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index c1001c7fce..8781e3098d 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -44,7 +44,7 @@ union fpr_t {
typedef struct tlb_t tlb_t;
struct tlb_t {
target_ulong VPN;
- uint_fast32_t PageMask;
+ uint32_t PageMask;
uint_fast8_t ASID;
uint_fast16_t G:1;
uint_fast16_t C0:3;
@@ -110,20 +110,20 @@ struct CPUMIPSState {
tlb_t tlb[MIPS_TLB_MAX];
uint32_t tlb_in_use;
#endif
- uint32_t CP0_index;
- uint32_t CP0_random;
- uint64_t CP0_EntryLo0;
- uint64_t CP0_EntryLo1;
- uint64_t CP0_Context;
- uint32_t CP0_PageMask;
- uint32_t CP0_PageGrain;
- uint32_t CP0_Wired;
- uint32_t CP0_HWREna;
+ int32_t CP0_Index;
+ int32_t CP0_Random;
+ target_ulong CP0_EntryLo0;
+ target_ulong CP0_EntryLo1;
+ target_ulong CP0_Context;
+ int32_t CP0_PageMask;
+ int32_t CP0_PageGrain;
+ int32_t CP0_Wired;
+ int32_t CP0_HWREna;
target_ulong CP0_BadVAddr;
- uint32_t CP0_Count;
- uint64_t CP0_EntryHi;
- uint32_t CP0_Compare;
- uint32_t CP0_Status;
+ int32_t CP0_Count;
+ target_ulong CP0_EntryHi;
+ int32_t CP0_Compare;
+ int32_t CP0_Status;
#define CP0St_CU3 31
#define CP0St_CU2 30
#define CP0St_CU1 29
@@ -146,9 +146,10 @@ struct CPUMIPSState {
#define CP0St_ERL 2
#define CP0St_EXL 1
#define CP0St_IE 0
- uint32_t CP0_IntCtl;
- uint32_t CP0_SRSCtl;
- uint32_t CP0_Cause;
+ int32_t CP0_IntCtl;
+ int32_t CP0_SRSCtl;
+ int32_t CP0_SRSMap;
+ int32_t CP0_Cause;
#define CP0Ca_BD 31
#define CP0Ca_TI 30
#define CP0Ca_CE 28
@@ -159,9 +160,9 @@ struct CPUMIPSState {
#define CP0Ca_IP 8
#define CP0Ca_EC 2
target_ulong CP0_EPC;
- uint32_t CP0_PRid;
+ int32_t CP0_PRid;
target_ulong CP0_EBase;
- uint32_t CP0_Config0;
+ int32_t CP0_Config0;
#define CP0C0_M 31
#define CP0C0_K23 28
#define CP0C0_KU 25
@@ -174,7 +175,7 @@ struct CPUMIPSState {
#define CP0C0_MT 7
#define CP0C0_VI 3
#define CP0C0_K0 0
- uint32_t CP0_Config1;
+ int32_t CP0_Config1;
#define CP0C1_M 31
#define CP0C1_MMU 25
#define CP0C1_IS 22
@@ -190,7 +191,7 @@ struct CPUMIPSState {
#define CP0C1_CA 2
#define CP0C1_EP 1
#define CP0C1_FP 0
- uint32_t CP0_Config2;
+ int32_t CP0_Config2;
#define CP0C2_M 31
#define CP0C2_TU 28
#define CP0C2_TS 24
@@ -200,7 +201,7 @@ struct CPUMIPSState {
#define CP0C2_SS 8
#define CP0C2_SL 4
#define CP0C2_SA 0
- uint32_t CP0_Config3;
+ int32_t CP0_Config3;
#define CP0C3_M 31
#define CP0C3_DSPP 10
#define CP0C3_LPA 7
@@ -211,11 +212,11 @@ struct CPUMIPSState {
#define CP0C3_SM 1
#define CP0C3_TL 0
target_ulong CP0_LLAddr;
- uint32_t CP0_WatchLo;
- uint32_t CP0_WatchHi;
- uint32_t CP0_XContext;
- uint32_t CP0_Framemask;
- uint32_t CP0_Debug;
+ target_ulong CP0_WatchLo;
+ int32_t CP0_WatchHi;
+ target_ulong CP0_XContext;
+ int32_t CP0_Framemask;
+ int32_t CP0_Debug;
#define CPDB_DBD 31
#define CP0DB_DM 30
#define CP0DB_LSNM 28
@@ -235,13 +236,13 @@ struct CPUMIPSState {
#define CP0DB_DBp 1
#define CP0DB_DSS 0
target_ulong CP0_DEPC;
- uint32_t CP0_Performance0;
- uint32_t CP0_TagLo;
- uint32_t CP0_DataLo;
- uint32_t CP0_TagHi;
- uint32_t CP0_DataHi;
+ int32_t CP0_Performance0;
+ int32_t CP0_TagLo;
+ int32_t CP0_DataLo;
+ int32_t CP0_TagHi;
+ int32_t CP0_DataHi;
target_ulong CP0_ErrorEPC;
- uint32_t CP0_DESAVE;
+ int32_t CP0_DESAVE;
/* Qemu */
int interrupt_request;
jmp_buf jmp_env;
diff --git a/target-mips/op.c b/target-mips/op.c
index 0550d27869..dec9f31ade 100644
--- a/target-mips/op.c
+++ b/target-mips/op.c
@@ -1032,7 +1032,7 @@ void op_jnz_T2 (void)
/* CP0 functions */
void op_mfc0_index (void)
{
- T0 = (int32_t)(env->CP0_index);
+ T0 = env->CP0_Index;
RETURN();
}
@@ -1044,49 +1044,49 @@ void op_mfc0_random (void)
void op_mfc0_entrylo0 (void)
{
- T0 = env->CP0_EntryLo0;
+ T0 = (int32_t)env->CP0_EntryLo0;
RETURN();
}
void op_mfc0_entrylo1 (void)
{
- T0 = env->CP0_EntryLo1;
+ T0 = (int32_t)env->CP0_EntryLo1;
RETURN();
}
void op_mfc0_context (void)
{
- T0 = env->CP0_Context;
+ T0 = (int32_t)env->CP0_Context;
RETURN();
}
void op_mfc0_pagemask (void)
{
- T0 = (int32_t)env->CP0_PageMask;
+ T0 = env->CP0_PageMask;
RETURN();
}
void op_mfc0_pagegrain (void)
{
- T0 = (int32_t)env->CP0_PageGrain;
+ T0 = env->CP0_PageGrain;
RETURN();
}
void op_mfc0_wired (void)
{
- T0 = (int32_t)env->CP0_Wired;
+ T0 = env->CP0_Wired;
RETURN();
}
void op_mfc0_hwrena (void)
{
- T0 = (int32_t)env->CP0_HWREna;
+ T0 = env->CP0_HWREna;
RETURN();
}
void op_mfc0_badvaddr (void)
{
- T0 = env->CP0_BadVAddr;
+ T0 = (int32_t)env->CP0_BadVAddr;
RETURN();
}
@@ -1098,19 +1098,19 @@ void op_mfc0_count (void)
void op_mfc0_entryhi (void)
{
- T0 = env->CP0_EntryHi;
+ T0 = (int32_t)env->CP0_EntryHi;
RETURN();
}
void op_mfc0_compare (void)
{
- T0 = (int32_t)env->CP0_Compare;
+ T0 = env->CP0_Compare;
RETURN();
}
void op_mfc0_status (void)
{
- T0 = (int32_t)env->CP0_Status;
+ T0 = env->CP0_Status;
if (env->hflags & MIPS_HFLAG_UM)
T0 |= (1 << CP0St_UM);
if (env->hflags & MIPS_HFLAG_ERL)
@@ -1122,67 +1122,73 @@ void op_mfc0_status (void)
void op_mfc0_intctl (void)
{
- T0 = (int32_t)env->CP0_IntCtl;
+ T0 = env->CP0_IntCtl;
RETURN();
}
void op_mfc0_srsctl (void)
{
- T0 = (int32_t)env->CP0_SRSCtl;
+ T0 = env->CP0_SRSCtl;
+ RETURN();
+}
+
+void op_mfc0_srsmap (void)
+{
+ T0 = env->CP0_SRSMap;
RETURN();
}
void op_mfc0_cause (void)
{
- T0 = (int32_t)env->CP0_Cause;
+ T0 = env->CP0_Cause;
RETURN();
}
void op_mfc0_epc (void)
{
- T0 = env->CP0_EPC;
+ T0 = (int32_t)env->CP0_EPC;
RETURN();
}
void op_mfc0_prid (void)
{
- T0 = (int32_t)env->CP0_PRid;
+ T0 = env->CP0_PRid;
RETURN();
}
void op_mfc0_ebase (void)
{
- T0 = env->CP0_EBase;
+ T0 = (int32_t)env->CP0_EBase;
RETURN();
}
void op_mfc0_config0 (void)
{
- T0 = (int32_t)env->CP0_Config0;
+ T0 = env->CP0_Config0;
RETURN();
}
void op_mfc0_config1 (void)
{
- T0 = (int32_t)env->CP0_Config1;
+ T0 = env->CP0_Config1;
RETURN();
}
void op_mfc0_config2 (void)
{
- T0 = (int32_t)env->CP0_Config2;
+ T0 = env->CP0_Config2;
RETURN();
}
void op_mfc0_config3 (void)
{
- T0 = (int32_t)env->CP0_Config3;
+ T0 = env->CP0_Config3;
RETURN();
}
void op_mfc0_lladdr (void)
{
- T0 = env->CP0_LLAddr >> 4;
+ T0 = (int32_t)env->CP0_LLAddr >> 4;
RETURN();
}
@@ -1194,13 +1200,13 @@ void op_mfc0_watchlo0 (void)
void op_mfc0_watchhi0 (void)
{
- T0 = (int32_t)env->CP0_WatchHi;
+ T0 = env->CP0_WatchHi;
RETURN();
}
void op_mfc0_xcontext (void)
{
- T0 = env->CP0_XContext;
+ T0 = (int32_t)env->CP0_XContext;
RETURN();
}
@@ -1212,7 +1218,7 @@ void op_mfc0_framemask (void)
void op_mfc0_debug (void)
{
- T0 = (int32_t)env->CP0_Debug;
+ T0 = env->CP0_Debug;
if (env->hflags & MIPS_HFLAG_DM)
T0 |= 1 << CP0DB_DM;
RETURN();
@@ -1220,55 +1226,55 @@ void op_mfc0_debug (void)
void op_mfc0_depc (void)
{
- T0 = env->CP0_DEPC;
+ T0 = (int32_t)env->CP0_DEPC;
RETURN();
}
void op_mfc0_performance0 (void)
{
- T0 = (int32_t)env->CP0_Performance0;
+ T0 = env->CP0_Performance0;
RETURN();
}
void op_mfc0_taglo (void)
{
- T0 = (int32_t)env->CP0_TagLo;
+ T0 = env->CP0_TagLo;
RETURN();
}
void op_mfc0_datalo (void)
{
- T0 = (int32_t)env->CP0_DataLo;
+ T0 = env->CP0_DataLo;
RETURN();
}
void op_mfc0_taghi (void)
{
- T0 = (int32_t)env->CP0_TagHi;
+ T0 = env->CP0_TagHi;
RETURN();
}
void op_mfc0_datahi (void)
{
- T0 = (int32_t)env->CP0_DataHi;
+ T0 = env->CP0_DataHi;
RETURN();
}
void op_mfc0_errorepc (void)
{
- T0 = env->CP0_ErrorEPC;
+ T0 = (int32_t)env->CP0_ErrorEPC;
RETURN();
}
void op_mfc0_desave (void)
{
- T0 = (int32_t)env->CP0_DESAVE;
+ T0 = env->CP0_DESAVE;
RETURN();
}
void op_mtc0_index (void)
{
- env->CP0_index = (env->CP0_index & 0x80000000) | (T0 & (MIPS_TLB_NB - 1));
+ env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (MIPS_TLB_NB - 1));
RETURN();
}
@@ -1276,7 +1282,7 @@ void op_mtc0_entrylo0 (void)
{
/* Large physaddr not implemented */
/* 1k pages not implemented */
- env->CP0_EntryLo0 = T0 & (int32_t)0x3FFFFFFF;
+ env->CP0_EntryLo0 = (int32_t)T0 & 0x3FFFFFFF;
RETURN();
}
@@ -1284,7 +1290,7 @@ void op_mtc0_entrylo1 (void)
{
/* Large physaddr not implemented */
/* 1k pages not implemented */
- env->CP0_EntryLo1 = T0 & (int32_t)0x3FFFFFFF;
+ env->CP0_EntryLo1 = (int32_t)T0 & 0x3FFFFFFF;
RETURN();
}
@@ -1334,7 +1340,7 @@ void op_mtc0_entryhi (void)
/* 1k pages not implemented */
/* Ignore MIPS64 TLB for now */
- val = T0 & (int32_t)0xFFFFE0FF;
+ val = (int32_t)T0 & 0xFFFFE0FF;
old = env->CP0_EntryHi;
env->CP0_EntryHi = val;
/* If the ASID changes, flush qemu's TLB. */
@@ -1353,7 +1359,7 @@ void op_mtc0_status (void)
{
uint32_t val, old, mask;
- val = T0 & (int32_t)0xFA78FF01;
+ val = (int32_t)T0 & 0xFA78FF01;
old = env->CP0_Status;
if (T0 & (1 << CP0St_UM))
env->hflags |= MIPS_HFLAG_UM;
@@ -1400,6 +1406,13 @@ void op_mtc0_srsctl (void)
RETURN();
}
+void op_mtc0_srsmap (void)
+{
+ /* shadow registers not implemented */
+ env->CP0_SRSMap = 0;
+ RETURN();
+}
+
void op_mtc0_cause (void)
{
uint32_t val, old;
@@ -1423,7 +1436,7 @@ void op_mtc0_cause (void)
void op_mtc0_epc (void)
{
- env->CP0_EPC = T0;
+ env->CP0_EPC = (int32_t)T0;
RETURN();
}
@@ -1455,7 +1468,7 @@ void op_mtc0_config2 (void)
void op_mtc0_watchlo0 (void)
{
- env->CP0_WatchLo = T0;
+ env->CP0_WatchLo = (int32_t)T0;
RETURN();
}
@@ -1467,7 +1480,7 @@ void op_mtc0_watchhi0 (void)
void op_mtc0_xcontext (void)
{
- env->CP0_XContext = T0; /* XXX */
+ env->CP0_XContext = (int32_t)T0; /* XXX */
RETURN();
}
@@ -1489,7 +1502,7 @@ void op_mtc0_debug (void)
void op_mtc0_depc (void)
{
- env->CP0_DEPC = T0;
+ env->CP0_DEPC = (int32_t)T0;
RETURN();
}
@@ -1501,7 +1514,7 @@ void op_mtc0_performance0 (void)
void op_mtc0_taglo (void)
{
- env->CP0_TagLo = T0 & (int32_t)0xFFFFFCF6;
+ env->CP0_TagLo = T0 & 0xFFFFFCF6;
RETURN();
}
@@ -1525,7 +1538,7 @@ void op_mtc0_datahi (void)
void op_mtc0_errorepc (void)
{
- env->CP0_ErrorEPC = T0;
+ env->CP0_ErrorEPC = (int32_t)T0;
RETURN();
}
@@ -1535,6 +1548,139 @@ void op_mtc0_desave (void)
RETURN();
}
+void op_dmfc0_entrylo0 (void)
+{
+ T0 = env->CP0_EntryLo0;
+ RETURN();
+}
+
+void op_dmfc0_entrylo1 (void)
+{
+ T0 = env->CP0_EntryLo1;
+ RETURN();
+}
+
+void op_dmfc0_context (void)
+{
+ T0 = env->CP0_Context;
+ RETURN();
+}
+
+void op_dmfc0_badvaddr (void)
+{
+ T0 = env->CP0_BadVAddr;
+ RETURN();
+}
+
+void op_dmfc0_entryhi (void)
+{
+ T0 = env->CP0_EntryHi;
+ RETURN();
+}
+
+void op_dmfc0_epc (void)
+{
+ T0 = env->CP0_EPC;
+ RETURN();
+}
+
+void op_dmfc0_ebase (void)
+{
+ T0 = env->CP0_EBase;
+ RETURN();
+}
+
+void op_dmfc0_lladdr (void)
+{
+ T0 = env->CP0_LLAddr >> 4;
+ RETURN();
+}
+
+void op_dmfc0_watchlo0 (void)
+{
+ T0 = env->CP0_WatchLo;
+ RETURN();
+}
+
+void op_dmfc0_xcontext (void)
+{
+ T0 = env->CP0_XContext;
+ RETURN();
+}
+
+void op_dmfc0_depc (void)
+{
+ T0 = env->CP0_DEPC;
+ RETURN();
+}
+
+void op_dmfc0_errorepc (void)
+{
+ T0 = env->CP0_ErrorEPC;
+ RETURN();
+}
+
+void op_dmtc0_entrylo0 (void)
+{
+ /* Large physaddr not implemented */
+ /* 1k pages not implemented */
+ env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
+ RETURN();
+}
+
+void op_dmtc0_entrylo1 (void)
+{
+ /* Large physaddr not implemented */
+ /* 1k pages not implemented */
+ env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
+ RETURN();
+}
+
+void op_dmtc0_context (void)
+{
+ env->CP0_Context = (env->CP0_Context & ~0x007FFFFF) | (T0 & 0x007FFFF0);
+ RETURN();
+}
+
+void op_dmtc0_epc (void)
+{
+ env->CP0_EPC = T0;
+ RETURN();
+}
+
+void op_dmtc0_ebase (void)
+{
+ /* vectored interrupts not implemented */
+ /* Multi-CPU not implemented */
+ /* XXX: 64bit addressing broken */
+ env->CP0_EBase = (int32_t)0x80000000 | (T0 & 0x3FFFF000);
+ RETURN();
+}
+
+void op_dmtc0_watchlo0 (void)
+{
+ env->CP0_WatchLo = T0;
+ RETURN();
+}
+
+void op_dmtc0_xcontext (void)
+{
+ env->CP0_XContext = T0; /* XXX */
+ RETURN();
+}
+
+void op_dmtc0_depc (void)
+{
+ env->CP0_DEPC = T0;
+ RETURN();
+}
+
+void op_dmtc0_errorepc (void)
+{
+ env->CP0_ErrorEPC = T0;
+ RETURN();
+}
+
#ifdef MIPS_USES_FPU
#if 0
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 4326b6621d..bea5a905e1 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -411,10 +411,10 @@ void do_tlbwi (void)
that might be a further win. */
mips_tlb_flush_extra (env, MIPS_TLB_NB);
- /* Wildly undefined effects for CP0_index containing a too high value and
+ /* Wildly undefined effects for CP0_Index containing a too high value and
MIPS_TLB_NB not being a power of two. But so does real silicon. */
- invalidate_tlb(env, env->CP0_index & (MIPS_TLB_NB - 1), 0);
- fill_tlb(env->CP0_index & (MIPS_TLB_NB - 1));
+ invalidate_tlb(env, env->CP0_Index & (MIPS_TLB_NB - 1), 0);
+ fill_tlb(env->CP0_Index & (MIPS_TLB_NB - 1));
}
void do_tlbwr (void)
@@ -439,7 +439,7 @@ void do_tlbp (void)
/* Check ASID, virtual page number & size */
if ((tlb->G == 1 || tlb->ASID == ASID) && tlb->VPN == tag) {
/* TLB match */
- env->CP0_index = i;
+ env->CP0_Index = i;
break;
}
}
@@ -455,7 +455,7 @@ void do_tlbp (void)
}
}
- env->CP0_index |= 0x80000000;
+ env->CP0_Index |= 0x80000000;
}
}
@@ -465,7 +465,7 @@ void do_tlbr (void)
uint8_t ASID;
ASID = env->CP0_EntryHi & 0xFF;
- tlb = &env->tlb[env->CP0_index & (MIPS_TLB_NB - 1)];
+ tlb = &env->tlb[env->CP0_Index & (MIPS_TLB_NB - 1)];
/* If this will change the current ASID, flush qemu's TLB. */
if (ASID != tlb->ASID)
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;