Commit 8c0fdd856c63eb11ec5ef955731b1b0cda51f967

Authored by ths
1 parent 873eb012

Dynamically translate MIPS mtc0 instructions.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2223 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/exec.h
@@ -68,7 +68,8 @@ void do_msubu (void); @@ -68,7 +68,8 @@ void do_msubu (void);
68 #endif 68 #endif
69 void do_mfc0_random(void); 69 void do_mfc0_random(void);
70 void do_mfc0_count(void); 70 void do_mfc0_count(void);
71 -void do_mtc0(int reg, int sel); 71 +void do_mtc0_status_debug(uint32_t old, uint32_t val);
  72 +void do_mtc0_status_irqraise_debug(void);
72 void do_tlbwi (void); 73 void do_tlbwi (void);
73 void do_tlbwr (void); 74 void do_tlbwr (void);
74 void do_tlbp (void); 75 void do_tlbp (void);
target-mips/op.c
@@ -852,9 +852,185 @@ void op_mfc0_desave (void) @@ -852,9 +852,185 @@ void op_mfc0_desave (void)
852 RETURN(); 852 RETURN();
853 } 853 }
854 854
855 -void op_mtc0 (void) 855 +void op_mtc0_index (void)
856 { 856 {
857 - CALL_FROM_TB2(do_mtc0, PARAM1, PARAM2); 857 + env->CP0_index = (env->CP0_index & 0x80000000) | (T0 & 0x0000000F);
  858 + RETURN();
  859 +}
  860 +
  861 +void op_mtc0_entrylo0 (void)
  862 +{
  863 + env->CP0_EntryLo0 = T0 & 0x3FFFFFFF;
  864 + RETURN();
  865 +}
  866 +
  867 +void op_mtc0_entrylo1 (void)
  868 +{
  869 + env->CP0_EntryLo1 = T0 & 0x3FFFFFFF;
  870 + RETURN();
  871 +}
  872 +
  873 +void op_mtc0_context (void)
  874 +{
  875 + env->CP0_Context = (env->CP0_Context & 0xFF800000) | (T0 & 0x007FFFF0);
  876 + RETURN();
  877 +}
  878 +
  879 +void op_mtc0_pagemask (void)
  880 +{
  881 + env->CP0_PageMask = T0 & 0x01FFE000;
  882 + RETURN();
  883 +}
  884 +
  885 +void op_mtc0_wired (void)
  886 +{
  887 + env->CP0_Wired = T0 & 0x0000000F;
  888 + RETURN();
  889 +}
  890 +
  891 +void op_mtc0_count (void)
  892 +{
  893 + CALL_FROM_TB2(cpu_mips_store_count, env, T0);
  894 + RETURN();
  895 +}
  896 +
  897 +void op_mtc0_entryhi (void)
  898 +{
  899 + uint32_t old, val;
  900 +
  901 + val = T0 & 0xFFFFE0FF;
  902 + old = env->CP0_EntryHi;
  903 + env->CP0_EntryHi = val;
  904 + /* If the ASID changes, flush qemu's TLB. */
  905 + if ((old & 0xFF) != (val & 0xFF))
  906 + CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1);
  907 + RETURN();
  908 +}
  909 +
  910 +void op_mtc0_compare (void)
  911 +{
  912 + CALL_FROM_TB2(cpu_mips_store_compare, env, T0);
  913 + RETURN();
  914 +}
  915 +
  916 +void op_mtc0_status (void)
  917 +{
  918 + uint32_t val, old, mask;
  919 +
  920 + val = T0 & 0xFA78FF01;
  921 + old = env->CP0_Status;
  922 + if (T0 & (1 << CP0St_UM))
  923 + env->hflags |= MIPS_HFLAG_UM;
  924 + else
  925 + env->hflags &= ~MIPS_HFLAG_UM;
  926 + if (T0 & (1 << CP0St_ERL))
  927 + env->hflags |= MIPS_HFLAG_ERL;
  928 + else
  929 + env->hflags &= ~MIPS_HFLAG_ERL;
  930 + if (T0 & (1 << CP0St_EXL))
  931 + env->hflags |= MIPS_HFLAG_EXL;
  932 + else
  933 + env->hflags &= ~MIPS_HFLAG_EXL;
  934 + env->CP0_Status = val;
  935 + /* If we unmasked an asserted IRQ, raise it */
  936 + mask = 0x0000FF00;
  937 + if (loglevel & CPU_LOG_TB_IN_ASM)
  938 + CALL_FROM_TB2(do_mtc0_status_debug, old, val);
  939 + if ((val & (1 << CP0St_IE)) && !(old & (1 << CP0St_IE)) &&
  940 + !(env->hflags & MIPS_HFLAG_EXL) &&
  941 + !(env->hflags & MIPS_HFLAG_ERL) &&
  942 + !(env->hflags & MIPS_HFLAG_DM) &&
  943 + (env->CP0_Status & env->CP0_Cause & mask)) {
  944 + env->interrupt_request |= CPU_INTERRUPT_HARD;
  945 + if (logfile)
  946 + CALL_FROM_TB0(do_mtc0_status_irqraise_debug);
  947 + } else if (!(val & (1 << CP0St_IE)) && (old & (1 << CP0St_IE))) {
  948 + env->interrupt_request &= ~CPU_INTERRUPT_HARD;
  949 + }
  950 + RETURN();
  951 +}
  952 +
  953 +void op_mtc0_cause (void)
  954 +{
  955 + uint32_t val, old;
  956 +
  957 + val = (env->CP0_Cause & 0xB000F87C) | (T0 & 0x000C00300);
  958 + old = env->CP0_Cause;
  959 + env->CP0_Cause = val;
  960 +#if 0
  961 + {
  962 + int i, mask;
  963 +
  964 + /* Check if we ever asserted a software IRQ */
  965 + for (i = 0; i < 2; i++) {
  966 + mask = 0x100 << i;
  967 + if ((val & mask) & !(old & mask))
  968 + CALL_FROM_TB1(mips_set_irq, i);
  969 + }
  970 + }
  971 +#endif
  972 + RETURN();
  973 +}
  974 +
  975 +void op_mtc0_epc (void)
  976 +{
  977 + env->CP0_EPC = T0;
  978 + RETURN();
  979 +}
  980 +
  981 +void op_mtc0_config0 (void)
  982 +{
  983 +#if defined(MIPS_USES_R4K_TLB)
  984 + env->CP0_Config0 = (env->CP0_Config0 & 0x8017FF80) | (T0 & 0x7E000001);
  985 +#else
  986 + env->CP0_Config0 = (env->CP0_Config0 & 0xFE17FF80) | (T0 & 0x00000001);
  987 +#endif
  988 + RETURN();
  989 +}
  990 +
  991 +void op_mtc0_watchlo (void)
  992 +{
  993 + env->CP0_WatchLo = T0;
  994 + RETURN();
  995 +}
  996 +
  997 +void op_mtc0_watchhi (void)
  998 +{
  999 + env->CP0_WatchHi = T0 & 0x40FF0FF8;
  1000 + RETURN();
  1001 +}
  1002 +
  1003 +void op_mtc0_debug (void)
  1004 +{
  1005 + env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
  1006 + if (T0 & (1 << CP0DB_DM))
  1007 + env->hflags |= MIPS_HFLAG_DM;
  1008 + else
  1009 + env->hflags &= ~MIPS_HFLAG_DM;
  1010 + RETURN();
  1011 +}
  1012 +
  1013 +void op_mtc0_depc (void)
  1014 +{
  1015 + env->CP0_DEPC = T0;
  1016 + RETURN();
  1017 +}
  1018 +
  1019 +void op_mtc0_taglo (void)
  1020 +{
  1021 + env->CP0_TagLo = T0 & 0xFFFFFCF6;
  1022 + RETURN();
  1023 +}
  1024 +
  1025 +void op_mtc0_errorepc (void)
  1026 +{
  1027 + env->CP0_ErrorEPC = T0;
  1028 + RETURN();
  1029 +}
  1030 +
  1031 +void op_mtc0_desave (void)
  1032 +{
  1033 + env->CP0_DESAVE = T0;
858 RETURN(); 1034 RETURN();
859 } 1035 }
860 1036
target-mips/op_helper.c
@@ -141,9 +141,24 @@ void do_mfc0_count (void) @@ -141,9 +141,24 @@ void do_mfc0_count (void)
141 cpu_abort(env, "mfc0 count\n"); 141 cpu_abort(env, "mfc0 count\n");
142 } 142 }
143 143
144 -void do_mtc0 (int reg, int sel) 144 +void cpu_mips_store_count(CPUState *env, uint32_t value)
145 { 145 {
146 - cpu_abort(env, "mtc0 reg=%d sel=%d\n", reg, sel); 146 + cpu_abort(env, "mtc0 count\n");
  147 +}
  148 +
  149 +void cpu_mips_store_compare(CPUState *env, uint32_t value)
  150 +{
  151 + cpu_abort(env, "mtc0 compare\n");
  152 +}
  153 +
  154 +void do_mtc0_status_debug(uint32_t old, uint32_t val)
  155 +{
  156 + cpu_abort(env, "mtc0 status\n");
  157 +}
  158 +
  159 +void do_mtc0_status_irqraise_debug(void)
  160 +{
  161 + cpu_abort(env, "mtc0 status\n");
147 } 162 }
148 163
149 void do_tlbwi (void) 164 void do_tlbwi (void)
@@ -166,6 +181,11 @@ void do_tlbr (void) @@ -166,6 +181,11 @@ void do_tlbr (void)
166 cpu_abort(env, "tlbr\n"); 181 cpu_abort(env, "tlbr\n");
167 } 182 }
168 183
  184 +void cpu_mips_tlb_flush (CPUState *env, int flush_global)
  185 +{
  186 + cpu_abort(env, "mips_tlb_flush\n");
  187 +}
  188 +
169 #else 189 #else
170 190
171 /* CP0 helpers */ 191 /* CP0 helpers */
@@ -179,222 +199,17 @@ void do_mfc0_count (void) @@ -179,222 +199,17 @@ void do_mfc0_count (void)
179 T0 = cpu_mips_get_count(env); 199 T0 = cpu_mips_get_count(env);
180 } 200 }
181 201
182 -void do_mtc0 (int reg, int sel) 202 +void do_mtc0_status_debug(uint32_t old, uint32_t val)
183 { 203 {
184 - const unsigned char *rn;  
185 - uint32_t val, old, mask; 204 + const uint32_t mask = 0x0000FF00;
  205 + fprintf(logfile, "Status %08x => %08x Cause %08x (%08x %08x %08x)\n",
  206 + old, val, env->CP0_Cause, old & mask, val & mask,
  207 + env->CP0_Cause & mask);
  208 +}
186 209
187 - if (sel != 0 && reg != 16 && reg != 28) {  
188 - val = -1;  
189 - old = -1;  
190 - rn = "invalid";  
191 - goto print;  
192 - }  
193 - switch (reg) {  
194 - case 0:  
195 - val = (env->CP0_index & 0x80000000) | (T0 & 0x0000000F);  
196 - old = env->CP0_index;  
197 - env->CP0_index = val;  
198 - rn = "Index";  
199 - break;  
200 - case 2:  
201 - val = T0 & 0x3FFFFFFF;  
202 - old = env->CP0_EntryLo0;  
203 - env->CP0_EntryLo0 = val;  
204 - rn = "EntryLo0";  
205 - break;  
206 - case 3:  
207 - val = T0 & 0x3FFFFFFF;  
208 - old = env->CP0_EntryLo1;  
209 - env->CP0_EntryLo1 = val;  
210 - rn = "EntryLo1";  
211 - break;  
212 - case 4:  
213 - val = (env->CP0_Context & 0xFF800000) | (T0 & 0x007FFFF0);  
214 - old = env->CP0_Context;  
215 - env->CP0_Context = val;  
216 - rn = "Context";  
217 - break;  
218 - case 5:  
219 - val = T0 & 0x01FFE000;  
220 - old = env->CP0_PageMask;  
221 - env->CP0_PageMask = val;  
222 - rn = "PageMask";  
223 - break;  
224 - case 6:  
225 - val = T0 & 0x0000000F;  
226 - old = env->CP0_Wired;  
227 - env->CP0_Wired = val;  
228 - rn = "Wired";  
229 - break;  
230 - case 9:  
231 - val = T0;  
232 - old = cpu_mips_get_count(env);  
233 - cpu_mips_store_count(env, val);  
234 - rn = "Count";  
235 - break;  
236 - case 10:  
237 - val = T0 & 0xFFFFE0FF;  
238 - old = env->CP0_EntryHi;  
239 - env->CP0_EntryHi = val;  
240 - /* If the ASID changes, flush qemu's TLB. */  
241 - if ((old & 0xFF) != (val & 0xFF))  
242 - cpu_mips_tlb_flush (env, 1);  
243 - rn = "EntryHi";  
244 - break;  
245 - case 11:  
246 - val = T0;  
247 - old = env->CP0_Compare;  
248 - cpu_mips_store_compare(env, val);  
249 - rn = "Compare";  
250 - break;  
251 - case 12:  
252 - val = T0 & 0xFA78FF01;  
253 - if (T0 & (1 << CP0St_UM))  
254 - env->hflags |= MIPS_HFLAG_UM;  
255 - else  
256 - env->hflags &= ~MIPS_HFLAG_UM;  
257 - if (T0 & (1 << CP0St_ERL))  
258 - env->hflags |= MIPS_HFLAG_ERL;  
259 - else  
260 - env->hflags &= ~MIPS_HFLAG_ERL;  
261 - if (T0 & (1 << CP0St_EXL))  
262 - env->hflags |= MIPS_HFLAG_EXL;  
263 - else  
264 - env->hflags &= ~MIPS_HFLAG_EXL;  
265 - old = env->CP0_Status;  
266 - env->CP0_Status = val;  
267 - /* If we unmasked an asserted IRQ, raise it */  
268 - mask = 0x0000FF00;  
269 - if (loglevel & CPU_LOG_TB_IN_ASM) {  
270 - fprintf(logfile, "Status %08x => %08x Cause %08x (%08x %08x %08x)\n",  
271 - old, val, env->CP0_Cause, old & mask, val & mask,  
272 - env->CP0_Cause & mask);  
273 - }  
274 - if ((val & (1 << CP0St_IE)) && !(old & (1 << CP0St_IE)) &&  
275 - !(env->hflags & MIPS_HFLAG_EXL) &&  
276 - !(env->hflags & MIPS_HFLAG_ERL) &&  
277 - !(env->hflags & MIPS_HFLAG_DM) &&  
278 - (env->CP0_Status & env->CP0_Cause & mask)) {  
279 - if (logfile)  
280 - fprintf(logfile, "Raise pending IRQs\n");  
281 - env->interrupt_request |= CPU_INTERRUPT_HARD;  
282 - } else if (!(val & (1 << CP0St_IE)) && (old & (1 << CP0St_IE))) {  
283 - env->interrupt_request &= ~CPU_INTERRUPT_HARD;  
284 - }  
285 - rn = "Status";  
286 - break;  
287 - case 13:  
288 - val = (env->CP0_Cause & 0xB000F87C) | (T0 & 0x000C00300);  
289 - old = env->CP0_Cause;  
290 - env->CP0_Cause = val;  
291 -#if 0  
292 - {  
293 - int i;  
294 - /* Check if we ever asserted a software IRQ */  
295 - for (i = 0; i < 2; i++) {  
296 - mask = 0x100 << i;  
297 - if ((val & mask) & !(old & mask))  
298 - mips_set_irq(i);  
299 - }  
300 - }  
301 -#endif  
302 - rn = "Cause";  
303 - break;  
304 - case 14:  
305 - val = T0;  
306 - old = env->CP0_EPC;  
307 - env->CP0_EPC = val;  
308 - rn = "EPC";  
309 - break;  
310 - case 16:  
311 - switch (sel) {  
312 - case 0:  
313 -#if defined(MIPS_USES_R4K_TLB)  
314 - val = (env->CP0_Config0 & 0x8017FF80) | (T0 & 0x7E000001);  
315 -#else  
316 - val = (env->CP0_Config0 & 0xFE17FF80) | (T0 & 0x00000001);  
317 -#endif  
318 - old = env->CP0_Config0;  
319 - env->CP0_Config0 = val;  
320 - rn = "Config0";  
321 - break;  
322 - default:  
323 - val = -1;  
324 - old = -1;  
325 - rn = "bad config selector";  
326 - break;  
327 - }  
328 - break;  
329 - case 18:  
330 - val = T0;  
331 - old = env->CP0_WatchLo;  
332 - env->CP0_WatchLo = val;  
333 - rn = "WatchLo";  
334 - break;  
335 - case 19:  
336 - val = T0 & 0x40FF0FF8;  
337 - old = env->CP0_WatchHi;  
338 - env->CP0_WatchHi = val;  
339 - rn = "WatchHi";  
340 - break;  
341 - case 23:  
342 - val = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);  
343 - if (T0 & (1 << CP0DB_DM))  
344 - env->hflags |= MIPS_HFLAG_DM;  
345 - else  
346 - env->hflags &= ~MIPS_HFLAG_DM;  
347 - old = env->CP0_Debug;  
348 - env->CP0_Debug = val;  
349 - rn = "Debug";  
350 - break;  
351 - case 24:  
352 - val = T0;  
353 - old = env->CP0_DEPC;  
354 - env->CP0_DEPC = val;  
355 - rn = "DEPC";  
356 - break;  
357 - case 28:  
358 - switch (sel) {  
359 - case 0:  
360 - val = T0 & 0xFFFFFCF6;  
361 - old = env->CP0_TagLo;  
362 - env->CP0_TagLo = val;  
363 - rn = "TagLo";  
364 - break;  
365 - default:  
366 - val = -1;  
367 - old = -1;  
368 - rn = "invalid sel";  
369 - break;  
370 - }  
371 - break;  
372 - case 30:  
373 - val = T0;  
374 - old = env->CP0_ErrorEPC;  
375 - env->CP0_ErrorEPC = val;  
376 - rn = "EPC";  
377 - break;  
378 - case 31:  
379 - val = T0;  
380 - old = env->CP0_DESAVE;  
381 - env->CP0_DESAVE = val;  
382 - rn = "DESAVE";  
383 - break;  
384 - default:  
385 - val = -1;  
386 - old = -1;  
387 - rn = "unknown";  
388 - break;  
389 - }  
390 - print:  
391 -#if defined MIPS_DEBUG_DISAS  
392 - if (loglevel & CPU_LOG_TB_IN_ASM) {  
393 - fprintf(logfile, "%08x mtc0 %s %08x => %08x (%d %d %08x)\n",  
394 - env->PC, rn, T0, val, reg, sel, old);  
395 - }  
396 -#endif  
397 - return; 210 +void do_mtc0_status_irqraise_debug(void)
  211 +{
  212 + fprintf(logfile, "Raise pending IRQs\n");
398 } 213 }
399 214
400 #ifdef MIPS_USES_FPU 215 #ifdef MIPS_USES_FPU
target-mips/translate.c
@@ -1371,6 +1371,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) @@ -1371,6 +1371,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1371 rn = "EntryLo0"; 1371 rn = "EntryLo0";
1372 break; 1372 break;
1373 case 3: 1373 case 3:
  1374 + /* also CONF */
1374 gen_op_mfc0_entrylo1(); 1375 gen_op_mfc0_entrylo1();
1375 rn = "EntryLo1"; 1376 rn = "EntryLo1";
1376 break; 1377 break;
@@ -1386,6 +1387,10 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) @@ -1386,6 +1387,10 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1386 gen_op_mfc0_wired(); 1387 gen_op_mfc0_wired();
1387 rn = "Wired"; 1388 rn = "Wired";
1388 break; 1389 break;
  1390 + case 7:
  1391 +// gen_op_mfc0_info();
  1392 + rn = "Info";
  1393 + break;
1389 case 8: 1394 case 8:
1390 gen_op_mfc0_badvaddr(); 1395 gen_op_mfc0_badvaddr();
1391 rn = "BadVaddr"; 1396 rn = "BadVaddr";
@@ -1445,6 +1450,19 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) @@ -1445,6 +1450,19 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1445 gen_op_mfc0_watchhi(); 1450 gen_op_mfc0_watchhi();
1446 rn = "WatchHi"; 1451 rn = "WatchHi";
1447 break; 1452 break;
  1453 + case 20:
  1454 + /* 64 bit only */
  1455 +// gen_op_mfc0_xcontext();
  1456 + rn = "XContext";
  1457 + break;
  1458 + case 21:
  1459 +// gen_op_mfc0_framemask();
  1460 + rn = "Framemask";
  1461 + break;
  1462 + case 22:
  1463 +// gen_op_mfc0_diagnostic();
  1464 + rn = "'Diagnostic";
  1465 + break;
1448 case 23: 1466 case 23:
1449 gen_op_mfc0_debug(); 1467 gen_op_mfc0_debug();
1450 rn = "Debug"; 1468 rn = "Debug";
@@ -1453,6 +1471,18 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) @@ -1453,6 +1471,18 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1453 gen_op_mfc0_depc(); 1471 gen_op_mfc0_depc();
1454 rn = "DEPC"; 1472 rn = "DEPC";
1455 break; 1473 break;
  1474 + case 25:
  1475 +// gen_op_mfc0_performance();
  1476 + rn = "Performance";
  1477 + break;
  1478 + case 26:
  1479 +// gen_op_mfc0_ecc();
  1480 + rn = "ECC";
  1481 + break;
  1482 + case 27:
  1483 +// gen_op_mfc0_cacheerr();
  1484 + rn = "CacheErr";
  1485 + break;
1456 case 28: 1486 case 28:
1457 switch (sel) { 1487 switch (sel) {
1458 case 0: 1488 case 0:
@@ -1468,6 +1498,10 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) @@ -1468,6 +1498,10 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1468 goto die; 1498 goto die;
1469 } 1499 }
1470 break; 1500 break;
  1501 + case 29:
  1502 +// gen_op_mfc0_taghi();
  1503 + rn = "TagHi";
  1504 + break;
1471 case 30: 1505 case 30:
1472 gen_op_mfc0_errorepc(); 1506 gen_op_mfc0_errorepc();
1473 rn = "ErrorEPC"; 1507 rn = "ErrorEPC";
@@ -1498,6 +1532,183 @@ die: @@ -1498,6 +1532,183 @@ die:
1498 generate_exception(ctx, EXCP_RI); 1532 generate_exception(ctx, EXCP_RI);
1499 } 1533 }
1500 1534
  1535 +static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
  1536 +{
  1537 + const unsigned char *rn;
  1538 + uint32_t val, old;
  1539 +
  1540 + if (sel != 0 && reg != 16 && reg != 28) {
  1541 + val = -1;
  1542 + old = -1;
  1543 + rn = "invalid";
  1544 + goto die;
  1545 + }
  1546 + switch (reg) {
  1547 + case 0:
  1548 + gen_op_mtc0_index();
  1549 + rn = "Index";
  1550 + break;
  1551 + case 1:
  1552 +// ignore or except?
  1553 + rn = "Random";
  1554 + break;
  1555 + case 2:
  1556 + gen_op_mtc0_entrylo0();
  1557 + rn = "EntryLo0";
  1558 + break;
  1559 + case 3:
  1560 + gen_op_mtc0_entrylo1();
  1561 + rn = "EntryLo1";
  1562 + break;
  1563 + case 4:
  1564 + gen_op_mtc0_context();
  1565 + rn = "Context";
  1566 + break;
  1567 + case 5:
  1568 + gen_op_mtc0_pagemask();
  1569 + rn = "PageMask";
  1570 + break;
  1571 + case 6:
  1572 + gen_op_mtc0_wired();
  1573 + rn = "Wired";
  1574 + break;
  1575 + case 7:
  1576 +// ignore or except?
  1577 + rn = "Info";
  1578 + break;
  1579 + case 8:
  1580 +// ignore or except?
  1581 + rn = "BadVaddr";
  1582 + break;
  1583 + case 9:
  1584 + gen_op_mtc0_count();
  1585 + rn = "Count";
  1586 + break;
  1587 + case 10:
  1588 + gen_op_mtc0_entryhi();
  1589 + rn = "EntryHi";
  1590 + break;
  1591 + case 11:
  1592 + gen_op_mtc0_compare();
  1593 + rn = "Compare";
  1594 + break;
  1595 + case 12:
  1596 + gen_op_mtc0_status();
  1597 + rn = "Status";
  1598 + break;
  1599 + case 13:
  1600 + gen_op_mtc0_cause();
  1601 + rn = "Cause";
  1602 + break;
  1603 + case 14:
  1604 + gen_op_mtc0_epc();
  1605 + rn = "EPC";
  1606 + break;
  1607 + case 15:
  1608 +// ignore or except?
  1609 + rn = "PRid";
  1610 + break;
  1611 + case 16:
  1612 + switch (sel) {
  1613 + case 0:
  1614 + gen_op_mtc0_config0();
  1615 + rn = "Config0";
  1616 + break;
  1617 + default:
  1618 + rn = "Invalid config selector";
  1619 + goto die;
  1620 + }
  1621 + break;
  1622 + case 17:
  1623 +// ignore or except?
  1624 + rn = "LLaddr";
  1625 + break;
  1626 + case 18:
  1627 + gen_op_mtc0_watchlo();
  1628 + rn = "WatchLo";
  1629 + break;
  1630 + case 19:
  1631 + gen_op_mtc0_watchhi();
  1632 + rn = "WatchHi";
  1633 + break;
  1634 + case 20:
  1635 + /* 64 bit only */
  1636 +// gen_op_mtc0_xcontext();
  1637 + rn = "XContext";
  1638 + break;
  1639 + case 21:
  1640 +// gen_op_mtc0_framemask();
  1641 + rn = "Framemask";
  1642 + break;
  1643 + case 22:
  1644 +// ignore or except?
  1645 + rn = "Diagnostic";
  1646 + break;
  1647 + case 23:
  1648 + gen_op_mtc0_debug();
  1649 + rn = "Debug";
  1650 + break;
  1651 + case 24:
  1652 + gen_op_mtc0_depc();
  1653 + rn = "DEPC";
  1654 + break;
  1655 + case 25:
  1656 +// ignore or except?
  1657 + rn = "Performance";
  1658 + break;
  1659 + case 26:
  1660 +// ignore or except?
  1661 + rn = "ECC";
  1662 + break;
  1663 + case 27:
  1664 +// ignore or except?
  1665 + rn = "CacheErr";
  1666 + break;
  1667 + case 28:
  1668 + switch (sel) {
  1669 + case 0:
  1670 + gen_op_mtc0_taglo();
  1671 + rn = "TagLo";
  1672 + break;
  1673 + default:
  1674 + rn = "invalid sel";
  1675 + goto die;
  1676 + }
  1677 + break;
  1678 + case 29:
  1679 +// gen_op_mtc0_taghi();
  1680 + rn = "TagHi";
  1681 + break;
  1682 + case 30:
  1683 + gen_op_mtc0_errorepc();
  1684 + rn = "ErrorEPC";
  1685 + break;
  1686 + case 31:
  1687 + gen_op_mtc0_desave();
  1688 + rn = "DESAVE";
  1689 + break;
  1690 + default:
  1691 + rn = "unknown";
  1692 + goto die;
  1693 + }
  1694 +#if defined MIPS_DEBUG_DISAS
  1695 + if (loglevel & CPU_LOG_TB_IN_ASM) {
  1696 + fprintf(logfile, "%08x mtc0 %s => %08x (%d %d)\n",
  1697 + env->PC, rn, T0, reg, sel);
  1698 + }
  1699 +#endif
  1700 + return;
  1701 +
  1702 +die:
  1703 +#if defined MIPS_DEBUG_DISAS
  1704 + if (loglevel & CPU_LOG_TB_IN_ASM) {
  1705 + fprintf(logfile, "%08x mtc0 %s => %08x (%d %d)\n",
  1706 + env->PC, rn, T0, reg, sel);
  1707 + }
  1708 +#endif
  1709 + generate_exception(ctx, EXCP_RI);
  1710 +}
  1711 +
1501 static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd) 1712 static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd)
1502 { 1713 {
1503 const unsigned char *opn = "unk"; 1714 const unsigned char *opn = "unk";
@@ -1529,7 +1740,7 @@ static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd) @@ -1529,7 +1740,7 @@ static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd)
1529 save_cpu_state(ctx, 1); 1740 save_cpu_state(ctx, 1);
1530 ctx->pc -= 4; 1741 ctx->pc -= 4;
1531 GEN_LOAD_REG_TN(T0, rt); 1742 GEN_LOAD_REG_TN(T0, rt);
1532 - gen_op_mtc0(rd, ctx->opcode & 0x7); 1743 + gen_mtc0(ctx, rd, ctx->opcode & 0x7);
1533 /* Stop translation as we may have switched the execution mode */ 1744 /* Stop translation as we may have switched the execution mode */
1534 ctx->bstate = BS_STOP; 1745 ctx->bstate = BS_STOP;
1535 opn = "mtc0"; 1746 opn = "mtc0";