Commit 7a387fffce508fedae82e3e81b90d1f20c02c783

Authored by ths
1 parent 8c0fdd85

Add MIPS32R2 instructions, and generally straighten out the instruction

decoding. This is also the first percent towards MIPS64 support.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2224 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/cpu.h
@@ -99,14 +99,16 @@ struct CPUMIPSState { @@ -99,14 +99,16 @@ struct CPUMIPSState {
99 #endif 99 #endif
100 uint32_t CP0_index; 100 uint32_t CP0_index;
101 uint32_t CP0_random; 101 uint32_t CP0_random;
102 - uint32_t CP0_EntryLo0;  
103 - uint32_t CP0_EntryLo1;  
104 - uint32_t CP0_Context; 102 + uint64_t CP0_EntryLo0;
  103 + uint64_t CP0_EntryLo1;
  104 + uint64_t CP0_Context;
105 uint32_t CP0_PageMask; 105 uint32_t CP0_PageMask;
  106 + uint32_t CP0_PageGrain;
106 uint32_t CP0_Wired; 107 uint32_t CP0_Wired;
  108 + uint32_t CP0_HWREna;
107 uint32_t CP0_BadVAddr; 109 uint32_t CP0_BadVAddr;
108 uint32_t CP0_Count; 110 uint32_t CP0_Count;
109 - uint32_t CP0_EntryHi; 111 + uint64_t CP0_EntryHi;
110 uint32_t CP0_Compare; 112 uint32_t CP0_Compare;
111 uint32_t CP0_Status; 113 uint32_t CP0_Status;
112 #define CP0St_CU3 31 114 #define CP0St_CU3 31
@@ -116,19 +118,36 @@ struct CPUMIPSState { @@ -116,19 +118,36 @@ struct CPUMIPSState {
116 #define CP0St_RP 27 118 #define CP0St_RP 27
117 #define CP0St_FR 26 119 #define CP0St_FR 26
118 #define CP0St_RE 25 120 #define CP0St_RE 25
  121 +#define CP0St_MX 24
  122 +#define CP0St_PX 23
119 #define CP0St_BEV 22 123 #define CP0St_BEV 22
120 #define CP0St_TS 21 124 #define CP0St_TS 21
121 #define CP0St_SR 20 125 #define CP0St_SR 20
122 #define CP0St_NMI 19 126 #define CP0St_NMI 19
123 #define CP0St_IM 8 127 #define CP0St_IM 8
  128 +#define CP0St_KX 7
  129 +#define CP0St_SX 6
  130 +#define CP0St_UX 5
124 #define CP0St_UM 4 131 #define CP0St_UM 4
  132 +#define CP0St_R0 3
125 #define CP0St_ERL 2 133 #define CP0St_ERL 2
126 #define CP0St_EXL 1 134 #define CP0St_EXL 1
127 #define CP0St_IE 0 135 #define CP0St_IE 0
  136 + uint32_t CP0_IntCtl;
  137 + uint32_t CP0_SRSCtl;
128 uint32_t CP0_Cause; 138 uint32_t CP0_Cause;
  139 +#define CP0Ca_BD 31
  140 +#define CP0Ca_TI 30
  141 +#define CP0Ca_CE 28
  142 +#define CP0Ca_DC 27
  143 +#define CP0Ca_PCI 26
129 #define CP0Ca_IV 23 144 #define CP0Ca_IV 23
  145 +#define CP0Ca_WP 22
  146 +#define CP0Ca_IP 8
  147 +#define CP0Ca_EC 2
130 uint32_t CP0_EPC; 148 uint32_t CP0_EPC;
131 uint32_t CP0_PRid; 149 uint32_t CP0_PRid;
  150 + uint32_t CP0_EBase;
132 uint32_t CP0_Config0; 151 uint32_t CP0_Config0;
133 #define CP0C0_M 31 152 #define CP0C0_M 31
134 #define CP0C0_K23 28 153 #define CP0C0_K23 28
@@ -140,8 +159,10 @@ struct CPUMIPSState { @@ -140,8 +159,10 @@ struct CPUMIPSState {
140 #define CP0C0_AT 13 159 #define CP0C0_AT 13
141 #define CP0C0_AR 10 160 #define CP0C0_AR 10
142 #define CP0C0_MT 7 161 #define CP0C0_MT 7
  162 +#define CP0C0_VI 3
143 #define CP0C0_K0 0 163 #define CP0C0_K0 0
144 uint32_t CP0_Config1; 164 uint32_t CP0_Config1;
  165 +#define CP0C1_M 31
145 #define CP0C1_MMU 25 166 #define CP0C1_MMU 25
146 #define CP0C1_IS 22 167 #define CP0C1_IS 22
147 #define CP0C1_IL 19 168 #define CP0C1_IL 19
@@ -149,14 +170,38 @@ struct CPUMIPSState { @@ -149,14 +170,38 @@ struct CPUMIPSState {
149 #define CP0C1_DS 13 170 #define CP0C1_DS 13
150 #define CP0C1_DL 10 171 #define CP0C1_DL 10
151 #define CP0C1_DA 7 172 #define CP0C1_DA 7
  173 +#define CP0C1_C2 6
  174 +#define CP0C1_MD 5
152 #define CP0C1_PC 4 175 #define CP0C1_PC 4
153 #define CP0C1_WR 3 176 #define CP0C1_WR 3
154 #define CP0C1_CA 2 177 #define CP0C1_CA 2
155 #define CP0C1_EP 1 178 #define CP0C1_EP 1
156 #define CP0C1_FP 0 179 #define CP0C1_FP 0
  180 + uint32_t CP0_Config2;
  181 +#define CP0C2_M 31
  182 +#define CP0C2_TU 28
  183 +#define CP0C2_TS 24
  184 +#define CP0C2_TL 20
  185 +#define CP0C2_TA 16
  186 +#define CP0C2_SU 12
  187 +#define CP0C2_SS 8
  188 +#define CP0C2_SL 4
  189 +#define CP0C2_SA 0
  190 + uint32_t CP0_Config3;
  191 +#define CP0C3_M 31
  192 +#define CP0C3_DSPP 10
  193 +#define CP0C3_LPA 7
  194 +#define CP0C3_VEIC 6
  195 +#define CP0C3_VInt 5
  196 +#define CP0C3_SP 4
  197 +#define CP0C3_MT 2
  198 +#define CP0C3_SM 1
  199 +#define CP0C3_TL 0
157 uint32_t CP0_LLAddr; 200 uint32_t CP0_LLAddr;
158 uint32_t CP0_WatchLo; 201 uint32_t CP0_WatchLo;
159 uint32_t CP0_WatchHi; 202 uint32_t CP0_WatchHi;
  203 + uint32_t CP0_XContext;
  204 + uint32_t CP0_Framemask;
160 uint32_t CP0_Debug; 205 uint32_t CP0_Debug;
161 #define CPDB_DBD 31 206 #define CPDB_DBD 31
162 #define CP0DB_DM 30 207 #define CP0DB_DM 30
@@ -177,8 +222,11 @@ struct CPUMIPSState { @@ -177,8 +222,11 @@ struct CPUMIPSState {
177 #define CP0DB_DBp 1 222 #define CP0DB_DBp 1
178 #define CP0DB_DSS 0 223 #define CP0DB_DSS 0
179 uint32_t CP0_DEPC; 224 uint32_t CP0_DEPC;
  225 + uint32_t CP0_Performance0;
180 uint32_t CP0_TagLo; 226 uint32_t CP0_TagLo;
181 uint32_t CP0_DataLo; 227 uint32_t CP0_DataLo;
  228 + uint32_t CP0_TagHi;
  229 + uint32_t CP0_DataHi;
182 uint32_t CP0_ErrorEPC; 230 uint32_t CP0_ErrorEPC;
183 uint32_t CP0_DESAVE; 231 uint32_t CP0_DESAVE;
184 /* Qemu */ 232 /* Qemu */
@@ -211,6 +259,9 @@ struct CPUMIPSState { @@ -211,6 +259,9 @@ struct CPUMIPSState {
211 259
212 int halted; /* TRUE if the CPU is in suspend state */ 260 int halted; /* TRUE if the CPU is in suspend state */
213 261
  262 + int SYNCI_Step; /* Address step size for SYNCI */
  263 + int CCRes; /* Cycle count resolution/divisor */
  264 +
214 CPU_COMMON 265 CPU_COMMON
215 266
216 int ram_size; 267 int ram_size;
target-mips/exec.h
@@ -68,6 +68,7 @@ void do_msubu (void); @@ -68,6 +68,7 @@ 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_entryhi(uint32_t in);
71 void do_mtc0_status_debug(uint32_t old, uint32_t val); 72 void do_mtc0_status_debug(uint32_t old, uint32_t val);
72 void do_mtc0_status_irqraise_debug(void); 73 void do_mtc0_status_irqraise_debug(void);
73 void do_tlbwi (void); 74 void do_tlbwi (void);
target-mips/helper.c
@@ -302,15 +302,9 @@ void do_interrupt (CPUState *env) @@ -302,15 +302,9 @@ void do_interrupt (CPUState *env)
302 #endif 302 #endif
303 env->CP0_Wired = 0; 303 env->CP0_Wired = 0;
304 env->CP0_Config0 = MIPS_CONFIG0; 304 env->CP0_Config0 = MIPS_CONFIG0;
305 -#if defined (MIPS_CONFIG1)  
306 env->CP0_Config1 = MIPS_CONFIG1; 305 env->CP0_Config1 = MIPS_CONFIG1;
307 -#endif  
308 -#if defined (MIPS_CONFIG2)  
309 env->CP0_Config2 = MIPS_CONFIG2; 306 env->CP0_Config2 = MIPS_CONFIG2;
310 -#endif  
311 -#if defined (MIPS_CONFIG3)  
312 env->CP0_Config3 = MIPS_CONFIG3; 307 env->CP0_Config3 = MIPS_CONFIG3;
313 -#endif  
314 env->CP0_WatchLo = 0; 308 env->CP0_WatchLo = 0;
315 env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV); 309 env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV);
316 goto set_error_EPC; 310 goto set_error_EPC;
target-mips/mips-defs.h
@@ -29,26 +29,44 @@ @@ -29,26 +29,44 @@
29 * Define a major version 1, minor version 0. 29 * Define a major version 1, minor version 0.
30 */ 30 */
31 #define MIPS_FCR0 ((0 << 16) | (1 << 8) | (1 << 4) | 0) 31 #define MIPS_FCR0 ((0 << 16) | (1 << 8) | (1 << 4) | 0)
32 -/* Have config1, uses TLB */  
33 -#define MIPS_CONFIG0_1 \  
34 -((1 << CP0C0_M) | (0 << CP0C0_K23) | (0 << CP0C0_KU) | \  
35 - (1 << CP0C0_MT) | (2 << CP0C0_K0)) 32 + /* Have config1, is MIPS32R1, uses TLB, no virtual icache,
  33 + uncached coherency */
  34 +#define MIPS_CONFIG0_1 \
  35 + ((1 << CP0C0_M) | (0x0 << CP0C0_K23) | (0x0 << CP0C0_KU) | \
  36 + (0x0 << CP0C0_AT) | (0x0 << CP0C0_AR) | (0x1 << CP0C0_MT) | \
  37 + (0x2 << CP0C0_K0))
36 #ifdef TARGET_WORDS_BIGENDIAN 38 #ifdef TARGET_WORDS_BIGENDIAN
37 #define MIPS_CONFIG0 (MIPS_CONFIG0_1 | (1 << CP0C0_BE)) 39 #define MIPS_CONFIG0 (MIPS_CONFIG0_1 | (1 << CP0C0_BE))
38 #else 40 #else
39 #define MIPS_CONFIG0 MIPS_CONFIG0_1 41 #define MIPS_CONFIG0 MIPS_CONFIG0_1
40 #endif 42 #endif
41 -/* 16 TLBs, 64 sets Icache, 16 bytes Icache line, 2-way Icache,  
42 - * 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache,  
43 - * no performance counters, watch registers present, no code compression,  
44 - * EJTAG present, FPU enable bit depending on MIPS_USES_FPU  
45 - */  
46 -#define MIPS_CONFIG1 \  
47 -((15 << CP0C1_MMU) | \  
48 - (0x000 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x01 << CP0C1_IA) | \  
49 - (0x000 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x01 << CP0C1_DA) | \  
50 - (0 << CP0C1_PC) | (1 << CP0C1_WR) | (0 << CP0C1_CA) | \  
51 - (1 << CP0C1_EP) | (MIPS_USES_FPU << CP0C1_FP)) 43 +/* Have config2, 16 TLB entries, 64 sets Icache, 16 bytes Icache line,
  44 + 2-way Icache, 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache,
  45 + no coprocessor2 attached, no MDMX support attached,
  46 + no performance counters, watch registers present,
  47 + no code compression, EJTAG present, FPU enable bit depending on
  48 + MIPS_USES_FPU */
  49 +#define MIPS_CONFIG1_1 \
  50 +((1 << CP0C1_M) | ((MIPS_TLB_NB - 1) << CP0C1_MMU) | \
  51 + (0x0 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x1 << CP0C1_IA) | \
  52 + (0x0 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x1 << CP0C1_DA) | \
  53 + (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \
  54 + (1 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP))
  55 +#ifdef MIPS_USES_FPU
  56 +#define MIPS_CONFIG1 (MIPS_CONFIG1_1 | (1 << CP0C1_FP))
  57 +#else
  58 +#define MIPS_CONFIG1 (MIPS_CONFIG1_1 | (0 << CP0C1_FP))
  59 +#endif
  60 +/* Have config3, no tertiary/secondary caches implemented */
  61 +#define MIPS_CONFIG2 \
  62 +((1 << CP0C2_M))
  63 +/* No config4, no DSP ASE, no large physaddr,
  64 + no external interrupt controller, no vectored interupts,
  65 + no 1kb pages, no MT ASE, no SmartMIPS ASE, no trace logic */
  66 +#define MIPS_CONFIG3 \
  67 +((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \
  68 + (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \
  69 + (0 << CP0C3_MT) | (0 << CP0C3_SM) | (0 << CP0C3_TL))
52 #elif (MIPS_CPU == MIPS_R4Kp) 70 #elif (MIPS_CPU == MIPS_R4Kp)
53 /* 32 bits target */ 71 /* 32 bits target */
54 #define TARGET_LONG_BITS 32 72 #define TARGET_LONG_BITS 32
@@ -60,7 +78,7 @@ @@ -60,7 +78,7 @@
60 #define MIPS_USES_R4K_FPM 78 #define MIPS_USES_R4K_FPM
61 #else 79 #else
62 #error "MIPS CPU not defined" 80 #error "MIPS CPU not defined"
63 -/* Remainder for other flags */ 81 +/* Reminder for other flags */
64 //#define TARGET_MIPS64 82 //#define TARGET_MIPS64
65 //#define MIPS_USES_FPU 83 //#define MIPS_USES_FPU
66 #endif 84 #endif
target-mips/op.c
@@ -437,6 +437,18 @@ void op_srl (void) @@ -437,6 +437,18 @@ void op_srl (void)
437 RETURN(); 437 RETURN();
438 } 438 }
439 439
  440 +void op_rotr (void)
  441 +{
  442 + target_ulong tmp;
  443 +
  444 + if (T1) {
  445 + tmp = T0 << (0x20 - T1);
  446 + T0 = (T0 >> T1) | tmp;
  447 + } else
  448 + T0 = T1;
  449 + RETURN();
  450 +}
  451 +
440 void op_sllv (void) 452 void op_sllv (void)
441 { 453 {
442 T0 = T1 << (T0 & 0x1F); 454 T0 = T1 << (T0 & 0x1F);
@@ -455,6 +467,19 @@ void op_srlv (void) @@ -455,6 +467,19 @@ void op_srlv (void)
455 RETURN(); 467 RETURN();
456 } 468 }
457 469
  470 +void op_rotrv (void)
  471 +{
  472 + target_ulong tmp;
  473 +
  474 + T0 &= 0x1F;
  475 + if (T0) {
  476 + tmp = T1 << (0x20 - T0);
  477 + T0 = (T1 >> T0) | tmp;
  478 + } else
  479 + T0 = T1;
  480 + RETURN();
  481 +}
  482 +
458 void op_clo (void) 483 void op_clo (void)
459 { 484 {
460 int n; 485 int n;
@@ -602,6 +627,20 @@ void op_movz (void) @@ -602,6 +627,20 @@ void op_movz (void)
602 RETURN(); 627 RETURN();
603 } 628 }
604 629
  630 +void op_movf (void)
  631 +{
  632 + if (!(env->fcr31 & PARAM1))
  633 + env->gpr[PARAM2] = env->gpr[PARAM3];
  634 + RETURN();
  635 +}
  636 +
  637 +void op_movt (void)
  638 +{
  639 + if (env->fcr31 & PARAM1)
  640 + env->gpr[PARAM2] = env->gpr[PARAM3];
  641 + RETURN();
  642 +}
  643 +
605 /* Tests */ 644 /* Tests */
606 #define OP_COND(name, cond) \ 645 #define OP_COND(name, cond) \
607 void glue(op_, name) (void) \ 646 void glue(op_, name) (void) \
@@ -625,28 +664,32 @@ OP_COND(gtz, (int32_t)T0 &gt; 0); @@ -625,28 +664,32 @@ OP_COND(gtz, (int32_t)T0 &gt; 0);
625 OP_COND(lez, (int32_t)T0 <= 0); 664 OP_COND(lez, (int32_t)T0 <= 0);
626 OP_COND(ltz, (int32_t)T0 < 0); 665 OP_COND(ltz, (int32_t)T0 < 0);
627 666
628 -/* Branchs */ 667 +/* Branches */
629 //#undef USE_DIRECT_JUMP 668 //#undef USE_DIRECT_JUMP
630 669
631 void OPPROTO op_goto_tb0(void) 670 void OPPROTO op_goto_tb0(void)
632 { 671 {
633 GOTO_TB(op_goto_tb0, PARAM1, 0); 672 GOTO_TB(op_goto_tb0, PARAM1, 0);
  673 + RETURN();
634 } 674 }
635 675
636 void OPPROTO op_goto_tb1(void) 676 void OPPROTO op_goto_tb1(void)
637 { 677 {
638 GOTO_TB(op_goto_tb1, PARAM1, 1); 678 GOTO_TB(op_goto_tb1, PARAM1, 1);
  679 + RETURN();
639 } 680 }
640 681
641 /* Branch to register */ 682 /* Branch to register */
642 void op_save_breg_target (void) 683 void op_save_breg_target (void)
643 { 684 {
644 env->btarget = T2; 685 env->btarget = T2;
  686 + RETURN();
645 } 687 }
646 688
647 void op_restore_breg_target (void) 689 void op_restore_breg_target (void)
648 { 690 {
649 T2 = env->btarget; 691 T2 = env->btarget;
  692 + RETURN();
650 } 693 }
651 694
652 void op_breg (void) 695 void op_breg (void)
@@ -724,12 +767,24 @@ void op_mfc0_pagemask (void) @@ -724,12 +767,24 @@ void op_mfc0_pagemask (void)
724 RETURN(); 767 RETURN();
725 } 768 }
726 769
  770 +void op_mfc0_pagegrain (void)
  771 +{
  772 + T0 = env->CP0_PageGrain;
  773 + RETURN();
  774 +}
  775 +
727 void op_mfc0_wired (void) 776 void op_mfc0_wired (void)
728 { 777 {
729 T0 = env->CP0_Wired; 778 T0 = env->CP0_Wired;
730 RETURN(); 779 RETURN();
731 } 780 }
732 781
  782 +void op_mfc0_hwrena (void)
  783 +{
  784 + T0 = env->CP0_HWREna;
  785 + RETURN();
  786 +}
  787 +
733 void op_mfc0_badvaddr (void) 788 void op_mfc0_badvaddr (void)
734 { 789 {
735 T0 = env->CP0_BadVAddr; 790 T0 = env->CP0_BadVAddr;
@@ -766,6 +821,18 @@ void op_mfc0_status (void) @@ -766,6 +821,18 @@ void op_mfc0_status (void)
766 RETURN(); 821 RETURN();
767 } 822 }
768 823
  824 +void op_mfc0_intctl (void)
  825 +{
  826 + T0 = env->CP0_IntCtl;
  827 + RETURN();
  828 +}
  829 +
  830 +void op_mfc0_srsctl (void)
  831 +{
  832 + T0 = env->CP0_SRSCtl;
  833 + RETURN();
  834 +}
  835 +
769 void op_mfc0_cause (void) 836 void op_mfc0_cause (void)
770 { 837 {
771 T0 = env->CP0_Cause; 838 T0 = env->CP0_Cause;
@@ -784,6 +851,12 @@ void op_mfc0_prid (void) @@ -784,6 +851,12 @@ void op_mfc0_prid (void)
784 RETURN(); 851 RETURN();
785 } 852 }
786 853
  854 +void op_mfc0_ebase (void)
  855 +{
  856 + T0 = env->CP0_EBase;
  857 + RETURN();
  858 +}
  859 +
787 void op_mfc0_config0 (void) 860 void op_mfc0_config0 (void)
788 { 861 {
789 T0 = env->CP0_Config0; 862 T0 = env->CP0_Config0;
@@ -796,24 +869,48 @@ void op_mfc0_config1 (void) @@ -796,24 +869,48 @@ void op_mfc0_config1 (void)
796 RETURN(); 869 RETURN();
797 } 870 }
798 871
  872 +void op_mfc0_config2 (void)
  873 +{
  874 + T0 = env->CP0_Config2;
  875 + RETURN();
  876 +}
  877 +
  878 +void op_mfc0_config3 (void)
  879 +{
  880 + T0 = env->CP0_Config3;
  881 + RETURN();
  882 +}
  883 +
799 void op_mfc0_lladdr (void) 884 void op_mfc0_lladdr (void)
800 { 885 {
801 T0 = env->CP0_LLAddr >> 4; 886 T0 = env->CP0_LLAddr >> 4;
802 RETURN(); 887 RETURN();
803 } 888 }
804 889
805 -void op_mfc0_watchlo (void) 890 +void op_mfc0_watchlo0 (void)
806 { 891 {
807 T0 = env->CP0_WatchLo; 892 T0 = env->CP0_WatchLo;
808 RETURN(); 893 RETURN();
809 } 894 }
810 895
811 -void op_mfc0_watchhi (void) 896 +void op_mfc0_watchhi0 (void)
812 { 897 {
813 T0 = env->CP0_WatchHi; 898 T0 = env->CP0_WatchHi;
814 RETURN(); 899 RETURN();
815 } 900 }
816 901
  902 +void op_mfc0_xcontext (void)
  903 +{
  904 + T0 = env->CP0_XContext;
  905 + RETURN();
  906 +}
  907 +
  908 +void op_mfc0_framemask (void)
  909 +{
  910 + T0 = env->CP0_Framemask;
  911 + RETURN();
  912 +}
  913 +
817 void op_mfc0_debug (void) 914 void op_mfc0_debug (void)
818 { 915 {
819 T0 = env->CP0_Debug; 916 T0 = env->CP0_Debug;
@@ -828,6 +925,12 @@ void op_mfc0_depc (void) @@ -828,6 +925,12 @@ void op_mfc0_depc (void)
828 RETURN(); 925 RETURN();
829 } 926 }
830 927
  928 +void op_mfc0_performance0 (void)
  929 +{
  930 + T0 = env->CP0_Performance0;
  931 + RETURN();
  932 +}
  933 +
831 void op_mfc0_taglo (void) 934 void op_mfc0_taglo (void)
832 { 935 {
833 T0 = env->CP0_TagLo; 936 T0 = env->CP0_TagLo;
@@ -840,6 +943,18 @@ void op_mfc0_datalo (void) @@ -840,6 +943,18 @@ void op_mfc0_datalo (void)
840 RETURN(); 943 RETURN();
841 } 944 }
842 945
  946 +void op_mfc0_taghi (void)
  947 +{
  948 + T0 = env->CP0_TagHi;
  949 + RETURN();
  950 +}
  951 +
  952 +void op_mfc0_datahi (void)
  953 +{
  954 + T0 = env->CP0_DataHi;
  955 + RETURN();
  956 +}
  957 +
843 void op_mfc0_errorepc (void) 958 void op_mfc0_errorepc (void)
844 { 959 {
845 T0 = env->CP0_ErrorEPC; 960 T0 = env->CP0_ErrorEPC;
@@ -854,37 +969,57 @@ void op_mfc0_desave (void) @@ -854,37 +969,57 @@ void op_mfc0_desave (void)
854 969
855 void op_mtc0_index (void) 970 void op_mtc0_index (void)
856 { 971 {
857 - env->CP0_index = (env->CP0_index & 0x80000000) | (T0 & 0x0000000F); 972 + env->CP0_index = (env->CP0_index & 0x80000000) | (T0 & (MIPS_TLB_NB - 1));
858 RETURN(); 973 RETURN();
859 } 974 }
860 975
861 void op_mtc0_entrylo0 (void) 976 void op_mtc0_entrylo0 (void)
862 { 977 {
863 - env->CP0_EntryLo0 = T0 & 0x3FFFFFFF; 978 + /* Large physaddr not implemented */
  979 + /* 1k pages not implemented */
  980 + env->CP0_EntryLo0 = T0 & 0x3FFFFFFFUL;
864 RETURN(); 981 RETURN();
865 } 982 }
866 983
867 void op_mtc0_entrylo1 (void) 984 void op_mtc0_entrylo1 (void)
868 { 985 {
869 - env->CP0_EntryLo1 = T0 & 0x3FFFFFFF; 986 + /* Large physaddr not implemented */
  987 + /* 1k pages not implemented */
  988 + env->CP0_EntryLo1 = T0 & 0x3FFFFFFFUL;
870 RETURN(); 989 RETURN();
871 } 990 }
872 991
873 void op_mtc0_context (void) 992 void op_mtc0_context (void)
874 { 993 {
875 - env->CP0_Context = (env->CP0_Context & 0xFF800000) | (T0 & 0x007FFFF0); 994 + env->CP0_Context = (env->CP0_Context & ~0x007FFFFF) | (T0 & 0x007FFFF0);
876 RETURN(); 995 RETURN();
877 } 996 }
878 997
879 void op_mtc0_pagemask (void) 998 void op_mtc0_pagemask (void)
880 { 999 {
881 - env->CP0_PageMask = T0 & 0x01FFE000; 1000 + /* 1k pages not implemented */
  1001 + env->CP0_PageMask = T0 & 0x1FFFE000;
  1002 + RETURN();
  1003 +}
  1004 +
  1005 +void op_mtc0_pagegrain (void)
  1006 +{
  1007 + /* SmartMIPS not implemented */
  1008 + /* Large physaddr not implemented */
  1009 + /* 1k pages not implemented */
  1010 + env->CP0_PageGrain = 0;
882 RETURN(); 1011 RETURN();
883 } 1012 }
884 1013
885 void op_mtc0_wired (void) 1014 void op_mtc0_wired (void)
886 { 1015 {
887 - env->CP0_Wired = T0 & 0x0000000F; 1016 + env->CP0_Wired = T0 & (MIPS_TLB_NB - 1);
  1017 + RETURN();
  1018 +}
  1019 +
  1020 +void op_mtc0_hwrena (void)
  1021 +{
  1022 + env->CP0_HWREna = T0 & 0x0000000F;
888 RETURN(); 1023 RETURN();
889 } 1024 }
890 1025
@@ -898,6 +1033,8 @@ void op_mtc0_entryhi (void) @@ -898,6 +1033,8 @@ void op_mtc0_entryhi (void)
898 { 1033 {
899 uint32_t old, val; 1034 uint32_t old, val;
900 1035
  1036 + /* 1k pages not implemented */
  1037 + /* Ignore MIPS64 TLB for now */
901 val = T0 & 0xFFFFE0FF; 1038 val = T0 & 0xFFFFE0FF;
902 old = env->CP0_EntryHi; 1039 old = env->CP0_EntryHi;
903 env->CP0_EntryHi = val; 1040 env->CP0_EntryHi = val;
@@ -950,6 +1087,20 @@ void op_mtc0_status (void) @@ -950,6 +1087,20 @@ void op_mtc0_status (void)
950 RETURN(); 1087 RETURN();
951 } 1088 }
952 1089
  1090 +void op_mtc0_intctl (void)
  1091 +{
  1092 + /* vectored interrupts not implemented */
  1093 + env->CP0_IntCtl = 0;
  1094 + RETURN();
  1095 +}
  1096 +
  1097 +void op_mtc0_srsctl (void)
  1098 +{
  1099 + /* shadow registers not implemented */
  1100 + env->CP0_SRSCtl = 0;
  1101 + RETURN();
  1102 +}
  1103 +
953 void op_mtc0_cause (void) 1104 void op_mtc0_cause (void)
954 { 1105 {
955 uint32_t val, old; 1106 uint32_t val, old;
@@ -960,7 +1111,6 @@ void op_mtc0_cause (void) @@ -960,7 +1111,6 @@ void op_mtc0_cause (void)
960 #if 0 1111 #if 0
961 { 1112 {
962 int i, mask; 1113 int i, mask;
963 -  
964 /* Check if we ever asserted a software IRQ */ 1114 /* Check if we ever asserted a software IRQ */
965 for (i = 0; i < 2; i++) { 1115 for (i = 0; i < 2; i++) {
966 mask = 0x100 << i; 1116 mask = 0x100 << i;
@@ -978,28 +1128,56 @@ void op_mtc0_epc (void) @@ -978,28 +1128,56 @@ void op_mtc0_epc (void)
978 RETURN(); 1128 RETURN();
979 } 1129 }
980 1130
  1131 +void op_mtc0_ebase (void)
  1132 +{
  1133 + /* vectored interrupts not implemented */
  1134 + /* Multi-CPU not implemented */
  1135 + env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000);
  1136 + RETURN();
  1137 +}
  1138 +
981 void op_mtc0_config0 (void) 1139 void op_mtc0_config0 (void)
982 { 1140 {
983 #if defined(MIPS_USES_R4K_TLB) 1141 #if defined(MIPS_USES_R4K_TLB)
984 - env->CP0_Config0 = (env->CP0_Config0 & 0x8017FF80) | (T0 & 0x7E000001); 1142 + /* Fixed mapping MMU not implemented */
  1143 + env->CP0_Config0 = (env->CP0_Config0 & 0x8017FF88) | (T0 & 0x00000001);
985 #else 1144 #else
986 - env->CP0_Config0 = (env->CP0_Config0 & 0xFE17FF80) | (T0 & 0x00000001); 1145 + env->CP0_Config0 = (env->CP0_Config0 & 0xFE17FF88) | (T0 & 0x00000001);
987 #endif 1146 #endif
988 RETURN(); 1147 RETURN();
989 } 1148 }
990 1149
991 -void op_mtc0_watchlo (void) 1150 +void op_mtc0_config2 (void)
  1151 +{
  1152 + /* tertiary/secondary caches not implemented */
  1153 + env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
  1154 + RETURN();
  1155 +}
  1156 +
  1157 +void op_mtc0_watchlo0 (void)
992 { 1158 {
993 env->CP0_WatchLo = T0; 1159 env->CP0_WatchLo = T0;
994 RETURN(); 1160 RETURN();
995 } 1161 }
996 1162
997 -void op_mtc0_watchhi (void) 1163 +void op_mtc0_watchhi0 (void)
998 { 1164 {
999 env->CP0_WatchHi = T0 & 0x40FF0FF8; 1165 env->CP0_WatchHi = T0 & 0x40FF0FF8;
1000 RETURN(); 1166 RETURN();
1001 } 1167 }
1002 1168
  1169 +void op_mtc0_xcontext (void)
  1170 +{
  1171 + env->CP0_XContext = T0; /* XXX */
  1172 + RETURN();
  1173 +}
  1174 +
  1175 +void op_mtc0_framemask (void)
  1176 +{
  1177 + env->CP0_Framemask = T0; /* XXX */
  1178 + RETURN();
  1179 +}
  1180 +
1003 void op_mtc0_debug (void) 1181 void op_mtc0_debug (void)
1004 { 1182 {
1005 env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120); 1183 env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
@@ -1016,12 +1194,36 @@ void op_mtc0_depc (void) @@ -1016,12 +1194,36 @@ void op_mtc0_depc (void)
1016 RETURN(); 1194 RETURN();
1017 } 1195 }
1018 1196
  1197 +void op_mtc0_performance0 (void)
  1198 +{
  1199 + env->CP0_Performance0 = T0; /* XXX */
  1200 + RETURN();
  1201 +}
  1202 +
1019 void op_mtc0_taglo (void) 1203 void op_mtc0_taglo (void)
1020 { 1204 {
1021 env->CP0_TagLo = T0 & 0xFFFFFCF6; 1205 env->CP0_TagLo = T0 & 0xFFFFFCF6;
1022 RETURN(); 1206 RETURN();
1023 } 1207 }
1024 1208
  1209 +void op_mtc0_datalo (void)
  1210 +{
  1211 + env->CP0_DataLo = T0; /* XXX */
  1212 + RETURN();
  1213 +}
  1214 +
  1215 +void op_mtc0_taghi (void)
  1216 +{
  1217 + env->CP0_TagHi = T0; /* XXX */
  1218 + RETURN();
  1219 +}
  1220 +
  1221 +void op_mtc0_datahi (void)
  1222 +{
  1223 + env->CP0_DataHi = T0; /* XXX */
  1224 + RETURN();
  1225 +}
  1226 +
1025 void op_mtc0_errorepc (void) 1227 void op_mtc0_errorepc (void)
1026 { 1228 {
1027 env->CP0_ErrorEPC = T0; 1229 env->CP0_ErrorEPC = T0;
@@ -1422,6 +1624,42 @@ void op_tlbr (void) @@ -1422,6 +1624,42 @@ void op_tlbr (void)
1422 void op_pmon (void) 1624 void op_pmon (void)
1423 { 1625 {
1424 CALL_FROM_TB1(do_pmon, PARAM1); 1626 CALL_FROM_TB1(do_pmon, PARAM1);
  1627 + RETURN();
  1628 +}
  1629 +
  1630 +void op_di (void)
  1631 +{
  1632 + uint32_t val;
  1633 +
  1634 + T0 = env->CP0_Status;
  1635 + val = T0 & ~(1 << CP0St_IE);
  1636 + if (val != T0) {
  1637 + env->interrupt_request &= ~CPU_INTERRUPT_HARD;
  1638 + env->CP0_Status = val;
  1639 + }
  1640 + RETURN();
  1641 +}
  1642 +
  1643 +void op_ei (void)
  1644 +{
  1645 + uint32_t val;
  1646 +
  1647 + T0 = env->CP0_Status;
  1648 + val = T0 | (1 << CP0St_IE);
  1649 + if (val != T0) {
  1650 + const uint32_t mask = 0x0000FF00;
  1651 +
  1652 + env->CP0_Status = val;
  1653 + if (!(env->hflags & MIPS_HFLAG_EXL) &&
  1654 + !(env->hflags & MIPS_HFLAG_ERL) &&
  1655 + !(env->hflags & MIPS_HFLAG_DM) &&
  1656 + (env->CP0_Status & env->CP0_Cause & mask)) {
  1657 + env->interrupt_request |= CPU_INTERRUPT_HARD;
  1658 + if (logfile)
  1659 + CALL_FROM_TB0(do_mtc0_status_irqraise_debug);
  1660 + }
  1661 + }
  1662 + RETURN();
1425 } 1663 }
1426 1664
1427 void op_trap (void) 1665 void op_trap (void)
@@ -1434,12 +1672,14 @@ void op_trap (void) @@ -1434,12 +1672,14 @@ void op_trap (void)
1434 1672
1435 void op_debug (void) 1673 void op_debug (void)
1436 { 1674 {
1437 - CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG); 1675 + CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG);
  1676 + RETURN();
1438 } 1677 }
1439 1678
1440 void op_set_lladdr (void) 1679 void op_set_lladdr (void)
1441 { 1680 {
1442 env->CP0_LLAddr = T2; 1681 env->CP0_LLAddr = T2;
  1682 + RETURN();
1443 } 1683 }
1444 1684
1445 void debug_eret (void); 1685 void debug_eret (void);
@@ -1456,12 +1696,50 @@ void op_eret (void) @@ -1456,12 +1696,50 @@ void op_eret (void)
1456 env->CP0_Status &= ~(1 << CP0St_EXL); 1696 env->CP0_Status &= ~(1 << CP0St_EXL);
1457 } 1697 }
1458 env->CP0_LLAddr = 1; 1698 env->CP0_LLAddr = 1;
  1699 + RETURN();
1459 } 1700 }
1460 1701
1461 void op_deret (void) 1702 void op_deret (void)
1462 { 1703 {
1463 CALL_FROM_TB0(debug_eret); 1704 CALL_FROM_TB0(debug_eret);
1464 env->PC = env->CP0_DEPC; 1705 env->PC = env->CP0_DEPC;
  1706 + RETURN();
  1707 +}
  1708 +
  1709 +void op_rdhwr_cpunum(void)
  1710 +{
  1711 + if (env->CP0_HWREna & (1 << 0))
  1712 + T0 = env->CP0_EBase & 0x2ff;
  1713 + else
  1714 + CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
  1715 + RETURN();
  1716 +}
  1717 +
  1718 +void op_rdhwr_synci_step(void)
  1719 +{
  1720 + if (env->CP0_HWREna & (1 << 1))
  1721 + T0 = env->SYNCI_Step;
  1722 + else
  1723 + CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
  1724 + RETURN();
  1725 +}
  1726 +
  1727 +void op_rdhwr_cc(void)
  1728 +{
  1729 + if (env->CP0_HWREna & (1 << 2))
  1730 + T0 = env->CP0_Count;
  1731 + else
  1732 + CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
  1733 + RETURN();
  1734 +}
  1735 +
  1736 +void op_rdhwr_ccres(void)
  1737 +{
  1738 + if (env->CP0_HWREna & (1 << 3))
  1739 + T0 = env->CCRes;
  1740 + else
  1741 + CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
  1742 + RETURN();
1465 } 1743 }
1466 1744
1467 void op_save_state (void) 1745 void op_save_state (void)
@@ -1491,10 +1769,62 @@ void op_raise_exception_err (void) @@ -1491,10 +1769,62 @@ void op_raise_exception_err (void)
1491 void op_exit_tb (void) 1769 void op_exit_tb (void)
1492 { 1770 {
1493 EXIT_TB(); 1771 EXIT_TB();
  1772 + RETURN();
1494 } 1773 }
1495 1774
1496 void op_wait (void) 1775 void op_wait (void)
1497 { 1776 {
1498 env->halted = 1; 1777 env->halted = 1;
1499 CALL_FROM_TB1(do_raise_exception, EXCP_HLT); 1778 CALL_FROM_TB1(do_raise_exception, EXCP_HLT);
  1779 + RETURN();
  1780 +}
  1781 +
  1782 +/* Bitfield operations. */
  1783 +void op_ext(void)
  1784 +{
  1785 + unsigned int pos = PARAM1;
  1786 + unsigned int size = PARAM2;
  1787 +
  1788 + T0 = (T1 >> pos) & ((1 << size) - 1);
  1789 + RETURN();
  1790 +}
  1791 +
  1792 +void op_ins(void)
  1793 +{
  1794 + unsigned int pos = PARAM1;
  1795 + unsigned int size = PARAM2;
  1796 + target_ulong mask = ((1 << size) - 1) << pos;
  1797 +
  1798 + T0 = (T2 & ~mask) | ((T1 << pos) & mask);
  1799 + RETURN();
  1800 +}
  1801 +
  1802 +void op_wsbh(void)
  1803 +{
  1804 + T0 = ((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF);
  1805 + RETURN();
  1806 +}
  1807 +
  1808 +void op_dsbh(void)
  1809 +{
  1810 + T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
  1811 + RETURN();
  1812 +}
  1813 +
  1814 +void op_dshd(void)
  1815 +{
  1816 + T0 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
  1817 + RETURN();
  1818 +}
  1819 +
  1820 +void op_seb(void)
  1821 +{
  1822 + T0 = ((T1 & 0xFF) ^ 0x80) - 0x80;
  1823 + RETURN();
  1824 +}
  1825 +
  1826 +void op_seh(void)
  1827 +{
  1828 + T0 = ((T1 & 0xFFFF) ^ 0x8000) - 0x8000;
  1829 + RETURN();
1500 } 1830 }
target-mips/op_helper.c
@@ -153,12 +153,12 @@ void cpu_mips_store_compare(CPUState *env, uint32_t value) @@ -153,12 +153,12 @@ void cpu_mips_store_compare(CPUState *env, uint32_t value)
153 153
154 void do_mtc0_status_debug(uint32_t old, uint32_t val) 154 void do_mtc0_status_debug(uint32_t old, uint32_t val)
155 { 155 {
156 - cpu_abort(env, "mtc0 status\n"); 156 + cpu_abort(env, "mtc0 status debug\n");
157 } 157 }
158 158
159 -void do_mtc0_status_irqraise_debug(void) 159 +void do_mtc0_status_irqraise_debug (void)
160 { 160 {
161 - cpu_abort(env, "mtc0 status\n"); 161 + cpu_abort(env, "mtc0 status irqraise debug\n");
162 } 162 }
163 163
164 void do_tlbwi (void) 164 void do_tlbwi (void)
target-mips/translate.c
@@ -50,184 +50,313 @@ static uint32_t *gen_opparam_ptr; @@ -50,184 +50,313 @@ static uint32_t *gen_opparam_ptr;
50 50
51 #include "gen-op.h" 51 #include "gen-op.h"
52 52
53 -/* MIPS opcodes */  
54 -#define EXT_SPECIAL 0x100  
55 -#define EXT_SPECIAL2 0x200  
56 -#define EXT_REGIMM 0x300  
57 -#define EXT_CP0 0x400  
58 -#define EXT_CP1 0x500  
59 -#define EXT_CP2 0x600  
60 -#define EXT_CP3 0x700 53 +/* MIPS major opcodes */
  54 +#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
61 55
62 enum { 56 enum {
63 /* indirect opcode tables */ 57 /* indirect opcode tables */
64 - OPC_SPECIAL = 0x00,  
65 - OPC_BREGIMM = 0x01,  
66 - OPC_CP0 = 0x10,  
67 - OPC_CP1 = 0x11,  
68 - OPC_CP2 = 0x12,  
69 - OPC_CP3 = 0x13,  
70 - OPC_SPECIAL2 = 0x1C, 58 + OPC_SPECIAL = (0x00 << 26),
  59 + OPC_REGIMM = (0x01 << 26),
  60 + OPC_CP0 = (0x10 << 26),
  61 + OPC_CP1 = (0x11 << 26),
  62 + OPC_CP2 = (0x12 << 26),
  63 + OPC_CP3 = (0x13 << 26),
  64 + OPC_SPECIAL2 = (0x1C << 26),
  65 + OPC_SPECIAL3 = (0x1F << 26),
71 /* arithmetic with immediate */ 66 /* arithmetic with immediate */
72 - OPC_ADDI = 0x08,  
73 - OPC_ADDIU = 0x09,  
74 - OPC_SLTI = 0x0A,  
75 - OPC_SLTIU = 0x0B,  
76 - OPC_ANDI = 0x0C,  
77 - OPC_ORI = 0x0D,  
78 - OPC_XORI = 0x0E,  
79 - OPC_LUI = 0x0F, 67 + OPC_ADDI = (0x08 << 26),
  68 + OPC_ADDIU = (0x09 << 26),
  69 + OPC_SLTI = (0x0A << 26),
  70 + OPC_SLTIU = (0x0B << 26),
  71 + OPC_ANDI = (0x0C << 26),
  72 + OPC_ORI = (0x0D << 26),
  73 + OPC_XORI = (0x0E << 26),
  74 + OPC_LUI = (0x0F << 26),
  75 + OPC_DADDI = (0x18 << 26),
  76 + OPC_DADDIU = (0x19 << 26),
80 /* Jump and branches */ 77 /* Jump and branches */
81 - OPC_J = 0x02,  
82 - OPC_JAL = 0x03,  
83 - OPC_BEQ = 0x04, /* Unconditional if rs = rt = 0 (B) */  
84 - OPC_BEQL = 0x14,  
85 - OPC_BNE = 0x05,  
86 - OPC_BNEL = 0x15,  
87 - OPC_BLEZ = 0x06,  
88 - OPC_BLEZL = 0x16,  
89 - OPC_BGTZ = 0x07,  
90 - OPC_BGTZL = 0x17,  
91 - OPC_JALX = 0x1D, /* MIPS 16 only */ 78 + OPC_J = (0x02 << 26),
  79 + OPC_JAL = (0x03 << 26),
  80 + OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
  81 + OPC_BEQL = (0x14 << 26),
  82 + OPC_BNE = (0x05 << 26),
  83 + OPC_BNEL = (0x15 << 26),
  84 + OPC_BLEZ = (0x06 << 26),
  85 + OPC_BLEZL = (0x16 << 26),
  86 + OPC_BGTZ = (0x07 << 26),
  87 + OPC_BGTZL = (0x17 << 26),
  88 + OPC_JALX = (0x1D << 26), /* MIPS 16 only */
92 /* Load and stores */ 89 /* Load and stores */
93 - OPC_LB = 0x20,  
94 - OPC_LH = 0x21,  
95 - OPC_LWL = 0x22,  
96 - OPC_LW = 0x23,  
97 - OPC_LBU = 0x24,  
98 - OPC_LHU = 0x25,  
99 - OPC_LWR = 0x26,  
100 - OPC_LWU = 0x27,  
101 - OPC_SB = 0x28,  
102 - OPC_SH = 0x29,  
103 - OPC_SWL = 0x2A,  
104 - OPC_SW = 0x2B,  
105 - OPC_SWR = 0x2E,  
106 - OPC_LL = 0x30,  
107 - OPC_SC = 0x38, 90 + OPC_LDL = (0x1A << 26),
  91 + OPC_LDR = (0x1B << 26),
  92 + OPC_LB = (0x20 << 26),
  93 + OPC_LH = (0x21 << 26),
  94 + OPC_LWL = (0x22 << 26),
  95 + OPC_LW = (0x23 << 26),
  96 + OPC_LBU = (0x24 << 26),
  97 + OPC_LHU = (0x25 << 26),
  98 + OPC_LWR = (0x26 << 26),
  99 + OPC_LWU = (0x27 << 26),
  100 + OPC_SB = (0x28 << 26),
  101 + OPC_SH = (0x29 << 26),
  102 + OPC_SWL = (0x2A << 26),
  103 + OPC_SW = (0x2B << 26),
  104 + OPC_SDL = (0x2C << 26),
  105 + OPC_SDR = (0x2D << 26),
  106 + OPC_SWR = (0x2E << 26),
  107 + OPC_LL = (0x30 << 26),
  108 + OPC_LLD = (0x34 << 26),
  109 + OPC_LD = (0x37 << 26),
  110 + OPC_SC = (0x38 << 26),
  111 + OPC_SCD = (0x3C << 26),
  112 + OPC_SD = (0x3F << 26),
108 /* Floating point load/store */ 113 /* Floating point load/store */
109 - OPC_LWC1 = 0x31,  
110 - OPC_LWC2 = 0x32,  
111 - OPC_LDC1 = 0x35,  
112 - OPC_LDC2 = 0x36,  
113 - OPC_SWC1 = 0x39,  
114 - OPC_SWC2 = 0x3A,  
115 - OPC_SDC1 = 0x3D,  
116 - OPC_SDC2 = 0x3E, 114 + OPC_LWC1 = (0x31 << 26),
  115 + OPC_LWC2 = (0x32 << 26),
  116 + OPC_LDC1 = (0x35 << 26),
  117 + OPC_LDC2 = (0x36 << 26),
  118 + OPC_SWC1 = (0x39 << 26),
  119 + OPC_SWC2 = (0x3A << 26),
  120 + OPC_SDC1 = (0x3D << 26),
  121 + OPC_SDC2 = (0x3E << 26),
  122 + /* MDMX ASE specific */
  123 + OPC_MDMX = (0x1E << 26),
117 /* Cache and prefetch */ 124 /* Cache and prefetch */
118 - OPC_CACHE = 0x2F,  
119 - OPC_PREF = 0x33, 125 + OPC_CACHE = (0x2F << 26),
  126 + OPC_PREF = (0x33 << 26),
  127 + /* Reserved major opcode */
  128 + OPC_MAJOR3B_RESERVED = (0x3B << 26),
120 }; 129 };
121 130
122 /* MIPS special opcodes */ 131 /* MIPS special opcodes */
  132 +#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
  133 +
123 enum { 134 enum {
124 /* Shifts */ 135 /* Shifts */
125 - OPC_SLL = 0x00 | EXT_SPECIAL, 136 + OPC_SLL = 0x00 | OPC_SPECIAL,
126 /* NOP is SLL r0, r0, 0 */ 137 /* NOP is SLL r0, r0, 0 */
127 /* SSNOP is SLL r0, r0, 1 */ 138 /* SSNOP is SLL r0, r0, 1 */
128 - OPC_SRL = 0x02 | EXT_SPECIAL,  
129 - OPC_SRA = 0x03 | EXT_SPECIAL,  
130 - OPC_SLLV = 0x04 | EXT_SPECIAL,  
131 - OPC_SRLV = 0x06 | EXT_SPECIAL,  
132 - OPC_SRAV = 0x07 | EXT_SPECIAL, 139 + /* EHB is SLL r0, r0, 3 */
  140 + OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
  141 + OPC_SRA = 0x03 | OPC_SPECIAL,
  142 + OPC_SLLV = 0x04 | OPC_SPECIAL,
  143 + OPC_SRLV = 0x06 | OPC_SPECIAL,
  144 + OPC_SRAV = 0x07 | OPC_SPECIAL,
  145 + OPC_DSLLV = 0x14 | OPC_SPECIAL,
  146 + OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
  147 + OPC_DSRAV = 0x17 | OPC_SPECIAL,
  148 + OPC_DSLL = 0x38 | OPC_SPECIAL,
  149 + OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
  150 + OPC_DSRA = 0x3B | OPC_SPECIAL,
  151 + OPC_DSLL32 = 0x3C | OPC_SPECIAL,
  152 + OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
  153 + OPC_DSRA32 = 0x3F | OPC_SPECIAL,
133 /* Multiplication / division */ 154 /* Multiplication / division */
134 - OPC_MULT = 0x18 | EXT_SPECIAL,  
135 - OPC_MULTU = 0x19 | EXT_SPECIAL,  
136 - OPC_DIV = 0x1A | EXT_SPECIAL,  
137 - OPC_DIVU = 0x1B | EXT_SPECIAL, 155 + OPC_MULT = 0x18 | OPC_SPECIAL,
  156 + OPC_MULTU = 0x19 | OPC_SPECIAL,
  157 + OPC_DIV = 0x1A | OPC_SPECIAL,
  158 + OPC_DIVU = 0x1B | OPC_SPECIAL,
  159 + OPC_DMULT = 0x1C | OPC_SPECIAL,
  160 + OPC_DMULTU = 0x1D | OPC_SPECIAL,
  161 + OPC_DDIV = 0x1E | OPC_SPECIAL,
  162 + OPC_DDIVU = 0x1F | OPC_SPECIAL,
138 /* 2 registers arithmetic / logic */ 163 /* 2 registers arithmetic / logic */
139 - OPC_ADD = 0x20 | EXT_SPECIAL,  
140 - OPC_ADDU = 0x21 | EXT_SPECIAL,  
141 - OPC_SUB = 0x22 | EXT_SPECIAL,  
142 - OPC_SUBU = 0x23 | EXT_SPECIAL,  
143 - OPC_AND = 0x24 | EXT_SPECIAL,  
144 - OPC_OR = 0x25 | EXT_SPECIAL,  
145 - OPC_XOR = 0x26 | EXT_SPECIAL,  
146 - OPC_NOR = 0x27 | EXT_SPECIAL,  
147 - OPC_SLT = 0x2A | EXT_SPECIAL,  
148 - OPC_SLTU = 0x2B | EXT_SPECIAL, 164 + OPC_ADD = 0x20 | OPC_SPECIAL,
  165 + OPC_ADDU = 0x21 | OPC_SPECIAL,
  166 + OPC_SUB = 0x22 | OPC_SPECIAL,
  167 + OPC_SUBU = 0x23 | OPC_SPECIAL,
  168 + OPC_AND = 0x24 | OPC_SPECIAL,
  169 + OPC_OR = 0x25 | OPC_SPECIAL,
  170 + OPC_XOR = 0x26 | OPC_SPECIAL,
  171 + OPC_NOR = 0x27 | OPC_SPECIAL,
  172 + OPC_SLT = 0x2A | OPC_SPECIAL,
  173 + OPC_SLTU = 0x2B | OPC_SPECIAL,
  174 + OPC_DADD = 0x2C | OPC_SPECIAL,
  175 + OPC_DADDU = 0x2D | OPC_SPECIAL,
  176 + OPC_DSUB = 0x2E | OPC_SPECIAL,
  177 + OPC_DSUBU = 0x2F | OPC_SPECIAL,
149 /* Jumps */ 178 /* Jumps */
150 - OPC_JR = 0x08 | EXT_SPECIAL,  
151 - OPC_JALR = 0x09 | EXT_SPECIAL, 179 + OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
  180 + OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
152 /* Traps */ 181 /* Traps */
153 - OPC_TGE = 0x30 | EXT_SPECIAL,  
154 - OPC_TGEU = 0x31 | EXT_SPECIAL,  
155 - OPC_TLT = 0x32 | EXT_SPECIAL,  
156 - OPC_TLTU = 0x33 | EXT_SPECIAL,  
157 - OPC_TEQ = 0x34 | EXT_SPECIAL,  
158 - OPC_TNE = 0x36 | EXT_SPECIAL, 182 + OPC_TGE = 0x30 | OPC_SPECIAL,
  183 + OPC_TGEU = 0x31 | OPC_SPECIAL,
  184 + OPC_TLT = 0x32 | OPC_SPECIAL,
  185 + OPC_TLTU = 0x33 | OPC_SPECIAL,
  186 + OPC_TEQ = 0x34 | OPC_SPECIAL,
  187 + OPC_TNE = 0x36 | OPC_SPECIAL,
159 /* HI / LO registers load & stores */ 188 /* HI / LO registers load & stores */
160 - OPC_MFHI = 0x10 | EXT_SPECIAL,  
161 - OPC_MTHI = 0x11 | EXT_SPECIAL,  
162 - OPC_MFLO = 0x12 | EXT_SPECIAL,  
163 - OPC_MTLO = 0x13 | EXT_SPECIAL, 189 + OPC_MFHI = 0x10 | OPC_SPECIAL,
  190 + OPC_MTHI = 0x11 | OPC_SPECIAL,
  191 + OPC_MFLO = 0x12 | OPC_SPECIAL,
  192 + OPC_MTLO = 0x13 | OPC_SPECIAL,
164 /* Conditional moves */ 193 /* Conditional moves */
165 - OPC_MOVZ = 0x0A | EXT_SPECIAL,  
166 - OPC_MOVN = 0x0B | EXT_SPECIAL, 194 + OPC_MOVZ = 0x0A | OPC_SPECIAL,
  195 + OPC_MOVN = 0x0B | OPC_SPECIAL,
167 196
168 - OPC_MOVCI = 0x01 | EXT_SPECIAL, 197 + OPC_MOVCI = 0x01 | OPC_SPECIAL,
169 198
170 /* Special */ 199 /* Special */
171 - OPC_PMON = 0x05 | EXT_SPECIAL,  
172 - OPC_SYSCALL = 0x0C | EXT_SPECIAL,  
173 - OPC_BREAK = 0x0D | EXT_SPECIAL,  
174 - OPC_SYNC = 0x0F | EXT_SPECIAL, 200 + OPC_PMON = 0x05 | OPC_SPECIAL, /* inofficial */
  201 + OPC_SYSCALL = 0x0C | OPC_SPECIAL,
  202 + OPC_BREAK = 0x0D | OPC_SPECIAL,
  203 + OPC_SPIM = 0x0E | OPC_SPECIAL, /* inofficial */
  204 + OPC_SYNC = 0x0F | OPC_SPECIAL,
  205 +
  206 + OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
  207 + OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
  208 + OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
  209 + OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
  210 + OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
  211 + OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
  212 + OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
  213 +};
  214 +
  215 +/* REGIMM (rt field) opcodes */
  216 +#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
  217 +
  218 +enum {
  219 + OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
  220 + OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
  221 + OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
  222 + OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
  223 + OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
  224 + OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
  225 + OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
  226 + OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
  227 + OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
  228 + OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
  229 + OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
  230 + OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
  231 + OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
  232 + OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
  233 + OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
175 }; 234 };
176 235
  236 +/* Special2 opcodes */
  237 +#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
  238 +
177 enum { 239 enum {
178 - /* Mutiply & xxx operations */  
179 - OPC_MADD = 0x00 | EXT_SPECIAL2,  
180 - OPC_MADDU = 0x01 | EXT_SPECIAL2,  
181 - OPC_MUL = 0x02 | EXT_SPECIAL2,  
182 - OPC_MSUB = 0x04 | EXT_SPECIAL2,  
183 - OPC_MSUBU = 0x05 | EXT_SPECIAL2, 240 + /* Multiply & xxx operations */
  241 + OPC_MADD = 0x00 | OPC_SPECIAL2,
  242 + OPC_MADDU = 0x01 | OPC_SPECIAL2,
  243 + OPC_MUL = 0x02 | OPC_SPECIAL2,
  244 + OPC_MSUB = 0x04 | OPC_SPECIAL2,
  245 + OPC_MSUBU = 0x05 | OPC_SPECIAL2,
184 /* Misc */ 246 /* Misc */
185 - OPC_CLZ = 0x20 | EXT_SPECIAL2,  
186 - OPC_CLO = 0x21 | EXT_SPECIAL2, 247 + OPC_CLZ = 0x20 | OPC_SPECIAL2,
  248 + OPC_CLO = 0x21 | OPC_SPECIAL2,
  249 + OPC_DCLZ = 0x24 | OPC_SPECIAL2,
  250 + OPC_DCLO = 0x25 | OPC_SPECIAL2,
187 /* Special */ 251 /* Special */
188 - OPC_SDBBP = 0x3F | EXT_SPECIAL2, 252 + OPC_SDBBP = 0x3F | OPC_SPECIAL2,
  253 +};
  254 +
  255 +/* Special3 opcodes */
  256 +#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
  257 +
  258 +enum {
  259 + OPC_EXT = 0x00 | OPC_SPECIAL3,
  260 + OPC_DEXTM = 0x01 | OPC_SPECIAL3,
  261 + OPC_DEXTU = 0x02 | OPC_SPECIAL3,
  262 + OPC_DEXT = 0x03 | OPC_SPECIAL3,
  263 + OPC_INS = 0x04 | OPC_SPECIAL3,
  264 + OPC_DINSM = 0x05 | OPC_SPECIAL3,
  265 + OPC_DINSU = 0x06 | OPC_SPECIAL3,
  266 + OPC_DINS = 0x07 | OPC_SPECIAL3,
  267 + OPC_BSHFL = 0x20 | OPC_SPECIAL3,
  268 + OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
  269 + OPC_RDHWR = 0x3B | OPC_SPECIAL3,
189 }; 270 };
190 271
191 -/* Branch REGIMM */ 272 +/* BSHFL opcodes */
  273 +#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
  274 +
192 enum { 275 enum {
193 - OPC_BLTZ = 0x00 | EXT_REGIMM,  
194 - OPC_BLTZL = 0x02 | EXT_REGIMM,  
195 - OPC_BGEZ = 0x01 | EXT_REGIMM,  
196 - OPC_BGEZL = 0x03 | EXT_REGIMM,  
197 - OPC_BLTZAL = 0x10 | EXT_REGIMM,  
198 - OPC_BLTZALL = 0x12 | EXT_REGIMM,  
199 - OPC_BGEZAL = 0x11 | EXT_REGIMM,  
200 - OPC_BGEZALL = 0x13 | EXT_REGIMM,  
201 - OPC_TGEI = 0x08 | EXT_REGIMM,  
202 - OPC_TGEIU = 0x09 | EXT_REGIMM,  
203 - OPC_TLTI = 0x0A | EXT_REGIMM,  
204 - OPC_TLTIU = 0x0B | EXT_REGIMM,  
205 - OPC_TEQI = 0x0C | EXT_REGIMM,  
206 - OPC_TNEI = 0x0E | EXT_REGIMM, 276 + OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
  277 + OPC_SEB = (0x10 << 6) | OPC_BSHFL,
  278 + OPC_SEH = (0x18 << 6) | OPC_BSHFL,
207 }; 279 };
208 280
  281 +/* DBSHFL opcodes */
  282 +#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
  283 +
209 enum { 284 enum {
210 - /* Coprocessor 0 (MMU) */  
211 - OPC_MFC0 = 0x00 | EXT_CP0,  
212 - OPC_MTC0 = 0x04 | EXT_CP0,  
213 - OPC_TLBR = 0x01 | EXT_CP0,  
214 - OPC_TLBWI = 0x02 | EXT_CP0,  
215 - OPC_TLBWR = 0x06 | EXT_CP0,  
216 - OPC_TLBP = 0x08 | EXT_CP0,  
217 - OPC_ERET = 0x18 | EXT_CP0,  
218 - OPC_DERET = 0x1F | EXT_CP0,  
219 - OPC_WAIT = 0x20 | EXT_CP0, 285 + OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
  286 + OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
220 }; 287 };
221 288
222 -#ifdef MIPS_USES_FPU 289 +/* Coprocessor 0 (rs field) */
  290 +#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
  291 +
223 enum { 292 enum {
224 - /* Coprocessor 1 (FPU) */  
225 - OPC_MFC1 = 0x00 | EXT_CP1,  
226 - OPC_MTC1 = 0x04 | EXT_CP1,  
227 - OPC_CFC1 = 0x02 | EXT_CP1,  
228 - OPC_CTC1 = 0x06 | EXT_CP1, 293 + OPC_MFC0 = (0x00 << 21) | OPC_CP0,
  294 + OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
  295 + OPC_MTC0 = (0x04 << 21) | OPC_CP0,
  296 + OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
  297 + OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
  298 + OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
  299 + OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
  300 + OPC_C0 = (0x10 << 21) | OPC_CP0,
  301 + OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
  302 + OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
229 }; 303 };
230 -#endif 304 +
  305 +/* MFMC0 opcodes */
  306 +#define MASK_MFMC0(op) MASK_CP0(op) | (op & ((0x0C << 11) | (1 << 5)))
  307 +
  308 +enum {
  309 + OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
  310 + OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
  311 +};
  312 +
  313 +/* Coprocessor 0 (with rs == C0) */
  314 +#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
  315 +
  316 +enum {
  317 + OPC_TLBR = 0x01 | OPC_C0,
  318 + OPC_TLBWI = 0x02 | OPC_C0,
  319 + OPC_TLBWR = 0x06 | OPC_C0,
  320 + OPC_TLBP = 0x08 | OPC_C0,
  321 + OPC_RFE = 0x10 | OPC_C0,
  322 + OPC_ERET = 0x18 | OPC_C0,
  323 + OPC_DERET = 0x1F | OPC_C0,
  324 + OPC_WAIT = 0x20 | OPC_C0,
  325 +};
  326 +
  327 +/* Coprocessor 1 (rs field) */
  328 +#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
  329 +
  330 +enum {
  331 + OPC_MFC1 = (0x00 << 21) | OPC_CP1,
  332 + OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
  333 + OPC_CFC1 = (0x02 << 21) | OPC_CP1,
  334 + OPC_MFHCI = (0x03 << 21) | OPC_CP1,
  335 + OPC_MTC1 = (0x04 << 21) | OPC_CP1,
  336 + OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
  337 + OPC_CTC1 = (0x06 << 21) | OPC_CP1,
  338 + OPC_MTHCI = (0x07 << 21) | OPC_CP1,
  339 + OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
  340 + OPC_S_FMT = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
  341 + OPC_D_FMT = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
  342 + OPC_E_FMT = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
  343 + OPC_Q_FMT = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
  344 + OPC_W_FMT = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
  345 + OPC_L_FMT = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
  346 +};
  347 +
  348 +enum {
  349 + OPC_BC1F = (0x00 << 16) | OPC_BC1,
  350 + OPC_BC1T = (0x01 << 16) | OPC_BC1,
  351 + OPC_BC1FL = (0x02 << 16) | OPC_BC1,
  352 + OPC_BC1TL = (0x03 << 16) | OPC_BC1,
  353 +};
  354 +
  355 +#define MASK_CP1_BCOND(op) MASK_CP1(op) | (op & ((0x1F << 21) | (0x3 << 16)))
  356 +#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & ((0x1F << 21) | 0x3F))
  357 +
  358 +#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
  359 +#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
231 360
232 const unsigned char *regnames[] = 361 const unsigned char *regnames[] =
233 { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3", 362 { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
@@ -260,8 +389,7 @@ GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr); @@ -260,8 +389,7 @@ GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
260 GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr); 389 GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
261 GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr); 390 GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
262 391
263 -#ifdef MIPS_USES_FPU  
264 -const unsigned char *fregnames[] = 392 +static const char *fregnames[] =
265 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", 393 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
266 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", 394 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
267 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", 395 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
@@ -344,8 +472,6 @@ static inline void gen_cmp_ ## fmt(int n) \ @@ -344,8 +472,6 @@ static inline void gen_cmp_ ## fmt(int n) \
344 FOP_CONDS(d) 472 FOP_CONDS(d)
345 FOP_CONDS(s) 473 FOP_CONDS(s)
346 474
347 -#endif  
348 -  
349 typedef struct DisasContext { 475 typedef struct DisasContext {
350 struct TranslationBlock *tb; 476 struct TranslationBlock *tb;
351 target_ulong pc, saved_pc; 477 target_ulong pc, saved_pc;
@@ -410,9 +536,7 @@ do { \ @@ -410,9 +536,7 @@ do { \
410 } \ 536 } \
411 } while (0) 537 } while (0)
412 538
413 -#ifdef MIPS_USES_FPU  
414 -  
415 -# define GEN_LOAD_FREG_FTN(FTn, Fn) \ 539 +#define GEN_LOAD_FREG_FTN(FTn, Fn) \
416 do { \ 540 do { \
417 glue(gen_op_load_fpr_, FTn)(Fn); \ 541 glue(gen_op_load_fpr_, FTn)(Fn); \
418 } while (0) 542 } while (0)
@@ -422,8 +546,6 @@ do { \ @@ -422,8 +546,6 @@ do { \
422 glue(gen_op_store_fpr_, FTn)(Fn); \ 546 glue(gen_op_store_fpr_, FTn)(Fn); \
423 } while (0) 547 } while (0)
424 548
425 -#endif  
426 -  
427 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc) 549 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
428 { 550 {
429 #if defined MIPS_DEBUG_DISAS 551 #if defined MIPS_DEBUG_DISAS
@@ -487,7 +609,7 @@ static GenOpFunc *gen_op_s##width[] = { \ @@ -487,7 +609,7 @@ static GenOpFunc *gen_op_s##width[] = { \
487 } 609 }
488 #endif 610 #endif
489 611
490 -#ifdef TARGET_MIPS64 612 +#ifdef MIPS_HAS_MIPS64
491 OP_LD_TABLE(d); 613 OP_LD_TABLE(d);
492 OP_LD_TABLE(dl); 614 OP_LD_TABLE(dl);
493 OP_LD_TABLE(dr); 615 OP_LD_TABLE(dr);
@@ -510,18 +632,16 @@ OP_LD_TABLE(bu); @@ -510,18 +632,16 @@ OP_LD_TABLE(bu);
510 OP_ST_TABLE(b); 632 OP_ST_TABLE(b);
511 OP_LD_TABLE(l); 633 OP_LD_TABLE(l);
512 OP_ST_TABLE(c); 634 OP_ST_TABLE(c);
513 -#ifdef MIPS_USES_FPU  
514 OP_LD_TABLE(wc1); 635 OP_LD_TABLE(wc1);
515 OP_ST_TABLE(wc1); 636 OP_ST_TABLE(wc1);
516 OP_LD_TABLE(dc1); 637 OP_LD_TABLE(dc1);
517 OP_ST_TABLE(dc1); 638 OP_ST_TABLE(dc1);
518 -#endif  
519 639
520 /* Load and store */ 640 /* Load and store */
521 -static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt, 641 +static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
522 int base, int16_t offset) 642 int base, int16_t offset)
523 { 643 {
524 - const unsigned char *opn = "unk"; 644 + const char *opn = "unk";
525 645
526 if (base == 0) { 646 if (base == 0) {
527 GEN_LOAD_IMM_TN(T0, offset); 647 GEN_LOAD_IMM_TN(T0, offset);
@@ -536,23 +656,27 @@ static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt, @@ -536,23 +656,27 @@ static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt,
536 * memory access 656 * memory access
537 */ 657 */
538 switch (opc) { 658 switch (opc) {
539 -#if defined(TARGET_MIPS64) 659 +#ifdef MIPS_HAS_MIPS64
540 case OPC_LD: 660 case OPC_LD:
541 -#if defined (MIPS_HAS_UNALIGNED_LS)  
542 - case OPC_ULD:  
543 -#endif  
544 op_ldst(ld); 661 op_ldst(ld);
545 GEN_STORE_TN_REG(rt, T0); 662 GEN_STORE_TN_REG(rt, T0);
546 opn = "ld"; 663 opn = "ld";
547 break; 664 break;
  665 + case OPC_LLD:
  666 + op_ldst(lld);
  667 + GEN_STORE_TN_REG(rt, T0);
  668 + opn = "lld";
  669 + break;
548 case OPC_SD: 670 case OPC_SD:
549 -#if defined (MIPS_HAS_UNALIGNED_LS)  
550 - case OPC_USD:  
551 -#endif  
552 GEN_LOAD_REG_TN(T1, rt); 671 GEN_LOAD_REG_TN(T1, rt);
553 op_ldst(sd); 672 op_ldst(sd);
554 opn = "sd"; 673 opn = "sd";
555 break; 674 break;
  675 + case OPC_SCD:
  676 + GEN_LOAD_REG_TN(T1, rt);
  677 + op_ldst(scd);
  678 + opn = "scd";
  679 + break;
556 case OPC_LDL: 680 case OPC_LDL:
557 op_ldst(ldl); 681 op_ldst(ldl);
558 GEN_STORE_TN_REG(rt, T0); 682 GEN_STORE_TN_REG(rt, T0);
@@ -575,9 +699,6 @@ static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt, @@ -575,9 +699,6 @@ static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt,
575 break; 699 break;
576 #endif 700 #endif
577 case OPC_LW: 701 case OPC_LW:
578 -#if defined (MIPS_HAS_UNALIGNED_LS)  
579 - case OPC_ULW:  
580 -#endif  
581 op_ldst(lw); 702 op_ldst(lw);
582 GEN_STORE_TN_REG(rt, T0); 703 GEN_STORE_TN_REG(rt, T0);
583 opn = "lw"; 704 opn = "lw";
@@ -588,33 +709,21 @@ static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt, @@ -588,33 +709,21 @@ static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt,
588 opn = "lwu"; 709 opn = "lwu";
589 break; 710 break;
590 case OPC_SW: 711 case OPC_SW:
591 -#if defined (MIPS_HAS_UNALIGNED_LS)  
592 - case OPC_USW:  
593 -#endif  
594 GEN_LOAD_REG_TN(T1, rt); 712 GEN_LOAD_REG_TN(T1, rt);
595 op_ldst(sw); 713 op_ldst(sw);
596 opn = "sw"; 714 opn = "sw";
597 break; 715 break;
598 case OPC_LH: 716 case OPC_LH:
599 -#if defined (MIPS_HAS_UNALIGNED_LS)  
600 - case OPC_ULH:  
601 -#endif  
602 op_ldst(lh); 717 op_ldst(lh);
603 GEN_STORE_TN_REG(rt, T0); 718 GEN_STORE_TN_REG(rt, T0);
604 opn = "lh"; 719 opn = "lh";
605 break; 720 break;
606 case OPC_SH: 721 case OPC_SH:
607 -#if defined (MIPS_HAS_UNALIGNED_LS)  
608 - case OPC_USH:  
609 -#endif  
610 GEN_LOAD_REG_TN(T1, rt); 722 GEN_LOAD_REG_TN(T1, rt);
611 op_ldst(sh); 723 op_ldst(sh);
612 opn = "sh"; 724 opn = "sh";
613 break; 725 break;
614 case OPC_LHU: 726 case OPC_LHU:
615 -#if defined (MIPS_HAS_UNALIGNED_LS)  
616 - case OPC_ULHU:  
617 -#endif  
618 op_ldst(lhu); 727 op_ldst(lhu);
619 GEN_STORE_TN_REG(rt, T0); 728 GEN_STORE_TN_REG(rt, T0);
620 opn = "lhu"; 729 opn = "lhu";
@@ -675,13 +784,11 @@ static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt, @@ -675,13 +784,11 @@ static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt,
675 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]); 784 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
676 } 785 }
677 786
678 -#ifdef MIPS_USES_FPU  
679 -  
680 /* Load and store */ 787 /* Load and store */
681 -static void gen_flt_ldst (DisasContext *ctx, uint16_t opc, int ft, 788 +static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
682 int base, int16_t offset) 789 int base, int16_t offset)
683 { 790 {
684 - const unsigned char *opn = "unk"; 791 + const char *opn = "unk";
685 792
686 if (base == 0) { 793 if (base == 0) {
687 GEN_LOAD_IMM_TN(T0, offset); 794 GEN_LOAD_IMM_TN(T0, offset);
@@ -718,21 +825,20 @@ static void gen_flt_ldst (DisasContext *ctx, uint16_t opc, int ft, @@ -718,21 +825,20 @@ static void gen_flt_ldst (DisasContext *ctx, uint16_t opc, int ft,
718 break; 825 break;
719 default: 826 default:
720 MIPS_INVAL("float load/store"); 827 MIPS_INVAL("float load/store");
721 - generate_exception(ctx, EXCP_CpU); 828 + generate_exception_err(ctx, EXCP_CpU, 1);
722 return; 829 return;
723 } 830 }
724 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]); 831 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
725 } 832 }
726 -#endif  
727 833
728 /* Arithmetic with immediate operand */ 834 /* Arithmetic with immediate operand */
729 -static void gen_arith_imm (DisasContext *ctx, uint16_t opc, int rt, 835 +static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
730 int rs, int16_t imm) 836 int rs, int16_t imm)
731 { 837 {
732 uint32_t uimm; 838 uint32_t uimm;
733 - const unsigned char *opn = "unk"; 839 + const char *opn = "unk";
734 840
735 - if (rt == 0 && opc != OPC_ADDI) { 841 + if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
736 /* if no destination, treat it as a NOP 842 /* if no destination, treat it as a NOP
737 * For addi, we must generate the overflow exception when needed. 843 * For addi, we must generate the overflow exception when needed.
738 */ 844 */
@@ -740,8 +846,9 @@ static void gen_arith_imm (DisasContext *ctx, uint16_t opc, int rt, @@ -740,8 +846,9 @@ static void gen_arith_imm (DisasContext *ctx, uint16_t opc, int rt,
740 return; 846 return;
741 } 847 }
742 if (opc == OPC_ADDI || opc == OPC_ADDIU || 848 if (opc == OPC_ADDI || opc == OPC_ADDIU ||
  849 + opc == OPC_DADDI || opc == OPC_DADDIU ||
743 opc == OPC_SLTI || opc == OPC_SLTIU) 850 opc == OPC_SLTI || opc == OPC_SLTIU)
744 - uimm = (int32_t)imm; /* Sign extent to 32 bits */ 851 + uimm = (int32_t)imm; /* Sign extend to 32 bits */
745 else 852 else
746 uimm = (uint16_t)imm; 853 uimm = (uint16_t)imm;
747 if (opc != OPC_LUI) { 854 if (opc != OPC_LUI) {
@@ -761,6 +868,17 @@ static void gen_arith_imm (DisasContext *ctx, uint16_t opc, int rt, @@ -761,6 +868,17 @@ static void gen_arith_imm (DisasContext *ctx, uint16_t opc, int rt,
761 gen_op_add(); 868 gen_op_add();
762 opn = "addiu"; 869 opn = "addiu";
763 break; 870 break;
  871 +#ifdef MIPS_HAS_MIPS64
  872 + case OPC_DADDI:
  873 + save_cpu_state(ctx, 1);
  874 + gen_op_daddo();
  875 + opn = "daddi";
  876 + break;
  877 + case OPC_DADDIU:
  878 + gen_op_dadd();
  879 + opn = "daddiu";
  880 + break;
  881 +#endif
764 case OPC_SLTI: 882 case OPC_SLTI:
765 gen_op_lt(); 883 gen_op_lt();
766 opn = "slti"; 884 opn = "slti";
@@ -793,9 +911,50 @@ static void gen_arith_imm (DisasContext *ctx, uint16_t opc, int rt, @@ -793,9 +911,50 @@ static void gen_arith_imm (DisasContext *ctx, uint16_t opc, int rt,
793 opn = "sra"; 911 opn = "sra";
794 break; 912 break;
795 case OPC_SRL: 913 case OPC_SRL:
796 - gen_op_srl();  
797 - opn = "srl"; 914 + if ((ctx->opcode >> 21) & 1) {
  915 + gen_op_rotr();
  916 + opn = "rotr";
  917 + } else {
  918 + gen_op_srl();
  919 + opn = "srl";
  920 + }
  921 + break;
  922 +#ifdef MIPS_HAS_MIPS64
  923 + case OPC_DSLL:
  924 + gen_op_dsll();
  925 + opn = "dsll";
  926 + break;
  927 + case OPC_DSRA:
  928 + gen_op_dsra();
  929 + opn = "dsra";
  930 + break;
  931 + case OPC_DSRL:
  932 + if ((ctx->opcode >> 21) & 1) {
  933 + gen_op_drotr();
  934 + opn = "drotr";
  935 + } else {
  936 + gen_op_dsrl();
  937 + opn = "dsrl";
  938 + }
  939 + break;
  940 + case OPC_DSLL32:
  941 + gen_op_dsll32();
  942 + opn = "dsll32";
  943 + break;
  944 + case OPC_DSRA32:
  945 + gen_op_dsra32();
  946 + opn = "dsra32";
  947 + break;
  948 + case OPC_DSRL32:
  949 + if ((ctx->opcode >> 21) & 1) {
  950 + gen_op_drotr32();
  951 + opn = "drotr32";
  952 + } else {
  953 + gen_op_dsrl32();
  954 + opn = "dsrl32";
  955 + }
798 break; 956 break;
  957 +#endif
799 default: 958 default:
800 MIPS_INVAL("imm arith"); 959 MIPS_INVAL("imm arith");
801 generate_exception(ctx, EXCP_RI); 960 generate_exception(ctx, EXCP_RI);
@@ -806,12 +965,13 @@ static void gen_arith_imm (DisasContext *ctx, uint16_t opc, int rt, @@ -806,12 +965,13 @@ static void gen_arith_imm (DisasContext *ctx, uint16_t opc, int rt,
806 } 965 }
807 966
808 /* Arithmetic */ 967 /* Arithmetic */
809 -static void gen_arith (DisasContext *ctx, uint16_t opc, 968 +static void gen_arith (DisasContext *ctx, uint32_t opc,
810 int rd, int rs, int rt) 969 int rd, int rs, int rt)
811 { 970 {
812 - const unsigned char *opn = "unk"; 971 + const char *opn = "unk";
813 972
814 - if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB) { 973 + if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
  974 + && opc != OPC_DADD && opc != OPC_DSUB) {
815 /* if no destination, treat it as a NOP 975 /* if no destination, treat it as a NOP
816 * For add & sub, we must generate the overflow exception when needed. 976 * For add & sub, we must generate the overflow exception when needed.
817 */ 977 */
@@ -839,6 +999,26 @@ static void gen_arith (DisasContext *ctx, uint16_t opc, @@ -839,6 +999,26 @@ static void gen_arith (DisasContext *ctx, uint16_t opc,
839 gen_op_sub(); 999 gen_op_sub();
840 opn = "subu"; 1000 opn = "subu";
841 break; 1001 break;
  1002 +#ifdef MIPS_HAS_MIPS64
  1003 + case OPC_DADD:
  1004 + save_cpu_state(ctx, 1);
  1005 + gen_op_daddo();
  1006 + opn = "dadd";
  1007 + break;
  1008 + case OPC_DADDU:
  1009 + gen_op_dadd();
  1010 + opn = "daddu";
  1011 + break;
  1012 + case OPC_DSUB:
  1013 + save_cpu_state(ctx, 1);
  1014 + gen_op_dsubo();
  1015 + opn = "dsub";
  1016 + break;
  1017 + case OPC_DSUBU:
  1018 + gen_op_dsub();
  1019 + opn = "dsubu";
  1020 + break;
  1021 +#endif
842 case OPC_SLT: 1022 case OPC_SLT:
843 gen_op_lt(); 1023 gen_op_lt();
844 opn = "slt"; 1024 opn = "slt";
@@ -884,9 +1064,33 @@ static void gen_arith (DisasContext *ctx, uint16_t opc, @@ -884,9 +1064,33 @@ static void gen_arith (DisasContext *ctx, uint16_t opc,
884 opn = "srav"; 1064 opn = "srav";
885 break; 1065 break;
886 case OPC_SRLV: 1066 case OPC_SRLV:
887 - gen_op_srlv();  
888 - opn = "srlv"; 1067 + if ((ctx->opcode >> 6) & 1) {
  1068 + gen_op_rotrv();
  1069 + opn = "rotrv";
  1070 + } else {
  1071 + gen_op_srlv();
  1072 + opn = "srlv";
  1073 + }
  1074 + break;
  1075 +#ifdef MIPS_HAS_MIPS64
  1076 + case OPC_DSLLV:
  1077 + gen_op_dsllv();
  1078 + opn = "dsllv";
  1079 + break;
  1080 + case OPC_DSRAV:
  1081 + gen_op_dsrav();
  1082 + opn = "dsrav";
  1083 + break;
  1084 + case OPC_DSRLV:
  1085 + if ((ctx->opcode >> 6) & 1) {
  1086 + gen_op_drotrv();
  1087 + opn = "drotrv";
  1088 + } else {
  1089 + gen_op_dsrlv();
  1090 + opn = "dsrlv";
  1091 + }
889 break; 1092 break;
  1093 +#endif
890 default: 1094 default:
891 MIPS_INVAL("arith"); 1095 MIPS_INVAL("arith");
892 generate_exception(ctx, EXCP_RI); 1096 generate_exception(ctx, EXCP_RI);
@@ -898,9 +1102,9 @@ static void gen_arith (DisasContext *ctx, uint16_t opc, @@ -898,9 +1102,9 @@ static void gen_arith (DisasContext *ctx, uint16_t opc,
898 } 1102 }
899 1103
900 /* Arithmetic on HI/LO registers */ 1104 /* Arithmetic on HI/LO registers */
901 -static void gen_HILO (DisasContext *ctx, uint16_t opc, int reg) 1105 +static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
902 { 1106 {
903 - const unsigned char *opn = "unk"; 1107 + const char *opn = "unk";
904 1108
905 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { 1109 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
906 /* Treat as a NOP */ 1110 /* Treat as a NOP */
@@ -936,10 +1140,10 @@ static void gen_HILO (DisasContext *ctx, uint16_t opc, int reg) @@ -936,10 +1140,10 @@ static void gen_HILO (DisasContext *ctx, uint16_t opc, int reg)
936 MIPS_DEBUG("%s %s", opn, regnames[reg]); 1140 MIPS_DEBUG("%s %s", opn, regnames[reg]);
937 } 1141 }
938 1142
939 -static void gen_muldiv (DisasContext *ctx, uint16_t opc, 1143 +static void gen_muldiv (DisasContext *ctx, uint32_t opc,
940 int rs, int rt) 1144 int rs, int rt)
941 { 1145 {
942 - const unsigned char *opn = "unk"; 1146 + const char *opn = "unk";
943 1147
944 GEN_LOAD_REG_TN(T0, rs); 1148 GEN_LOAD_REG_TN(T0, rs);
945 GEN_LOAD_REG_TN(T1, rt); 1149 GEN_LOAD_REG_TN(T1, rt);
@@ -960,6 +1164,24 @@ static void gen_muldiv (DisasContext *ctx, uint16_t opc, @@ -960,6 +1164,24 @@ static void gen_muldiv (DisasContext *ctx, uint16_t opc,
960 gen_op_multu(); 1164 gen_op_multu();
961 opn = "multu"; 1165 opn = "multu";
962 break; 1166 break;
  1167 +#ifdef MIPS_HAS_MIPS64
  1168 + case OPC_DDIV:
  1169 + gen_op_ddiv();
  1170 + opn = "ddiv";
  1171 + break;
  1172 + case OPC_DDIVU:
  1173 + gen_op_ddivu();
  1174 + opn = "ddivu";
  1175 + break;
  1176 + case OPC_DMULT:
  1177 + gen_op_dmult();
  1178 + opn = "dmult";
  1179 + break;
  1180 + case OPC_DMULTU:
  1181 + gen_op_dmultu();
  1182 + opn = "dmultu";
  1183 + break;
  1184 +#endif
963 case OPC_MADD: 1185 case OPC_MADD:
964 gen_op_madd(); 1186 gen_op_madd();
965 opn = "madd"; 1187 opn = "madd";
@@ -984,10 +1206,10 @@ static void gen_muldiv (DisasContext *ctx, uint16_t opc, @@ -984,10 +1206,10 @@ static void gen_muldiv (DisasContext *ctx, uint16_t opc,
984 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]); 1206 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
985 } 1207 }
986 1208
987 -static void gen_cl (DisasContext *ctx, uint16_t opc, 1209 +static void gen_cl (DisasContext *ctx, uint32_t opc,
988 int rd, int rs) 1210 int rd, int rs)
989 { 1211 {
990 - const unsigned char *opn = "unk"; 1212 + const char *opn = "unk";
991 if (rd == 0) { 1213 if (rd == 0) {
992 /* Treat as a NOP */ 1214 /* Treat as a NOP */
993 MIPS_DEBUG("NOP"); 1215 MIPS_DEBUG("NOP");
@@ -996,15 +1218,23 @@ static void gen_cl (DisasContext *ctx, uint16_t opc, @@ -996,15 +1218,23 @@ static void gen_cl (DisasContext *ctx, uint16_t opc,
996 GEN_LOAD_REG_TN(T0, rs); 1218 GEN_LOAD_REG_TN(T0, rs);
997 switch (opc) { 1219 switch (opc) {
998 case OPC_CLO: 1220 case OPC_CLO:
999 - /* CLO */  
1000 gen_op_clo(); 1221 gen_op_clo();
1001 opn = "clo"; 1222 opn = "clo";
1002 break; 1223 break;
1003 case OPC_CLZ: 1224 case OPC_CLZ:
1004 - /* CLZ */  
1005 gen_op_clz(); 1225 gen_op_clz();
1006 opn = "clz"; 1226 opn = "clz";
1007 break; 1227 break;
  1228 +#ifdef MIPS_HAS_MIPS64
  1229 + case OPC_DCLO:
  1230 + gen_op_dclo();
  1231 + opn = "dclo";
  1232 + break;
  1233 + case OPC_DCLZ:
  1234 + gen_op_dclz();
  1235 + opn = "dclz";
  1236 + break;
  1237 +#endif
1008 default: 1238 default:
1009 MIPS_INVAL("CLx"); 1239 MIPS_INVAL("CLx");
1010 generate_exception(ctx, EXCP_RI); 1240 generate_exception(ctx, EXCP_RI);
@@ -1015,7 +1245,7 @@ static void gen_cl (DisasContext *ctx, uint16_t opc, @@ -1015,7 +1245,7 @@ static void gen_cl (DisasContext *ctx, uint16_t opc,
1015 } 1245 }
1016 1246
1017 /* Traps */ 1247 /* Traps */
1018 -static void gen_trap (DisasContext *ctx, uint16_t opc, 1248 +static void gen_trap (DisasContext *ctx, uint32_t opc,
1019 int rs, int rt, int16_t imm) 1249 int rs, int rt, int16_t imm)
1020 { 1250 {
1021 int cond; 1251 int cond;
@@ -1130,7 +1360,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) @@ -1130,7 +1360,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1130 } 1360 }
1131 1361
1132 /* Branches (before delay slot) */ 1362 /* Branches (before delay slot) */
1133 -static void gen_compute_branch (DisasContext *ctx, uint16_t opc, 1363 +static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1134 int rs, int rt, int32_t offset) 1364 int rs, int rt, int32_t offset)
1135 { 1365 {
1136 target_ulong btarget; 1366 target_ulong btarget;
@@ -1180,8 +1410,9 @@ static void gen_compute_branch (DisasContext *ctx, uint16_t opc, @@ -1180,8 +1410,9 @@ static void gen_compute_branch (DisasContext *ctx, uint16_t opc,
1180 case OPC_JR: 1410 case OPC_JR:
1181 case OPC_JALR: 1411 case OPC_JALR:
1182 /* Jump to register */ 1412 /* Jump to register */
1183 - if (offset != 0) {  
1184 - /* Only hint = 0 is valid */ 1413 + if (offset != 0 && offset != 16) {
  1414 + /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
  1415 + others are reserved. */
1185 generate_exception(ctx, EXCP_RI); 1416 generate_exception(ctx, EXCP_RI);
1186 return; 1417 return;
1187 } 1418 }
@@ -1348,80 +1579,342 @@ static void gen_compute_branch (DisasContext *ctx, uint16_t opc, @@ -1348,80 +1579,342 @@ static void gen_compute_branch (DisasContext *ctx, uint16_t opc,
1348 return; 1579 return;
1349 } 1580 }
1350 1581
  1582 +/* special3 bitfield operations */
  1583 +static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
  1584 + int rs, int lsb, int msb)
  1585 +{
  1586 + GEN_LOAD_REG_TN(T1, rs);
  1587 + switch (opc) {
  1588 + case OPC_EXT:
  1589 + if (lsb + msb > 31)
  1590 + goto fail;
  1591 + gen_op_ext(lsb, msb + 1);
  1592 + break;
  1593 + case OPC_DEXTM:
  1594 + if (lsb + msb > 63)
  1595 + goto fail;
  1596 + gen_op_ext(lsb, msb + 1 + 32);
  1597 + break;
  1598 + case OPC_DEXTU:
  1599 + if (lsb + msb > 63)
  1600 + goto fail;
  1601 + gen_op_ext(lsb + 32, msb + 1);
  1602 + break;
  1603 + case OPC_DEXT:
  1604 + gen_op_ext(lsb, msb + 1);
  1605 + break;
  1606 + case OPC_INS:
  1607 + if (lsb > msb)
  1608 + goto fail;
  1609 + GEN_LOAD_REG_TN(T2, rt);
  1610 + gen_op_ins(lsb, msb - lsb + 1);
  1611 + break;
  1612 + case OPC_DINSM:
  1613 + if (lsb > msb)
  1614 + goto fail;
  1615 + GEN_LOAD_REG_TN(T2, rt);
  1616 + gen_op_ins(lsb, msb - lsb + 1 + 32);
  1617 + break;
  1618 + case OPC_DINSU:
  1619 + if (lsb > msb)
  1620 + goto fail;
  1621 + GEN_LOAD_REG_TN(T2, rt);
  1622 + gen_op_ins(lsb + 32, msb - lsb + 1);
  1623 + break;
  1624 + case OPC_DINS:
  1625 + if (lsb > msb)
  1626 + goto fail;
  1627 + GEN_LOAD_REG_TN(T2, rt);
  1628 + gen_op_ins(lsb, msb - lsb + 1);
  1629 + break;
  1630 + default:
  1631 +fail:
  1632 + MIPS_INVAL("bitops");
  1633 + generate_exception(ctx, EXCP_RI);
  1634 + return;
  1635 + }
  1636 + GEN_STORE_TN_REG(rt, T0);
  1637 +}
  1638 +
1351 /* CP0 (MMU and control) */ 1639 /* CP0 (MMU and control) */
1352 static void gen_mfc0 (DisasContext *ctx, int reg, int sel) 1640 static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1353 { 1641 {
1354 - const unsigned char *rn; 1642 + const char *rn = "invalid";
1355 1643
1356 - if (sel != 0 && reg != 16 && reg != 28) {  
1357 - rn = "invalid";  
1358 - goto die;  
1359 - }  
1360 switch (reg) { 1644 switch (reg) {
1361 case 0: 1645 case 0:
1362 - gen_op_mfc0_index();  
1363 - rn = "Index"; 1646 + switch (sel) {
  1647 + case 0:
  1648 + gen_op_mfc0_index();
  1649 + rn = "Index";
  1650 + break;
  1651 + case 1:
  1652 +// gen_op_mfc0_mvpcontrol(); /* MT ASE */
  1653 + rn = "MVPControl";
  1654 +// break;
  1655 + case 2:
  1656 +// gen_op_mfc0_mvpconf0(); /* MT ASE */
  1657 + rn = "MVPConf0";
  1658 +// break;
  1659 + case 3:
  1660 +// gen_op_mfc0_mvpconf1(); /* MT ASE */
  1661 + rn = "MVPConf1";
  1662 +// break;
  1663 + default:
  1664 + goto die;
  1665 + }
1364 break; 1666 break;
1365 case 1: 1667 case 1:
1366 - gen_op_mfc0_random();  
1367 - rn = "Random"; 1668 + switch (sel) {
  1669 + case 0:
  1670 + gen_op_mfc0_random();
  1671 + rn = "Random";
  1672 + break;
  1673 + case 1:
  1674 +// gen_op_mfc0_vpecontrol(); /* MT ASE */
  1675 + rn = "VPEControl";
  1676 +// break;
  1677 + case 2:
  1678 +// gen_op_mfc0_vpeconf0(); /* MT ASE */
  1679 + rn = "VPEConf0";
  1680 +// break;
  1681 + case 3:
  1682 +// gen_op_mfc0_vpeconf1(); /* MT ASE */
  1683 + rn = "VPEConf1";
  1684 +// break;
  1685 + case 4:
  1686 +// gen_op_mfc0_YQMask(); /* MT ASE */
  1687 + rn = "YQMask";
  1688 +// break;
  1689 + case 5:
  1690 +// gen_op_mfc0_vpeschedule(); /* MT ASE */
  1691 + rn = "VPESchedule";
  1692 +// break;
  1693 + case 6:
  1694 +// gen_op_mfc0_vpeschefback(); /* MT ASE */
  1695 + rn = "VPEScheFBack";
  1696 +// break;
  1697 + case 7:
  1698 +// gen_op_mfc0_vpeopt(); /* MT ASE */
  1699 + rn = "VPEOpt";
  1700 +// break;
  1701 + default:
  1702 + goto die;
  1703 + }
1368 break; 1704 break;
1369 case 2: 1705 case 2:
1370 - gen_op_mfc0_entrylo0();  
1371 - rn = "EntryLo0"; 1706 + switch (sel) {
  1707 + case 0:
  1708 + gen_op_mfc0_entrylo0();
  1709 + rn = "EntryLo0";
  1710 + break;
  1711 + case 1:
  1712 +// gen_op_mfc0_tcstatus(); /* MT ASE */
  1713 + rn = "TCStatus";
  1714 +// break;
  1715 + case 2:
  1716 +// gen_op_mfc0_tcbind(); /* MT ASE */
  1717 + rn = "TCBind";
  1718 +// break;
  1719 + case 3:
  1720 +// gen_op_mfc0_tcrestart(); /* MT ASE */
  1721 + rn = "TCRestart";
  1722 +// break;
  1723 + case 4:
  1724 +// gen_op_mfc0_tchalt(); /* MT ASE */
  1725 + rn = "TCHalt";
  1726 +// break;
  1727 + case 5:
  1728 +// gen_op_mfc0_tccontext(); /* MT ASE */
  1729 + rn = "TCContext";
  1730 +// break;
  1731 + case 6:
  1732 +// gen_op_mfc0_tcschedule(); /* MT ASE */
  1733 + rn = "TCSchedule";
  1734 +// break;
  1735 + case 7:
  1736 +// gen_op_mfc0_tcschefback(); /* MT ASE */
  1737 + rn = "TCScheFBack";
  1738 +// break;
  1739 + default:
  1740 + goto die;
  1741 + }
1372 break; 1742 break;
1373 case 3: 1743 case 3:
1374 - /* also CONF */  
1375 - gen_op_mfc0_entrylo1();  
1376 - rn = "EntryLo1"; 1744 + switch (sel) {
  1745 + case 0:
  1746 + gen_op_mfc0_entrylo1();
  1747 + rn = "EntryLo1";
  1748 + break;
  1749 + default:
  1750 + goto die;
  1751 + }
1377 break; 1752 break;
1378 case 4: 1753 case 4:
1379 - gen_op_mfc0_context();  
1380 - rn = "Context"; 1754 + switch (sel) {
  1755 + case 0:
  1756 + gen_op_mfc0_context();
  1757 + rn = "Context";
  1758 + break;
  1759 + case 1:
  1760 +// gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
  1761 + rn = "ContextConfig";
  1762 +// break;
  1763 + default:
  1764 + goto die;
  1765 + }
1381 break; 1766 break;
1382 case 5: 1767 case 5:
1383 - gen_op_mfc0_pagemask();  
1384 - rn = "PageMask"; 1768 + switch (sel) {
  1769 + case 0:
  1770 + gen_op_mfc0_pagemask();
  1771 + rn = "PageMask";
  1772 + break;
  1773 + case 1:
  1774 + gen_op_mfc0_pagegrain();
  1775 + rn = "PageGrain";
  1776 + break;
  1777 + default:
  1778 + goto die;
  1779 + }
1385 break; 1780 break;
1386 case 6: 1781 case 6:
1387 - gen_op_mfc0_wired();  
1388 - rn = "Wired"; 1782 + switch (sel) {
  1783 + case 0:
  1784 + gen_op_mfc0_wired();
  1785 + rn = "Wired";
  1786 + break;
  1787 + case 1:
  1788 +// gen_op_mfc0_srsconf0(); /* shadow registers */
  1789 + rn = "SRSConf0";
  1790 +// break;
  1791 + case 2:
  1792 +// gen_op_mfc0_srsconf1(); /* shadow registers */
  1793 + rn = "SRSConf1";
  1794 +// break;
  1795 + case 3:
  1796 +// gen_op_mfc0_srsconf2(); /* shadow registers */
  1797 + rn = "SRSConf2";
  1798 +// break;
  1799 + case 4:
  1800 +// gen_op_mfc0_srsconf3(); /* shadow registers */
  1801 + rn = "SRSConf3";
  1802 +// break;
  1803 + case 5:
  1804 +// gen_op_mfc0_srsconf4(); /* shadow registers */
  1805 + rn = "SRSConf4";
  1806 +// break;
  1807 + default:
  1808 + goto die;
  1809 + }
1389 break; 1810 break;
1390 case 7: 1811 case 7:
1391 -// gen_op_mfc0_info();  
1392 - rn = "Info"; 1812 + switch (sel) {
  1813 + case 0:
  1814 + gen_op_mfc0_hwrena();
  1815 + rn = "HWREna";
  1816 + break;
  1817 + default:
  1818 + goto die;
  1819 + }
1393 break; 1820 break;
1394 case 8: 1821 case 8:
1395 - gen_op_mfc0_badvaddr();  
1396 - rn = "BadVaddr"; 1822 + switch (sel) {
  1823 + case 0:
  1824 + gen_op_mfc0_badvaddr();
  1825 + rn = "BadVaddr";
  1826 + break;
  1827 + default:
  1828 + goto die;
  1829 + }
1397 break; 1830 break;
1398 case 9: 1831 case 9:
1399 - gen_op_mfc0_count();  
1400 - rn = "Count"; 1832 + switch (sel) {
  1833 + case 0:
  1834 + gen_op_mfc0_count();
  1835 + rn = "Count";
  1836 + break;
  1837 + /* 6,7 are implementation dependent */
  1838 + default:
  1839 + goto die;
  1840 + }
1401 break; 1841 break;
1402 case 10: 1842 case 10:
1403 - gen_op_mfc0_entryhi();  
1404 - rn = "EntryHi"; 1843 + switch (sel) {
  1844 + case 0:
  1845 + gen_op_mfc0_entryhi();
  1846 + rn = "EntryHi";
  1847 + break;
  1848 + default:
  1849 + goto die;
  1850 + }
1405 break; 1851 break;
1406 case 11: 1852 case 11:
1407 - gen_op_mfc0_compare();  
1408 - rn = "Compare"; 1853 + switch (sel) {
  1854 + case 0:
  1855 + gen_op_mfc0_compare();
  1856 + rn = "Compare";
  1857 + break;
  1858 + /* 6,7 are implementation dependent */
  1859 + default:
  1860 + goto die;
  1861 + }
1409 break; 1862 break;
1410 case 12: 1863 case 12:
1411 - gen_op_mfc0_status();  
1412 - rn = "Status"; 1864 + switch (sel) {
  1865 + case 0:
  1866 + gen_op_mfc0_status();
  1867 + rn = "Status";
  1868 + break;
  1869 + case 1:
  1870 + gen_op_mfc0_intctl();
  1871 + rn = "IntCtl";
  1872 + break;
  1873 + case 2:
  1874 + gen_op_mfc0_srsctl();
  1875 + rn = "SRSCtl";
  1876 + break;
  1877 + case 3:
  1878 +// gen_op_mfc0_srsmap(); /* shadow registers */
  1879 + rn = "SRSMap";
  1880 +// break;
  1881 + default:
  1882 + goto die;
  1883 + }
1413 break; 1884 break;
1414 case 13: 1885 case 13:
1415 - gen_op_mfc0_cause();  
1416 - rn = "Cause"; 1886 + switch (sel) {
  1887 + case 0:
  1888 + gen_op_mfc0_cause();
  1889 + rn = "Cause";
  1890 + break;
  1891 + default:
  1892 + goto die;
  1893 + }
1417 break; 1894 break;
1418 case 14: 1895 case 14:
1419 - gen_op_mfc0_epc();  
1420 - rn = "EPC"; 1896 + switch (sel) {
  1897 + case 0:
  1898 + gen_op_mfc0_epc();
  1899 + rn = "EPC";
  1900 + break;
  1901 + default:
  1902 + goto die;
  1903 + }
1421 break; 1904 break;
1422 case 15: 1905 case 15:
1423 - gen_op_mfc0_prid();  
1424 - rn = "PRid"; 1906 + switch (sel) {
  1907 + case 0:
  1908 + gen_op_mfc0_prid();
  1909 + rn = "PRid";
  1910 + break;
  1911 + case 1:
  1912 + gen_op_mfc0_ebase();
  1913 + rn = "EBase";
  1914 + break;
  1915 + default:
  1916 + goto die;
  1917 + }
1425 break; 1918 break;
1426 case 16: 1919 case 16:
1427 switch (sel) { 1920 switch (sel) {
@@ -1433,91 +1926,285 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) @@ -1433,91 +1926,285 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1433 gen_op_mfc0_config1(); 1926 gen_op_mfc0_config1();
1434 rn = "Config1"; 1927 rn = "Config1";
1435 break; 1928 break;
  1929 + case 2:
  1930 + gen_op_mfc0_config2();
  1931 + rn = "Config2";
  1932 + break;
  1933 + case 3:
  1934 + gen_op_mfc0_config3();
  1935 + rn = "Config3";
  1936 + break;
  1937 + /* 6,7 are implementation dependent */
1436 default: 1938 default:
1437 - rn = "Unknown config register";  
1438 goto die; 1939 goto die;
1439 } 1940 }
1440 break; 1941 break;
1441 case 17: 1942 case 17:
1442 - gen_op_mfc0_lladdr();  
1443 - rn = "LLAddr"; 1943 + switch (sel) {
  1944 + case 0:
  1945 + gen_op_mfc0_lladdr();
  1946 + rn = "LLAddr";
  1947 + break;
  1948 + default:
  1949 + goto die;
  1950 + }
1444 break; 1951 break;
1445 case 18: 1952 case 18:
1446 - gen_op_mfc0_watchlo();  
1447 - rn = "WatchLo"; 1953 + switch (sel) {
  1954 + case 0:
  1955 + gen_op_mfc0_watchlo0();
  1956 + rn = "WatchLo";
  1957 + break;
  1958 + case 1:
  1959 +// gen_op_mfc0_watchlo1();
  1960 + rn = "WatchLo1";
  1961 +// break;
  1962 + case 2:
  1963 +// gen_op_mfc0_watchlo2();
  1964 + rn = "WatchLo2";
  1965 +// break;
  1966 + case 3:
  1967 +// gen_op_mfc0_watchlo3();
  1968 + rn = "WatchLo3";
  1969 +// break;
  1970 + case 4:
  1971 +// gen_op_mfc0_watchlo4();
  1972 + rn = "WatchLo4";
  1973 +// break;
  1974 + case 5:
  1975 +// gen_op_mfc0_watchlo5();
  1976 + rn = "WatchLo5";
  1977 +// break;
  1978 + case 6:
  1979 +// gen_op_mfc0_watchlo6();
  1980 + rn = "WatchLo6";
  1981 +// break;
  1982 + case 7:
  1983 +// gen_op_mfc0_watchlo7();
  1984 + rn = "WatchLo7";
  1985 +// break;
  1986 + default:
  1987 + goto die;
  1988 + }
1448 break; 1989 break;
1449 case 19: 1990 case 19:
1450 - gen_op_mfc0_watchhi();  
1451 - rn = "WatchHi"; 1991 + switch (sel) {
  1992 + case 0:
  1993 + gen_op_mfc0_watchhi0();
  1994 + rn = "WatchHi";
  1995 + break;
  1996 + case 1:
  1997 +// gen_op_mfc0_watchhi1();
  1998 + rn = "WatchHi1";
  1999 +// break;
  2000 + case 2:
  2001 +// gen_op_mfc0_watchhi2();
  2002 + rn = "WatchHi2";
  2003 +// break;
  2004 + case 3:
  2005 +// gen_op_mfc0_watchhi3();
  2006 + rn = "WatchHi3";
  2007 +// break;
  2008 + case 4:
  2009 +// gen_op_mfc0_watchhi4();
  2010 + rn = "WatchHi4";
  2011 +// break;
  2012 + case 5:
  2013 +// gen_op_mfc0_watchhi5();
  2014 + rn = "WatchHi5";
  2015 +// break;
  2016 + case 6:
  2017 +// gen_op_mfc0_watchhi6();
  2018 + rn = "WatchHi6";
  2019 +// break;
  2020 + case 7:
  2021 +// gen_op_mfc0_watchhi7();
  2022 + rn = "WatchHi7";
  2023 +// break;
  2024 + default:
  2025 + goto die;
  2026 + }
1452 break; 2027 break;
1453 case 20: 2028 case 20:
1454 - /* 64 bit only */  
1455 -// gen_op_mfc0_xcontext();  
1456 - rn = "XContext"; 2029 + switch (sel) {
  2030 + case 0:
  2031 + /* 64 bit MMU only */
  2032 + gen_op_mfc0_xcontext();
  2033 + rn = "XContext";
  2034 + break;
  2035 + default:
  2036 + goto die;
  2037 + }
1457 break; 2038 break;
1458 case 21: 2039 case 21:
1459 -// gen_op_mfc0_framemask();  
1460 - rn = "Framemask"; 2040 + /* Officially reserved, but sel 0 is used for R1x000 framemask */
  2041 + switch (sel) {
  2042 + case 0:
  2043 + gen_op_mfc0_framemask();
  2044 + rn = "Framemask";
  2045 + break;
  2046 + default:
  2047 + goto die;
  2048 + }
1461 break; 2049 break;
1462 case 22: 2050 case 22:
1463 -// gen_op_mfc0_diagnostic();  
1464 - rn = "'Diagnostic";  
1465 - break; 2051 + /* ignored */
  2052 + rn = "'Diagnostic"; /* implementation dependent */
  2053 + break;
1466 case 23: 2054 case 23:
1467 - gen_op_mfc0_debug();  
1468 - rn = "Debug"; 2055 + switch (sel) {
  2056 + case 0:
  2057 + gen_op_mfc0_debug(); /* EJTAG support */
  2058 + rn = "Debug";
  2059 + break;
  2060 + case 1:
  2061 +// gen_op_mfc0_tracecontrol(); /* PDtrace support */
  2062 + rn = "TraceControl";
  2063 +// break;
  2064 + case 2:
  2065 +// gen_op_mfc0_tracecontrol2(); /* PDtrace support */
  2066 + rn = "TraceControl2";
  2067 +// break;
  2068 + case 3:
  2069 +// gen_op_mfc0_usertracedata(); /* PDtrace support */
  2070 + rn = "UserTraceData";
  2071 +// break;
  2072 + case 4:
  2073 +// gen_op_mfc0_debug(); /* PDtrace support */
  2074 + rn = "TraceBPC";
  2075 +// break;
  2076 + default:
  2077 + goto die;
  2078 + }
1469 break; 2079 break;
1470 case 24: 2080 case 24:
1471 - gen_op_mfc0_depc();  
1472 - rn = "DEPC"; 2081 + switch (sel) {
  2082 + case 0:
  2083 + gen_op_mfc0_depc(); /* EJTAG support */
  2084 + rn = "DEPC";
  2085 + break;
  2086 + default:
  2087 + goto die;
  2088 + }
1473 break; 2089 break;
1474 case 25: 2090 case 25:
1475 -// gen_op_mfc0_performance();  
1476 - rn = "Performance"; 2091 + switch (sel) {
  2092 + case 0:
  2093 + gen_op_mfc0_performance0();
  2094 + rn = "Performance0";
  2095 + break;
  2096 + case 1:
  2097 +// gen_op_mfc0_performance1();
  2098 + rn = "Performance1";
  2099 +// break;
  2100 + case 2:
  2101 +// gen_op_mfc0_performance2();
  2102 + rn = "Performance2";
  2103 +// break;
  2104 + case 3:
  2105 +// gen_op_mfc0_performance3();
  2106 + rn = "Performance3";
  2107 +// break;
  2108 + case 4:
  2109 +// gen_op_mfc0_performance4();
  2110 + rn = "Performance4";
  2111 +// break;
  2112 + case 5:
  2113 +// gen_op_mfc0_performance5();
  2114 + rn = "Performance5";
  2115 +// break;
  2116 + case 6:
  2117 +// gen_op_mfc0_performance6();
  2118 + rn = "Performance6";
  2119 +// break;
  2120 + case 7:
  2121 +// gen_op_mfc0_performance7();
  2122 + rn = "Performance7";
  2123 +// break;
  2124 + default:
  2125 + goto die;
  2126 + }
1477 break; 2127 break;
1478 case 26: 2128 case 26:
1479 -// gen_op_mfc0_ecc();  
1480 - rn = "ECC";  
1481 - break; 2129 + rn = "ECC";
  2130 + break;
1482 case 27: 2131 case 27:
1483 -// gen_op_mfc0_cacheerr();  
1484 - rn = "CacheErr"; 2132 + switch (sel) {
  2133 + /* ignored */
  2134 + case 0 ... 3:
  2135 + rn = "CacheErr";
  2136 + break;
  2137 + default:
  2138 + goto die;
  2139 + }
1485 break; 2140 break;
1486 case 28: 2141 case 28:
1487 switch (sel) { 2142 switch (sel) {
1488 case 0: 2143 case 0:
  2144 + case 2:
  2145 + case 4:
  2146 + case 6:
1489 gen_op_mfc0_taglo(); 2147 gen_op_mfc0_taglo();
1490 rn = "TagLo"; 2148 rn = "TagLo";
1491 break; 2149 break;
1492 case 1: 2150 case 1:
  2151 + case 3:
  2152 + case 5:
  2153 + case 7:
1493 gen_op_mfc0_datalo(); 2154 gen_op_mfc0_datalo();
1494 rn = "DataLo"; 2155 rn = "DataLo";
1495 break; 2156 break;
1496 default: 2157 default:
1497 - rn = "unknown sel";  
1498 goto die; 2158 goto die;
1499 } 2159 }
1500 break; 2160 break;
1501 case 29: 2161 case 29:
1502 -// gen_op_mfc0_taghi();  
1503 - rn = "TagHi"; 2162 + switch (sel) {
  2163 + case 0:
  2164 + case 2:
  2165 + case 4:
  2166 + case 6:
  2167 + gen_op_mfc0_taghi();
  2168 + rn = "TagHi";
  2169 + break;
  2170 + case 1:
  2171 + case 3:
  2172 + case 5:
  2173 + case 7:
  2174 + gen_op_mfc0_datahi();
  2175 + rn = "DataHi";
  2176 + break;
  2177 + default:
  2178 + goto die;
  2179 + }
1504 break; 2180 break;
1505 case 30: 2181 case 30:
1506 - gen_op_mfc0_errorepc();  
1507 - rn = "ErrorEPC"; 2182 + switch (sel) {
  2183 + case 0:
  2184 + gen_op_mfc0_errorepc();
  2185 + rn = "ErrorEPC";
  2186 + break;
  2187 + default:
  2188 + goto die;
  2189 + }
1508 break; 2190 break;
1509 case 31: 2191 case 31:
1510 - gen_op_mfc0_desave();  
1511 - rn = "DESAVE"; 2192 + switch (sel) {
  2193 + case 0:
  2194 + gen_op_mfc0_desave(); /* EJTAG support */
  2195 + rn = "DESAVE";
  2196 + break;
  2197 + default:
  2198 + goto die;
  2199 + }
1512 break; 2200 break;
1513 default: 2201 default:
1514 - rn = "unknown";  
1515 goto die; 2202 goto die;
1516 } 2203 }
1517 #if defined MIPS_DEBUG_DISAS 2204 #if defined MIPS_DEBUG_DISAS
1518 if (loglevel & CPU_LOG_TB_IN_ASM) { 2205 if (loglevel & CPU_LOG_TB_IN_ASM) {
1519 - fprintf(logfile, "%08x mfc0 %s => %08x (%d %d)\n",  
1520 - env->PC, rn, T0, reg, sel); 2206 + fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
  2207 + rn, reg, sel);
1521 } 2208 }
1522 #endif 2209 #endif
1523 return; 2210 return;
@@ -1525,8 +2212,8 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) @@ -1525,8 +2212,8 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1525 die: 2212 die:
1526 #if defined MIPS_DEBUG_DISAS 2213 #if defined MIPS_DEBUG_DISAS
1527 if (loglevel & CPU_LOG_TB_IN_ASM) { 2214 if (loglevel & CPU_LOG_TB_IN_ASM) {
1528 - fprintf(logfile, "%08x mfc0 %s => %08x (%d %d)\n",  
1529 - env->PC, rn, T0, reg, sel); 2215 + fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
  2216 + rn, reg, sel);
1530 } 2217 }
1531 #endif 2218 #endif
1532 generate_exception(ctx, EXCP_RI); 2219 generate_exception(ctx, EXCP_RI);
@@ -1534,167 +2221,583 @@ die: @@ -1534,167 +2221,583 @@ die:
1534 2221
1535 static void gen_mtc0 (DisasContext *ctx, int reg, int sel) 2222 static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
1536 { 2223 {
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 - } 2224 + const char *rn = "invalid";
  2225 +
1546 switch (reg) { 2226 switch (reg) {
1547 case 0: 2227 case 0:
1548 - gen_op_mtc0_index();  
1549 - rn = "Index"; 2228 + switch (sel) {
  2229 + case 0:
  2230 + gen_op_mtc0_index();
  2231 + rn = "Index";
  2232 + break;
  2233 + case 1:
  2234 +// gen_op_mtc0_mvpcontrol(); /* MT ASE */
  2235 + rn = "MVPControl";
  2236 +// break;
  2237 + case 2:
  2238 +// gen_op_mtc0_mvpconf0(); /* MT ASE */
  2239 + rn = "MVPConf0";
  2240 +// break;
  2241 + case 3:
  2242 +// gen_op_mtc0_mvpconf1(); /* MT ASE */
  2243 + rn = "MVPConf1";
  2244 +// break;
  2245 + default:
  2246 + goto die;
  2247 + }
1550 break; 2248 break;
1551 case 1: 2249 case 1:
1552 -// ignore or except?  
1553 - rn = "Random"; 2250 + switch (sel) {
  2251 + case 0:
  2252 + /* ignored */
  2253 + rn = "Random";
  2254 + break;
  2255 + case 1:
  2256 +// gen_op_mtc0_vpecontrol(); /* MT ASE */
  2257 + rn = "VPEControl";
  2258 +// break;
  2259 + case 2:
  2260 +// gen_op_mtc0_vpeconf0(); /* MT ASE */
  2261 + rn = "VPEConf0";
  2262 +// break;
  2263 + case 3:
  2264 +// gen_op_mtc0_vpeconf1(); /* MT ASE */
  2265 + rn = "VPEConf1";
  2266 +// break;
  2267 + case 4:
  2268 +// gen_op_mtc0_YQMask(); /* MT ASE */
  2269 + rn = "YQMask";
  2270 +// break;
  2271 + case 5:
  2272 +// gen_op_mtc0_vpeschedule(); /* MT ASE */
  2273 + rn = "VPESchedule";
  2274 +// break;
  2275 + case 6:
  2276 +// gen_op_mtc0_vpeschefback(); /* MT ASE */
  2277 + rn = "VPEScheFBack";
  2278 +// break;
  2279 + case 7:
  2280 +// gen_op_mtc0_vpeopt(); /* MT ASE */
  2281 + rn = "VPEOpt";
  2282 +// break;
  2283 + default:
  2284 + goto die;
  2285 + }
1554 break; 2286 break;
1555 case 2: 2287 case 2:
1556 - gen_op_mtc0_entrylo0();  
1557 - rn = "EntryLo0"; 2288 + switch (sel) {
  2289 + case 0:
  2290 + gen_op_mtc0_entrylo0();
  2291 + rn = "EntryLo0";
  2292 + break;
  2293 + case 1:
  2294 +// gen_op_mtc0_tcstatus(); /* MT ASE */
  2295 + rn = "TCStatus";
  2296 +// break;
  2297 + case 2:
  2298 +// gen_op_mtc0_tcbind(); /* MT ASE */
  2299 + rn = "TCBind";
  2300 +// break;
  2301 + case 3:
  2302 +// gen_op_mtc0_tcrestart(); /* MT ASE */
  2303 + rn = "TCRestart";
  2304 +// break;
  2305 + case 4:
  2306 +// gen_op_mtc0_tchalt(); /* MT ASE */
  2307 + rn = "TCHalt";
  2308 +// break;
  2309 + case 5:
  2310 +// gen_op_mtc0_tccontext(); /* MT ASE */
  2311 + rn = "TCContext";
  2312 +// break;
  2313 + case 6:
  2314 +// gen_op_mtc0_tcschedule(); /* MT ASE */
  2315 + rn = "TCSchedule";
  2316 +// break;
  2317 + case 7:
  2318 +// gen_op_mtc0_tcschefback(); /* MT ASE */
  2319 + rn = "TCScheFBack";
  2320 +// break;
  2321 + default:
  2322 + goto die;
  2323 + }
1558 break; 2324 break;
1559 case 3: 2325 case 3:
1560 - gen_op_mtc0_entrylo1();  
1561 - rn = "EntryLo1"; 2326 + switch (sel) {
  2327 + case 0:
  2328 + gen_op_mtc0_entrylo1();
  2329 + rn = "EntryLo1";
  2330 + break;
  2331 + default:
  2332 + goto die;
  2333 + }
1562 break; 2334 break;
1563 case 4: 2335 case 4:
1564 - gen_op_mtc0_context();  
1565 - rn = "Context"; 2336 + switch (sel) {
  2337 + case 0:
  2338 + gen_op_mtc0_context();
  2339 + rn = "Context";
  2340 + break;
  2341 + case 1:
  2342 +// gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
  2343 + rn = "ContextConfig";
  2344 +// break;
  2345 + default:
  2346 + goto die;
  2347 + }
1566 break; 2348 break;
1567 case 5: 2349 case 5:
1568 - gen_op_mtc0_pagemask();  
1569 - rn = "PageMask"; 2350 + switch (sel) {
  2351 + case 0:
  2352 + gen_op_mtc0_pagemask();
  2353 + rn = "PageMask";
  2354 + break;
  2355 + case 1:
  2356 + gen_op_mtc0_pagegrain();
  2357 + rn = "PageGrain";
  2358 + break;
  2359 + default:
  2360 + goto die;
  2361 + }
1570 break; 2362 break;
1571 case 6: 2363 case 6:
1572 - gen_op_mtc0_wired();  
1573 - rn = "Wired"; 2364 + switch (sel) {
  2365 + case 0:
  2366 + gen_op_mtc0_wired();
  2367 + rn = "Wired";
  2368 + break;
  2369 + case 1:
  2370 +// gen_op_mtc0_srsconf0(); /* shadow registers */
  2371 + rn = "SRSConf0";
  2372 +// break;
  2373 + case 2:
  2374 +// gen_op_mtc0_srsconf1(); /* shadow registers */
  2375 + rn = "SRSConf1";
  2376 +// break;
  2377 + case 3:
  2378 +// gen_op_mtc0_srsconf2(); /* shadow registers */
  2379 + rn = "SRSConf2";
  2380 +// break;
  2381 + case 4:
  2382 +// gen_op_mtc0_srsconf3(); /* shadow registers */
  2383 + rn = "SRSConf3";
  2384 +// break;
  2385 + case 5:
  2386 +// gen_op_mtc0_srsconf4(); /* shadow registers */
  2387 + rn = "SRSConf4";
  2388 +// break;
  2389 + default:
  2390 + goto die;
  2391 + }
1574 break; 2392 break;
1575 case 7: 2393 case 7:
1576 -// ignore or except?  
1577 - rn = "Info"; 2394 + switch (sel) {
  2395 + case 0:
  2396 + gen_op_mtc0_hwrena();
  2397 + rn = "HWREna";
  2398 + break;
  2399 + default:
  2400 + goto die;
  2401 + }
1578 break; 2402 break;
1579 case 8: 2403 case 8:
1580 -// ignore or except? 2404 + /* ignored */
1581 rn = "BadVaddr"; 2405 rn = "BadVaddr";
1582 break; 2406 break;
1583 case 9: 2407 case 9:
1584 - gen_op_mtc0_count();  
1585 - rn = "Count"; 2408 + switch (sel) {
  2409 + case 0:
  2410 + gen_op_mtc0_count();
  2411 + rn = "Count";
  2412 + break;
  2413 + /* 6,7 are implementation dependent */
  2414 + default:
  2415 + goto die;
  2416 + }
  2417 + /* Stop translation as we may have switched the execution mode */
  2418 + ctx->bstate = BS_STOP;
1586 break; 2419 break;
1587 case 10: 2420 case 10:
1588 - gen_op_mtc0_entryhi();  
1589 - rn = "EntryHi"; 2421 + switch (sel) {
  2422 + case 0:
  2423 + gen_op_mtc0_entryhi();
  2424 + rn = "EntryHi";
  2425 + break;
  2426 + default:
  2427 + goto die;
  2428 + }
1590 break; 2429 break;
1591 case 11: 2430 case 11:
1592 - gen_op_mtc0_compare();  
1593 - rn = "Compare"; 2431 + switch (sel) {
  2432 + case 0:
  2433 + gen_op_mtc0_compare();
  2434 + rn = "Compare";
  2435 + break;
  2436 + /* 6,7 are implementation dependent */
  2437 + default:
  2438 + goto die;
  2439 + }
  2440 + /* Stop translation as we may have switched the execution mode */
  2441 + ctx->bstate = BS_STOP;
1594 break; 2442 break;
1595 case 12: 2443 case 12:
1596 - gen_op_mtc0_status();  
1597 - rn = "Status"; 2444 + switch (sel) {
  2445 + case 0:
  2446 + gen_op_mtc0_status();
  2447 + rn = "Status";
  2448 + break;
  2449 + case 1:
  2450 + gen_op_mtc0_intctl();
  2451 + rn = "IntCtl";
  2452 + break;
  2453 + case 2:
  2454 + gen_op_mtc0_srsctl();
  2455 + rn = "SRSCtl";
  2456 + break;
  2457 + case 3:
  2458 +// gen_op_mtc0_srsmap(); /* shadow registers */
  2459 + rn = "SRSMap";
  2460 +// break;
  2461 + default:
  2462 + goto die;
  2463 + }
  2464 + /* Stop translation as we may have switched the execution mode */
  2465 + ctx->bstate = BS_STOP;
1598 break; 2466 break;
1599 case 13: 2467 case 13:
1600 - gen_op_mtc0_cause();  
1601 - rn = "Cause"; 2468 + switch (sel) {
  2469 + case 0:
  2470 + gen_op_mtc0_cause();
  2471 + rn = "Cause";
  2472 + break;
  2473 + default:
  2474 + goto die;
  2475 + }
  2476 + /* Stop translation as we may have switched the execution mode */
  2477 + ctx->bstate = BS_STOP;
1602 break; 2478 break;
1603 case 14: 2479 case 14:
1604 - gen_op_mtc0_epc();  
1605 - rn = "EPC"; 2480 + switch (sel) {
  2481 + case 0:
  2482 + gen_op_mtc0_epc();
  2483 + rn = "EPC";
  2484 + break;
  2485 + default:
  2486 + goto die;
  2487 + }
1606 break; 2488 break;
1607 case 15: 2489 case 15:
1608 -// ignore or except?  
1609 - rn = "PRid"; 2490 + switch (sel) {
  2491 + case 0:
  2492 + /* ignored */
  2493 + rn = "PRid";
  2494 + break;
  2495 + case 1:
  2496 + gen_op_mtc0_ebase();
  2497 + rn = "EBase";
  2498 + break;
  2499 + default:
  2500 + goto die;
  2501 + }
1610 break; 2502 break;
1611 case 16: 2503 case 16:
1612 switch (sel) { 2504 switch (sel) {
1613 case 0: 2505 case 0:
1614 gen_op_mtc0_config0(); 2506 gen_op_mtc0_config0();
1615 - rn = "Config0"; 2507 + rn = "Config";
  2508 + break;
  2509 + case 1:
  2510 + /* ignored */
  2511 + rn = "Config1";
  2512 + break;
  2513 + case 2:
  2514 + gen_op_mtc0_config2();
  2515 + rn = "Config2";
1616 break; 2516 break;
  2517 + case 3:
  2518 + /* ignored */
  2519 + rn = "Config3";
  2520 + break;
  2521 + /* 6,7 are implementation dependent */
1617 default: 2522 default:
1618 rn = "Invalid config selector"; 2523 rn = "Invalid config selector";
1619 goto die; 2524 goto die;
1620 } 2525 }
  2526 + /* Stop translation as we may have switched the execution mode */
  2527 + ctx->bstate = BS_STOP;
1621 break; 2528 break;
1622 case 17: 2529 case 17:
1623 -// ignore or except?  
1624 - rn = "LLaddr"; 2530 + switch (sel) {
  2531 + case 0:
  2532 + /* ignored */
  2533 + rn = "LLAddr";
  2534 + break;
  2535 + default:
  2536 + goto die;
  2537 + }
1625 break; 2538 break;
1626 case 18: 2539 case 18:
1627 - gen_op_mtc0_watchlo();  
1628 - rn = "WatchLo"; 2540 + switch (sel) {
  2541 + case 0:
  2542 + gen_op_mtc0_watchlo0();
  2543 + rn = "WatchLo";
  2544 + break;
  2545 + case 1:
  2546 +// gen_op_mtc0_watchlo1();
  2547 + rn = "WatchLo1";
  2548 +// break;
  2549 + case 2:
  2550 +// gen_op_mtc0_watchlo2();
  2551 + rn = "WatchLo2";
  2552 +// break;
  2553 + case 3:
  2554 +// gen_op_mtc0_watchlo3();
  2555 + rn = "WatchLo3";
  2556 +// break;
  2557 + case 4:
  2558 +// gen_op_mtc0_watchlo4();
  2559 + rn = "WatchLo4";
  2560 +// break;
  2561 + case 5:
  2562 +// gen_op_mtc0_watchlo5();
  2563 + rn = "WatchLo5";
  2564 +// break;
  2565 + case 6:
  2566 +// gen_op_mtc0_watchlo6();
  2567 + rn = "WatchLo6";
  2568 +// break;
  2569 + case 7:
  2570 +// gen_op_mtc0_watchlo7();
  2571 + rn = "WatchLo7";
  2572 +// break;
  2573 + default:
  2574 + goto die;
  2575 + }
1629 break; 2576 break;
1630 case 19: 2577 case 19:
1631 - gen_op_mtc0_watchhi();  
1632 - rn = "WatchHi"; 2578 + switch (sel) {
  2579 + case 0:
  2580 + gen_op_mtc0_watchhi0();
  2581 + rn = "WatchHi";
  2582 + break;
  2583 + case 1:
  2584 +// gen_op_mtc0_watchhi1();
  2585 + rn = "WatchHi1";
  2586 +// break;
  2587 + case 2:
  2588 +// gen_op_mtc0_watchhi2();
  2589 + rn = "WatchHi2";
  2590 +// break;
  2591 + case 3:
  2592 +// gen_op_mtc0_watchhi3();
  2593 + rn = "WatchHi3";
  2594 +// break;
  2595 + case 4:
  2596 +// gen_op_mtc0_watchhi4();
  2597 + rn = "WatchHi4";
  2598 +// break;
  2599 + case 5:
  2600 +// gen_op_mtc0_watchhi5();
  2601 + rn = "WatchHi5";
  2602 +// break;
  2603 + case 6:
  2604 +// gen_op_mtc0_watchhi6();
  2605 + rn = "WatchHi6";
  2606 +// break;
  2607 + case 7:
  2608 +// gen_op_mtc0_watchhi7();
  2609 + rn = "WatchHi7";
  2610 +// break;
  2611 + default:
  2612 + goto die;
  2613 + }
1633 break; 2614 break;
1634 case 20: 2615 case 20:
1635 - /* 64 bit only */  
1636 -// gen_op_mtc0_xcontext();  
1637 - rn = "XContext"; 2616 + switch (sel) {
  2617 + case 0:
  2618 + /* 64 bit MMU only */
  2619 + gen_op_mtc0_xcontext();
  2620 + rn = "XContext";
  2621 + break;
  2622 + default:
  2623 + goto die;
  2624 + }
1638 break; 2625 break;
1639 case 21: 2626 case 21:
1640 -// gen_op_mtc0_framemask();  
1641 - rn = "Framemask";  
1642 - break; 2627 + /* Officially reserved, but sel 0 is used for R1x000 framemask */
  2628 + switch (sel) {
  2629 + case 0:
  2630 + gen_op_mtc0_framemask();
  2631 + rn = "Framemask";
  2632 + break;
  2633 + default:
  2634 + goto die;
  2635 + }
  2636 + break;
1643 case 22: 2637 case 22:
1644 -// ignore or except?  
1645 - rn = "Diagnostic"; 2638 + /* ignored */
  2639 + rn = "Diagnostic"; /* implementation dependent */
1646 break; 2640 break;
1647 case 23: 2641 case 23:
1648 - gen_op_mtc0_debug();  
1649 - rn = "Debug"; 2642 + switch (sel) {
  2643 + case 0:
  2644 + gen_op_mtc0_debug(); /* EJTAG support */
  2645 + rn = "Debug";
  2646 + break;
  2647 + case 1:
  2648 +// gen_op_mtc0_tracecontrol(); /* PDtrace support */
  2649 + rn = "TraceControl";
  2650 +// break;
  2651 + case 2:
  2652 +// gen_op_mtc0_tracecontrol2(); /* PDtrace support */
  2653 + rn = "TraceControl2";
  2654 +// break;
  2655 + case 3:
  2656 +// gen_op_mtc0_usertracedata(); /* PDtrace support */
  2657 + rn = "UserTraceData";
  2658 +// break;
  2659 + case 4:
  2660 +// gen_op_mtc0_debug(); /* PDtrace support */
  2661 + rn = "TraceBPC";
  2662 +// break;
  2663 + default:
  2664 + goto die;
  2665 + }
  2666 + /* Stop translation as we may have switched the execution mode */
  2667 + ctx->bstate = BS_STOP;
1650 break; 2668 break;
1651 case 24: 2669 case 24:
1652 - gen_op_mtc0_depc();  
1653 - rn = "DEPC"; 2670 + switch (sel) {
  2671 + case 0:
  2672 + gen_op_mtc0_depc(); /* EJTAG support */
  2673 + rn = "DEPC";
  2674 + break;
  2675 + default:
  2676 + goto die;
  2677 + }
1654 break; 2678 break;
1655 case 25: 2679 case 25:
1656 -// ignore or except?  
1657 - rn = "Performance"; 2680 + switch (sel) {
  2681 + case 0:
  2682 + gen_op_mtc0_performance0();
  2683 + rn = "Performance0";
  2684 + break;
  2685 + case 1:
  2686 +// gen_op_mtc0_performance1();
  2687 + rn = "Performance1";
  2688 +// break;
  2689 + case 2:
  2690 +// gen_op_mtc0_performance2();
  2691 + rn = "Performance2";
  2692 +// break;
  2693 + case 3:
  2694 +// gen_op_mtc0_performance3();
  2695 + rn = "Performance3";
  2696 +// break;
  2697 + case 4:
  2698 +// gen_op_mtc0_performance4();
  2699 + rn = "Performance4";
  2700 +// break;
  2701 + case 5:
  2702 +// gen_op_mtc0_performance5();
  2703 + rn = "Performance5";
  2704 +// break;
  2705 + case 6:
  2706 +// gen_op_mtc0_performance6();
  2707 + rn = "Performance6";
  2708 +// break;
  2709 + case 7:
  2710 +// gen_op_mtc0_performance7();
  2711 + rn = "Performance7";
  2712 +// break;
  2713 + default:
  2714 + goto die;
  2715 + }
1658 break; 2716 break;
1659 case 26: 2717 case 26:
1660 -// ignore or except? 2718 + /* ignored */
1661 rn = "ECC"; 2719 rn = "ECC";
1662 break; 2720 break;
1663 case 27: 2721 case 27:
1664 -// ignore or except?  
1665 - rn = "CacheErr"; 2722 + switch (sel) {
  2723 + case 0 ... 3:
  2724 + /* ignored */
  2725 + rn = "CacheErr";
  2726 + break;
  2727 + default:
  2728 + goto die;
  2729 + }
1666 break; 2730 break;
1667 case 28: 2731 case 28:
1668 switch (sel) { 2732 switch (sel) {
1669 case 0: 2733 case 0:
  2734 + case 2:
  2735 + case 4:
  2736 + case 6:
1670 gen_op_mtc0_taglo(); 2737 gen_op_mtc0_taglo();
1671 rn = "TagLo"; 2738 rn = "TagLo";
1672 break; 2739 break;
  2740 + case 1:
  2741 + case 3:
  2742 + case 5:
  2743 + case 7:
  2744 + gen_op_mtc0_datalo();
  2745 + rn = "DataLo";
  2746 + break;
1673 default: 2747 default:
1674 - rn = "invalid sel";  
1675 goto die; 2748 goto die;
1676 } 2749 }
1677 break; 2750 break;
1678 case 29: 2751 case 29:
1679 -// gen_op_mtc0_taghi();  
1680 - rn = "TagHi"; 2752 + switch (sel) {
  2753 + case 0:
  2754 + case 2:
  2755 + case 4:
  2756 + case 6:
  2757 + gen_op_mtc0_taghi();
  2758 + rn = "TagHi";
  2759 + break;
  2760 + case 1:
  2761 + case 3:
  2762 + case 5:
  2763 + case 7:
  2764 + gen_op_mtc0_datahi();
  2765 + rn = "DataHi";
  2766 + break;
  2767 + default:
  2768 + rn = "invalid sel";
  2769 + goto die;
  2770 + }
1681 break; 2771 break;
1682 case 30: 2772 case 30:
1683 - gen_op_mtc0_errorepc();  
1684 - rn = "ErrorEPC"; 2773 + switch (sel) {
  2774 + case 0:
  2775 + gen_op_mtc0_errorepc();
  2776 + rn = "ErrorEPC";
  2777 + break;
  2778 + default:
  2779 + goto die;
  2780 + }
1685 break; 2781 break;
1686 case 31: 2782 case 31:
1687 - gen_op_mtc0_desave();  
1688 - rn = "DESAVE"; 2783 + switch (sel) {
  2784 + case 0:
  2785 + gen_op_mtc0_desave(); /* EJTAG support */
  2786 + rn = "DESAVE";
  2787 + break;
  2788 + default:
  2789 + goto die;
  2790 + }
  2791 + /* Stop translation as we may have switched the execution mode */
  2792 + ctx->bstate = BS_STOP;
1689 break; 2793 break;
1690 default: 2794 default:
1691 - rn = "unknown";  
1692 goto die; 2795 goto die;
1693 } 2796 }
1694 #if defined MIPS_DEBUG_DISAS 2797 #if defined MIPS_DEBUG_DISAS
1695 if (loglevel & CPU_LOG_TB_IN_ASM) { 2798 if (loglevel & CPU_LOG_TB_IN_ASM) {
1696 - fprintf(logfile, "%08x mtc0 %s => %08x (%d %d)\n",  
1697 - env->PC, rn, T0, reg, sel); 2799 + fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
  2800 + rn, reg, sel);
1698 } 2801 }
1699 #endif 2802 #endif
1700 return; 2803 return;
@@ -1702,16 +2805,16 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) @@ -1702,16 +2805,16 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
1702 die: 2805 die:
1703 #if defined MIPS_DEBUG_DISAS 2806 #if defined MIPS_DEBUG_DISAS
1704 if (loglevel & CPU_LOG_TB_IN_ASM) { 2807 if (loglevel & CPU_LOG_TB_IN_ASM) {
1705 - fprintf(logfile, "%08x mtc0 %s => %08x (%d %d)\n",  
1706 - env->PC, rn, T0, reg, sel); 2808 + fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
  2809 + rn, reg, sel);
1707 } 2810 }
1708 #endif 2811 #endif
1709 generate_exception(ctx, EXCP_RI); 2812 generate_exception(ctx, EXCP_RI);
1710 } 2813 }
1711 2814
1712 -static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd) 2815 +static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
1713 { 2816 {
1714 - const unsigned char *opn = "unk"; 2817 + const char *opn = "unk";
1715 2818
1716 if (!(ctx->CP0_Status & (1 << CP0St_CU0)) && 2819 if (!(ctx->CP0_Status & (1 << CP0St_CU0)) &&
1717 (ctx->hflags & MIPS_HFLAG_UM) && 2820 (ctx->hflags & MIPS_HFLAG_UM) &&
@@ -1720,7 +2823,7 @@ static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd) @@ -1720,7 +2823,7 @@ static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd)
1720 if (loglevel & CPU_LOG_TB_IN_ASM) { 2823 if (loglevel & CPU_LOG_TB_IN_ASM) {
1721 fprintf(logfile, "CP0 is not usable\n"); 2824 fprintf(logfile, "CP0 is not usable\n");
1722 } 2825 }
1723 - generate_exception_err (ctx, EXCP_CpU, 0); 2826 + generate_exception (ctx, EXCP_CpU);
1724 return; 2827 return;
1725 } 2828 }
1726 2829
@@ -1736,13 +2839,12 @@ static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd) @@ -1736,13 +2839,12 @@ static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd)
1736 break; 2839 break;
1737 case OPC_MTC0: 2840 case OPC_MTC0:
1738 /* If we get an exception, we want to restart at next instruction */ 2841 /* If we get an exception, we want to restart at next instruction */
  2842 + /* XXX: breaks for mtc in delay slot */
1739 ctx->pc += 4; 2843 ctx->pc += 4;
1740 save_cpu_state(ctx, 1); 2844 save_cpu_state(ctx, 1);
1741 ctx->pc -= 4; 2845 ctx->pc -= 4;
1742 GEN_LOAD_REG_TN(T0, rt); 2846 GEN_LOAD_REG_TN(T0, rt);
1743 gen_mtc0(ctx, rd, ctx->opcode & 0x7); 2847 gen_mtc0(ctx, rd, ctx->opcode & 0x7);
1744 - /* Stop translation as we may have switched the execution mode */  
1745 - ctx->bstate = BS_STOP;  
1746 opn = "mtc0"; 2848 opn = "mtc0";
1747 break; 2849 break;
1748 #if defined(MIPS_USES_R4K_TLB) 2850 #if defined(MIPS_USES_R4K_TLB)
@@ -1800,31 +2902,30 @@ static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd) @@ -1800,31 +2902,30 @@ static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd)
1800 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd); 2902 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
1801 } 2903 }
1802 2904
1803 -#ifdef MIPS_USES_FPU  
1804 /* CP1 Branches (before delay slot) */ 2905 /* CP1 Branches (before delay slot) */
1805 -static void gen_compute_branch1 (DisasContext *ctx, uint16_t cond, 2906 +static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
1806 int32_t offset) 2907 int32_t offset)
1807 { 2908 {
1808 target_ulong btarget; 2909 target_ulong btarget;
1809 2910
1810 btarget = ctx->pc + 4 + offset; 2911 btarget = ctx->pc + 4 + offset;
1811 2912
1812 - switch (cond) {  
1813 - case 0x0000: /* bc1f */ 2913 + switch (op) {
  2914 + case OPC_BC1F:
1814 gen_op_bc1f(); 2915 gen_op_bc1f();
1815 MIPS_DEBUG("bc1f %08x", btarget); 2916 MIPS_DEBUG("bc1f %08x", btarget);
1816 goto not_likely; 2917 goto not_likely;
1817 - case 0x0002: /* bc1fl */ 2918 + case OPC_BC1FL:
1818 gen_op_bc1f(); 2919 gen_op_bc1f();
1819 MIPS_DEBUG("bc1fl %08x", btarget); 2920 MIPS_DEBUG("bc1fl %08x", btarget);
1820 goto likely; 2921 goto likely;
1821 - case 0x0001: /* bc1t */ 2922 + case OPC_BC1T:
1822 gen_op_bc1t(); 2923 gen_op_bc1t();
1823 MIPS_DEBUG("bc1t %08x", btarget); 2924 MIPS_DEBUG("bc1t %08x", btarget);
1824 not_likely: 2925 not_likely:
1825 ctx->hflags |= MIPS_HFLAG_BC; 2926 ctx->hflags |= MIPS_HFLAG_BC;
1826 break; 2927 break;
1827 - case 0x0003: /* bc1tl */ 2928 + case OPC_BC1TL:
1828 gen_op_bc1t(); 2929 gen_op_bc1t();
1829 MIPS_DEBUG("bc1tl %08x", btarget); 2930 MIPS_DEBUG("bc1tl %08x", btarget);
1830 likely: 2931 likely:
@@ -1832,7 +2933,7 @@ static void gen_compute_branch1 (DisasContext *ctx, uint16_t cond, @@ -1832,7 +2933,7 @@ static void gen_compute_branch1 (DisasContext *ctx, uint16_t cond,
1832 break; 2933 break;
1833 default: 2934 default:
1834 MIPS_INVAL("cp1 branch/jump"); 2935 MIPS_INVAL("cp1 branch/jump");
1835 - generate_exception(ctx, EXCP_RI); 2936 + generate_exception_err (ctx, EXCP_RI, 1);
1836 return; 2937 return;
1837 } 2938 }
1838 gen_op_set_bcond(); 2939 gen_op_set_bcond();
@@ -1845,9 +2946,9 @@ static void gen_compute_branch1 (DisasContext *ctx, uint16_t cond, @@ -1845,9 +2946,9 @@ static void gen_compute_branch1 (DisasContext *ctx, uint16_t cond,
1845 } 2946 }
1846 2947
1847 /* Coprocessor 1 (FPU) */ 2948 /* Coprocessor 1 (FPU) */
1848 -static void gen_cp1 (DisasContext *ctx, uint16_t opc, int rt, int fs) 2949 +static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
1849 { 2950 {
1850 - const unsigned char *opn = "unk"; 2951 + const char *opn = "unk";
1851 2952
1852 switch (opc) { 2953 switch (opc) {
1853 case OPC_MFC1: 2954 case OPC_MFC1:
@@ -1865,7 +2966,7 @@ static void gen_cp1 (DisasContext *ctx, uint16_t opc, int rt, int fs) @@ -1865,7 +2966,7 @@ static void gen_cp1 (DisasContext *ctx, uint16_t opc, int rt, int fs)
1865 case OPC_CFC1: 2966 case OPC_CFC1:
1866 if (fs != 0 && fs != 31) { 2967 if (fs != 0 && fs != 31) {
1867 MIPS_INVAL("cfc1 freg"); 2968 MIPS_INVAL("cfc1 freg");
1868 - generate_exception(ctx, EXCP_RI); 2969 + generate_exception_err (ctx, EXCP_RI, 1);
1869 return; 2970 return;
1870 } 2971 }
1871 GEN_LOAD_IMM_TN(T1, fs); 2972 GEN_LOAD_IMM_TN(T1, fs);
@@ -1874,9 +2975,9 @@ static void gen_cp1 (DisasContext *ctx, uint16_t opc, int rt, int fs) @@ -1874,9 +2975,9 @@ static void gen_cp1 (DisasContext *ctx, uint16_t opc, int rt, int fs)
1874 opn = "cfc1"; 2975 opn = "cfc1";
1875 break; 2976 break;
1876 case OPC_CTC1: 2977 case OPC_CTC1:
1877 - if (fs != 0 && fs != 31) { 2978 + if (fs != 0 && fs != 31) {
1878 MIPS_INVAL("ctc1 freg"); 2979 MIPS_INVAL("ctc1 freg");
1879 - generate_exception(ctx, EXCP_RI); 2980 + generate_exception_err (ctx, EXCP_RI, 1);
1880 return; 2981 return;
1881 } 2982 }
1882 GEN_LOAD_IMM_TN(T1, fs); 2983 GEN_LOAD_IMM_TN(T1, fs);
@@ -1890,7 +2991,7 @@ static void gen_cp1 (DisasContext *ctx, uint16_t opc, int rt, int fs) @@ -1890,7 +2991,7 @@ static void gen_cp1 (DisasContext *ctx, uint16_t opc, int rt, int fs)
1890 ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F, 2991 ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
1891 ((ctx->opcode >> 16) & 0x1F)); 2992 ((ctx->opcode >> 16) & 0x1F));
1892 } 2993 }
1893 - generate_exception(ctx, EXCP_RI); 2994 + generate_exception_err (ctx, EXCP_RI, 1);
1894 return; 2995 return;
1895 } 2996 }
1896 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]); 2997 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
@@ -1908,16 +3009,16 @@ static void gen_cp1 (DisasContext *ctx, uint16_t opc, int rt, int fs) @@ -1908,16 +3009,16 @@ static void gen_cp1 (DisasContext *ctx, uint16_t opc, int rt, int fs)
1908 */ 3009 */
1909 #define CHECK_FR(ctx, freg) do { \ 3010 #define CHECK_FR(ctx, freg) do { \
1910 if (!((ctx)->CP0_Status & (1<<CP0St_FR)) && ((freg) & 1)) { \ 3011 if (!((ctx)->CP0_Status & (1<<CP0St_FR)) && ((freg) & 1)) { \
1911 - generate_exception(ctx, EXCP_RI); \ 3012 + generate_exception_err (ctx, EXCP_RI, 1); \
1912 return; \ 3013 return; \
1913 } \ 3014 } \
1914 } while(0) 3015 } while(0)
1915 3016
1916 #define FOP(func, fmt) (((fmt) << 21) | (func)) 3017 #define FOP(func, fmt) (((fmt) << 21) | (func))
1917 3018
1918 -static void gen_farith (DisasContext *ctx, int fmt, int ft, int fs, int fd, int func) 3019 +static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd)
1919 { 3020 {
1920 - const unsigned char *opn = "unk"; 3021 + const char *opn = "unk";
1921 const char *condnames[] = { 3022 const char *condnames[] = {
1922 "c.f", 3023 "c.f",
1923 "c.un", 3024 "c.un",
@@ -1937,7 +3038,8 @@ static void gen_farith (DisasContext *ctx, int fmt, int ft, int fs, int fd, int @@ -1937,7 +3038,8 @@ static void gen_farith (DisasContext *ctx, int fmt, int ft, int fs, int fd, int
1937 "c.ngt", 3038 "c.ngt",
1938 }; 3039 };
1939 int binary = 0; 3040 int binary = 0;
1940 - 3041 + uint32_t func = ctx->opcode & 0x3f;
  3042 +
1941 switch (ctx->opcode & FOP(0x3f, 0x1f)) { 3043 switch (ctx->opcode & FOP(0x3f, 0x1f)) {
1942 case FOP(0, 17): 3044 case FOP(0, 17):
1943 CHECK_FR(ctx, fs | ft | fd); 3045 CHECK_FR(ctx, fs | ft | fd);
@@ -2033,7 +3135,7 @@ static void gen_farith (DisasContext *ctx, int fmt, int ft, int fs, int fd, int @@ -2033,7 +3135,7 @@ static void gen_farith (DisasContext *ctx, int fmt, int ft, int fs, int fd, int
2033 GEN_LOAD_FREG_FTN(DT0, fs); 3135 GEN_LOAD_FREG_FTN(DT0, fs);
2034 gen_op_float_floorw_d(); 3136 gen_op_float_floorw_d();
2035 GEN_STORE_FTN_FREG(fd, WT2); 3137 GEN_STORE_FTN_FREG(fd, WT2);
2036 - opn = "ceil.w.d"; 3138 + opn = "floor.w.d";
2037 break; 3139 break;
2038 case FOP(33, 16): /* cvt.d.s */ 3140 case FOP(33, 16): /* cvt.d.s */
2039 CHECK_FR(ctx, fs | fd); 3141 CHECK_FR(ctx, fs | fd);
@@ -2201,11 +3303,11 @@ static void gen_farith (DisasContext *ctx, int fmt, int ft, int fs, int fd, int @@ -2201,11 +3303,11 @@ static void gen_farith (DisasContext *ctx, int fmt, int ft, int fs, int fd, int
2201 break; 3303 break;
2202 default: 3304 default:
2203 if (loglevel & CPU_LOG_TB_IN_ASM) { 3305 if (loglevel & CPU_LOG_TB_IN_ASM) {
2204 - fprintf(logfile, "Invalid arith function: %08x %03x %03x %03x\n", 3306 + fprintf(logfile, "Invalid FP arith function: %08x %03x %03x %03x\n",
2205 ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F, 3307 ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
2206 ((ctx->opcode >> 16) & 0x1F)); 3308 ((ctx->opcode >> 16) & 0x1F));
2207 } 3309 }
2208 - generate_exception(ctx, EXCP_RI); 3310 + generate_exception_err (ctx, EXCP_RI, 1);
2209 return; 3311 return;
2210 } 3312 }
2211 if (binary) 3313 if (binary)
@@ -2213,14 +3315,27 @@ static void gen_farith (DisasContext *ctx, int fmt, int ft, int fs, int fd, int @@ -2213,14 +3315,27 @@ static void gen_farith (DisasContext *ctx, int fmt, int ft, int fs, int fd, int
2213 else 3315 else
2214 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]); 3316 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
2215 } 3317 }
2216 -#endif  
2217 3318
2218 -/* ISA extensions */ 3319 +static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
  3320 +{
  3321 + uint32_t ccbit;
  3322 +
  3323 + if (cc)
  3324 + ccbit = 1 << (24 + cc);
  3325 + else
  3326 + ccbit = 1 << 23;
  3327 + if (!tf)
  3328 + gen_op_movf(ccbit, rd, rs);
  3329 + else
  3330 + gen_op_movt(ccbit, rd, rs);
  3331 +}
  3332 +
  3333 +/* ISA extensions (ASEs) */
2219 /* MIPS16 extension to MIPS32 */ 3334 /* MIPS16 extension to MIPS32 */
2220 /* SmartMIPS extension to MIPS32 */ 3335 /* SmartMIPS extension to MIPS32 */
2221 3336
2222 -#ifdef TARGET_MIPS64  
2223 -static void gen_arith64 (DisasContext *ctx, uint16_t opc) 3337 +#ifdef MIPS_HAS_MIPS64
  3338 +static void gen_arith64 (DisasContext *ctx, uint32_t opc)
2224 { 3339 {
2225 if (func == 0x02 && rd == 0) { 3340 if (func == 0x02 && rd == 0) {
2226 /* NOP */ 3341 /* NOP */
@@ -2265,7 +3380,7 @@ static void decode_opc (DisasContext *ctx) @@ -2265,7 +3380,7 @@ static void decode_opc (DisasContext *ctx)
2265 { 3380 {
2266 int32_t offset; 3381 int32_t offset;
2267 int rs, rt, rd, sa; 3382 int rs, rt, rd, sa;
2268 - uint16_t op, op1; 3383 + uint32_t op, op1, op2;
2269 int16_t imm; 3384 int16_t imm;
2270 3385
2271 /* make sure instructions are on a word boundary */ 3386 /* make sure instructions are on a word boundary */
@@ -2279,76 +3394,86 @@ static void decode_opc (DisasContext *ctx) @@ -2279,76 +3394,86 @@ static void decode_opc (DisasContext *ctx)
2279 MIPS_DEBUG("blikely condition (%08x)", ctx->pc + 4); 3394 MIPS_DEBUG("blikely condition (%08x)", ctx->pc + 4);
2280 gen_blikely(ctx); 3395 gen_blikely(ctx);
2281 } 3396 }
2282 - op = ctx->opcode >> 26;  
2283 - rs = ((ctx->opcode >> 21) & 0x1F);  
2284 - rt = ((ctx->opcode >> 16) & 0x1F);  
2285 - rd = ((ctx->opcode >> 11) & 0x1F);  
2286 - sa = ((ctx->opcode >> 6) & 0x1F); 3397 + op = MASK_OP_MAJOR(ctx->opcode);
  3398 + rs = (ctx->opcode >> 21) & 0x1f;
  3399 + rt = (ctx->opcode >> 16) & 0x1f;
  3400 + rd = (ctx->opcode >> 11) & 0x1f;
  3401 + sa = (ctx->opcode >> 6) & 0x1f;
2287 imm = (int16_t)ctx->opcode; 3402 imm = (int16_t)ctx->opcode;
2288 switch (op) { 3403 switch (op) {
2289 - case 0x00: /* Special opcode */  
2290 - op1 = ctx->opcode & 0x3F; 3404 + case OPC_SPECIAL:
  3405 + op1 = MASK_SPECIAL(ctx->opcode);
2291 switch (op1) { 3406 switch (op1) {
2292 - case 0x00: /* Arithmetic with immediate */  
2293 - case 0x02 ... 0x03:  
2294 - gen_arith_imm(ctx, op1 | EXT_SPECIAL, rd, rt, sa);  
2295 - break;  
2296 - case 0x04: /* Arithmetic */  
2297 - case 0x06 ... 0x07:  
2298 - case 0x0A ... 0x0B:  
2299 - case 0x20 ... 0x27:  
2300 - case 0x2A ... 0x2B:  
2301 - gen_arith(ctx, op1 | EXT_SPECIAL, rd, rs, rt);  
2302 - break;  
2303 - case 0x18 ... 0x1B: /* MULT / DIV */  
2304 - gen_muldiv(ctx, op1 | EXT_SPECIAL, rs, rt);  
2305 - break;  
2306 - case 0x08 ... 0x09: /* Jumps */  
2307 - gen_compute_branch(ctx, op1 | EXT_SPECIAL, rs, rd, sa); 3407 + case OPC_SLL: /* Arithmetic with immediate */
  3408 + case OPC_SRL ... OPC_SRA:
  3409 + gen_arith_imm(ctx, op1, rd, rt, sa);
  3410 + break;
  3411 + case OPC_SLLV: /* Arithmetic */
  3412 + case OPC_SRLV ... OPC_SRAV:
  3413 + case OPC_MOVZ ... OPC_MOVN:
  3414 + case OPC_ADD ... OPC_NOR:
  3415 + case OPC_SLT ... OPC_SLTU:
  3416 + gen_arith(ctx, op1, rd, rs, rt);
  3417 + break;
  3418 + case OPC_MULT ... OPC_DIVU:
  3419 + gen_muldiv(ctx, op1, rs, rt);
  3420 + break;
  3421 + case OPC_JR ... OPC_JALR:
  3422 + gen_compute_branch(ctx, op1, rs, rd, sa);
2308 return; 3423 return;
2309 - case 0x30 ... 0x34: /* Traps */  
2310 - case 0x36:  
2311 - gen_trap(ctx, op1 | EXT_SPECIAL, rs, rt, -1); 3424 + case OPC_TGE ... OPC_TEQ: /* Traps */
  3425 + case OPC_TNE:
  3426 + gen_trap(ctx, op1, rs, rt, -1);
2312 break; 3427 break;
2313 - case 0x10: /* Move from HI/LO */  
2314 - case 0x12:  
2315 - gen_HILO(ctx, op1 | EXT_SPECIAL, rd); 3428 + case OPC_MFHI: /* Move from HI/LO */
  3429 + case OPC_MFLO:
  3430 + gen_HILO(ctx, op1, rd);
2316 break; 3431 break;
2317 - case 0x11:  
2318 - case 0x13: /* Move to HI/LO */  
2319 - gen_HILO(ctx, op1 | EXT_SPECIAL, rs); 3432 + case OPC_MTHI:
  3433 + case OPC_MTLO: /* Move to HI/LO */
  3434 + gen_HILO(ctx, op1, rs);
2320 break; 3435 break;
2321 - case 0x0C: /* SYSCALL */ 3436 + case OPC_PMON: /* Pmon entry point */
  3437 + gen_op_pmon(sa);
  3438 + break;
  3439 + case OPC_SYSCALL:
2322 generate_exception(ctx, EXCP_SYSCALL); 3440 generate_exception(ctx, EXCP_SYSCALL);
  3441 + ctx->bstate = BS_EXCP;
2323 break; 3442 break;
2324 - case 0x0D: /* BREAK */ 3443 + case OPC_BREAK:
2325 generate_exception(ctx, EXCP_BREAK); 3444 generate_exception(ctx, EXCP_BREAK);
2326 break; 3445 break;
2327 - case 0x0F: /* SYNC */  
2328 - /* Treat as a noop */ 3446 + case OPC_SPIM: /* SPIM ? */
  3447 + /* Implemented as RI exception for now. */
  3448 + MIPS_INVAL("spim (unofficial)");
  3449 + generate_exception(ctx, EXCP_RI);
2329 break; 3450 break;
2330 - case 0x05: /* Pmon entry point */  
2331 - gen_op_pmon((ctx->opcode >> 6) & 0x1F); 3451 + case OPC_SYNC:
  3452 + /* Treat as a noop. */
2332 break; 3453 break;
2333 3454
2334 - case 0x01: /* MOVCI */  
2335 -#if defined (MIPS_HAS_MOVCI)  
2336 - /* XXX */  
2337 -#else  
2338 - /* Not implemented */  
2339 - generate_exception_err (ctx, EXCP_CpU, 1);  
2340 -#endif 3455 + case OPC_MOVCI:
  3456 + gen_op_cp1_enabled();
  3457 + gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
  3458 + (ctx->opcode >> 16) & 1);
2341 break; 3459 break;
2342 3460
2343 -#if defined (TARGET_MIPS64)  
2344 - case 0x14: /* MIPS64 specific opcodes */  
2345 - case 0x16:  
2346 - case 0x17:  
2347 - case 0x1C ... 0x1F:  
2348 - case 0x2C ... 0x2F:  
2349 - case 0x37:  
2350 - case 0x39 ... 0x3B:  
2351 - case 0x3E ... 0x3F: 3461 +#ifdef MIPS_HAS_MIPS64
  3462 + /* MIPS64 specific opcodes */
  3463 + case OPC_DSLL:
  3464 + case OPC_DSRL ... OPC_DSRA:
  3465 + case OPC_DSLL32:
  3466 + case OPC_DSRL32 ... OPC_DSRA32:
  3467 + gen_arith_imm(ctx, op1, rd, rt, sa);
  3468 + break;
  3469 + case OPC_DSLLV:
  3470 + case OPC_DSRLV ... OPC_DSRAV:
  3471 + case OPC_DADD ... OPC_DSUBU:
  3472 + gen_arith(ctx, op1, rd, rs, rt);
  3473 + break;
  3474 + case OPC_DMULT ... OPC_DDIVU:
  3475 + gen_muldiv(ctx, op1, rs, rt);
  3476 + break;
2352 #endif 3477 #endif
2353 default: /* Invalid */ 3478 default: /* Invalid */
2354 MIPS_INVAL("special"); 3479 MIPS_INVAL("special");
@@ -2356,23 +3481,20 @@ static void decode_opc (DisasContext *ctx) @@ -2356,23 +3481,20 @@ static void decode_opc (DisasContext *ctx)
2356 break; 3481 break;
2357 } 3482 }
2358 break; 3483 break;
2359 - case 0x1C: /* Special2 opcode */  
2360 - op1 = ctx->opcode & 0x3F; 3484 + case OPC_SPECIAL2:
  3485 + op1 = MASK_SPECIAL2(ctx->opcode);
2361 switch (op1) { 3486 switch (op1) {
2362 -#if defined (MIPS_USES_R4K_EXT)  
2363 - /* Those instructions are not part of MIPS32 core */  
2364 - case 0x00 ... 0x01: /* Multiply and add/sub */  
2365 - case 0x04 ... 0x05:  
2366 - gen_muldiv(ctx, op1 | EXT_SPECIAL2, rs, rt); 3487 + case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
  3488 + case OPC_MSUB ... OPC_MSUBU:
  3489 + gen_muldiv(ctx, op1, rs, rt);
2367 break; 3490 break;
2368 - case 0x02: /* MUL */  
2369 - gen_arith(ctx, op1 | EXT_SPECIAL2, rd, rs, rt); 3491 + case OPC_MUL:
  3492 + gen_arith(ctx, op1, rd, rs, rt);
2370 break; 3493 break;
2371 - case 0x20 ... 0x21: /* CLO / CLZ */  
2372 - gen_cl(ctx, op1 | EXT_SPECIAL2, rd, rs); 3494 + case OPC_CLZ ... OPC_CLO:
  3495 + gen_cl(ctx, op1, rd, rs);
2373 break; 3496 break;
2374 -#endif  
2375 - case 0x3F: /* SDBBP */ 3497 + case OPC_SDBBP:
2376 /* XXX: not clear which exception should be raised 3498 /* XXX: not clear which exception should be raised
2377 * when in debug mode... 3499 * when in debug mode...
2378 */ 3500 */
@@ -2383,22 +3505,109 @@ static void decode_opc (DisasContext *ctx) @@ -2383,22 +3505,109 @@ static void decode_opc (DisasContext *ctx)
2383 } 3505 }
2384 /* Treat as a noop */ 3506 /* Treat as a noop */
2385 break; 3507 break;
  3508 +#ifdef MIPS_HAS_MIPS64
  3509 + case OPC_DCLZ ... OPC_DCLO:
  3510 + gen_cl(ctx, op1, rd, rs);
  3511 + break;
  3512 +#endif
2386 default: /* Invalid */ 3513 default: /* Invalid */
2387 MIPS_INVAL("special2"); 3514 MIPS_INVAL("special2");
2388 generate_exception(ctx, EXCP_RI); 3515 generate_exception(ctx, EXCP_RI);
2389 break; 3516 break;
2390 } 3517 }
2391 break; 3518 break;
2392 - case 0x01: /* B REGIMM opcode */  
2393 - op1 = ((ctx->opcode >> 16) & 0x1F); 3519 + case OPC_SPECIAL3:
  3520 + op1 = MASK_SPECIAL3(ctx->opcode);
2394 switch (op1) { 3521 switch (op1) {
2395 - case 0x00 ... 0x03: /* REGIMM branches */  
2396 - case 0x10 ... 0x13:  
2397 - gen_compute_branch(ctx, op1 | EXT_REGIMM, rs, -1, imm << 2); 3522 + case OPC_EXT:
  3523 + case OPC_INS:
  3524 + gen_bitops(ctx, op1, rt, rs, sa, rd);
  3525 + break;
  3526 + case OPC_BSHFL:
  3527 + op2 = MASK_BSHFL(ctx->opcode);
  3528 + switch (op2) {
  3529 + case OPC_WSBH:
  3530 + GEN_LOAD_REG_TN(T1, rt);
  3531 + gen_op_wsbh();
  3532 + break;
  3533 + case OPC_SEB:
  3534 + GEN_LOAD_REG_TN(T1, rt);
  3535 + gen_op_seb();
  3536 + break;
  3537 + case OPC_SEH:
  3538 + GEN_LOAD_REG_TN(T1, rt);
  3539 + gen_op_seh();
  3540 + break;
  3541 + default: /* Invalid */
  3542 + MIPS_INVAL("bshfl");
  3543 + generate_exception(ctx, EXCP_RI);
  3544 + break;
  3545 + }
  3546 + GEN_STORE_TN_REG(rd, T0);
  3547 + break;
  3548 + case OPC_RDHWR:
  3549 + switch (rd) {
  3550 + case 0:
  3551 + gen_op_rdhwr_cpunum();
  3552 + break;
  3553 + case 1:
  3554 + gen_op_rdhwr_synci_step();
  3555 + break;
  3556 + case 2:
  3557 + gen_op_rdhwr_cc();
  3558 + break;
  3559 + case 3:
  3560 + gen_op_rdhwr_ccres();
  3561 + break;
  3562 + default: /* Invalid */
  3563 + MIPS_INVAL("rdhwr");
  3564 + generate_exception(ctx, EXCP_RI);
  3565 + break;
  3566 + }
  3567 + GEN_STORE_TN_REG(rt, T0);
  3568 + break;
  3569 +#ifdef MIPS_HAS_MIPS64
  3570 + case OPC_DEXTM ... OPC_DEXT:
  3571 + case OPC_DINSM ... OPC_DINS:
  3572 + gen_bitops(ctx, op1, rt, rs, sa, rd);
  3573 + break;
  3574 + case OPC_DBSHFL:
  3575 + op2 = MASK_DBSHFL(ctx->opcode);
  3576 + switch (op2) {
  3577 + case OPC_DSBH:
  3578 + GEN_LOAD_REG_TN(T1, rt);
  3579 + gen_op_dsbh();
  3580 + break;
  3581 + case OPC_DSHD:
  3582 + GEN_LOAD_REG_TN(T1, rt);
  3583 + gen_op_dshd();
  3584 + break;
  3585 + default: /* Invalid */
  3586 + MIPS_INVAL("dbshfl");
  3587 + generate_exception(ctx, EXCP_RI);
  3588 + break;
  3589 + }
  3590 + GEN_STORE_TN_REG(rd, T0);
  3591 +#endif
  3592 + default: /* Invalid */
  3593 + MIPS_INVAL("special3");
  3594 + generate_exception(ctx, EXCP_RI);
  3595 + break;
  3596 + }
  3597 + break;
  3598 + case OPC_REGIMM:
  3599 + op1 = MASK_REGIMM(ctx->opcode);
  3600 + switch (op1) {
  3601 + case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
  3602 + case OPC_BLTZAL ... OPC_BGEZALL:
  3603 + gen_compute_branch(ctx, op1, rs, -1, imm << 2);
2398 return; 3604 return;
2399 - case 0x08 ... 0x0C: /* Traps */  
2400 - case 0x0E:  
2401 - gen_trap(ctx, op1 | EXT_REGIMM, rs, -1, imm); 3605 + case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
  3606 + case OPC_TNEI:
  3607 + gen_trap(ctx, op1, rs, -1, imm);
  3608 + break;
  3609 + case OPC_SYNCI:
  3610 + /* treat as noop */
2402 break; 3611 break;
2403 default: /* Invalid */ 3612 default: /* Invalid */
2404 MIPS_INVAL("REGIMM"); 3613 MIPS_INVAL("REGIMM");
@@ -2406,48 +3615,78 @@ static void decode_opc (DisasContext *ctx) @@ -2406,48 +3615,78 @@ static void decode_opc (DisasContext *ctx)
2406 break; 3615 break;
2407 } 3616 }
2408 break; 3617 break;
2409 - case 0x10: /* CP0 opcode */  
2410 - op1 = ((ctx->opcode >> 21) & 0x1F); 3618 + case OPC_CP0:
  3619 + op1 = MASK_CP0(ctx->opcode);
2411 switch (op1) { 3620 switch (op1) {
2412 - case 0x00:  
2413 - case 0x04:  
2414 - gen_cp0(ctx, op1 | EXT_CP0, rt, rd); 3621 + case OPC_MFC0:
  3622 + case OPC_MTC0:
  3623 +#ifdef MIPS_HAS_MIPS64
  3624 + case OPC_DMFC0:
  3625 + case OPC_DMTC0:
  3626 +#endif
  3627 + gen_cp0(ctx, op1, rt, rd);
  3628 + break;
  3629 + case OPC_C0_FIRST ... OPC_C0_LAST:
  3630 + gen_cp0(ctx, MASK_C0(ctx->opcode), rt, rd);
  3631 + break;
  3632 + case OPC_MFMC0:
  3633 + op2 = MASK_MFMC0(ctx->opcode);
  3634 + switch (op2) {
  3635 + case OPC_DI:
  3636 + gen_op_di();
  3637 + /* Stop translation as we may have switched the execution mode */
  3638 + ctx->bstate = BS_STOP;
  3639 + break;
  3640 + case OPC_EI:
  3641 + gen_op_ei();
  3642 + /* Stop translation as we may have switched the execution mode */
  3643 + ctx->bstate = BS_STOP;
  3644 + break;
  3645 + default: /* Invalid */
  3646 + MIPS_INVAL("MFMC0");
  3647 + generate_exception(ctx, EXCP_RI);
  3648 + break;
  3649 + }
  3650 + GEN_STORE_TN_REG(rt, T0);
2415 break; 3651 break;
  3652 + /* Shadow registers (not implemented). */
  3653 + case OPC_RDPGPR:
  3654 + case OPC_WRPGPR:
2416 default: 3655 default:
2417 - gen_cp0(ctx, (ctx->opcode & 0x3F) | EXT_CP0, rt, rd); 3656 + generate_exception(ctx, EXCP_RI);
2418 break; 3657 break;
2419 } 3658 }
2420 break; 3659 break;
2421 - case 0x08 ... 0x0F: /* Arithmetic with immediate opcode */  
2422 - gen_arith_imm(ctx, op, rt, rs, imm);  
2423 - break;  
2424 - case 0x02 ... 0x03: /* Jump */  
2425 - offset = (int32_t)(ctx->opcode & 0x03FFFFFF) << 2;  
2426 - gen_compute_branch(ctx, op, rs, rt, offset);  
2427 - return;  
2428 - case 0x04 ... 0x07: /* Branch */  
2429 - case 0x14 ... 0x17:  
2430 - gen_compute_branch(ctx, op, rs, rt, imm << 2);  
2431 - return;  
2432 - case 0x20 ... 0x2E: /* Load and stores */  
2433 - case 0x30:  
2434 - case 0x38:  
2435 - gen_ldst(ctx, op, rt, rs, imm);  
2436 - break;  
2437 - case 0x2F: /* Cache operation */  
2438 - /* Treat as a noop */  
2439 - break;  
2440 - case 0x33: /* Prefetch */ 3660 + case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
  3661 + gen_arith_imm(ctx, op, rt, rs, imm);
  3662 + break;
  3663 + case OPC_J ... OPC_JAL: /* Jump */
  3664 + offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
  3665 + gen_compute_branch(ctx, op, rs, rt, offset);
  3666 + return;
  3667 + case OPC_BEQ ... OPC_BGTZ: /* Branch */
  3668 + case OPC_BEQL ... OPC_BGTZL:
  3669 + gen_compute_branch(ctx, op, rs, rt, imm << 2);
  3670 + return;
  3671 + case OPC_LB ... OPC_LWR: /* Load and stores */
  3672 + case OPC_SB ... OPC_SW:
  3673 + case OPC_SWR:
  3674 + case OPC_LL:
  3675 + case OPC_SC:
  3676 + gen_ldst(ctx, op, rt, rs, imm);
  3677 + break;
  3678 + case OPC_CACHE:
  3679 + /* Treat as a noop */
  3680 + break;
  3681 + case OPC_PREF:
2441 /* Treat as a noop */ 3682 /* Treat as a noop */
2442 break; 3683 break;
2443 - case 0x3F: /* HACK */  
2444 - break;  
2445 3684
2446 /* Floating point. */ 3685 /* Floating point. */
2447 - case 0x31: /* LWC1 */  
2448 - case 0x35: /* LDC1 */  
2449 - case 0x39: /* SWC1 */  
2450 - case 0x3D: /* SDC1 */ 3686 + case OPC_LWC1:
  3687 + case OPC_LDC1:
  3688 + case OPC_SWC1:
  3689 + case OPC_SDC1:
2451 #if defined(MIPS_USES_FPU) 3690 #if defined(MIPS_USES_FPU)
2452 save_cpu_state(ctx, 1); 3691 save_cpu_state(ctx, 1);
2453 gen_op_cp1_enabled(); 3692 gen_op_cp1_enabled();
@@ -2457,65 +3696,80 @@ static void decode_opc (DisasContext *ctx) @@ -2457,65 +3696,80 @@ static void decode_opc (DisasContext *ctx)
2457 #endif 3696 #endif
2458 break; 3697 break;
2459 3698
2460 - case 0x11: /* CP1 opcode */ 3699 + case OPC_CP1:
2461 #if defined(MIPS_USES_FPU) 3700 #if defined(MIPS_USES_FPU)
2462 save_cpu_state(ctx, 1); 3701 save_cpu_state(ctx, 1);
2463 gen_op_cp1_enabled(); 3702 gen_op_cp1_enabled();
2464 - op1 = ((ctx->opcode >> 21) & 0x1F); 3703 + op1 = MASK_CP1(ctx->opcode);
2465 switch (op1) { 3704 switch (op1) {
2466 - case 0x00: /* mfc1 */  
2467 - case 0x02: /* cfc1 */  
2468 - case 0x04: /* mtc1 */  
2469 - case 0x06: /* ctc1 */  
2470 - gen_cp1(ctx, op1 | EXT_CP1, rt, rd);  
2471 - break;  
2472 - case 0x08: /* bc */  
2473 - gen_compute_branch1(ctx, rt, imm << 2); 3705 + case OPC_MFC1:
  3706 + case OPC_CFC1:
  3707 + case OPC_MTC1:
  3708 + case OPC_CTC1:
  3709 + gen_cp1(ctx, op1, rt, rd);
  3710 + break;
  3711 + case OPC_BC1:
  3712 + gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2);
2474 return; 3713 return;
2475 - case 0x10: /* 16: fmt=single fp */  
2476 - case 0x11: /* 17: fmt=double fp */  
2477 - case 0x14: /* 20: fmt=32bit fixed */  
2478 - case 0x15: /* 21: fmt=64bit fixed */  
2479 - gen_farith(ctx, op1, rt, rd, sa, ctx->opcode & 0x3f); 3714 + case OPC_S_FMT:
  3715 + case OPC_D_FMT:
  3716 + case OPC_W_FMT:
  3717 + case OPC_L_FMT:
  3718 + gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa);
2480 break; 3719 break;
2481 default: 3720 default:
2482 generate_exception_err(ctx, EXCP_RI, 1); 3721 generate_exception_err(ctx, EXCP_RI, 1);
2483 break; 3722 break;
2484 } 3723 }
2485 - break;  
2486 #else 3724 #else
2487 generate_exception_err(ctx, EXCP_CpU, 1); 3725 generate_exception_err(ctx, EXCP_CpU, 1);
2488 #endif 3726 #endif
2489 break; 3727 break;
2490 3728
2491 /* COP2. */ 3729 /* COP2. */
2492 - case 0x32: /* LWC2 */  
2493 - case 0x36: /* LDC2 */  
2494 - case 0x3A: /* SWC2 */  
2495 - case 0x3E: /* SDC2 */  
2496 - case 0x12: /* CP2 opcode */  
2497 - /* Not implemented */ 3730 + case OPC_LWC2:
  3731 + case OPC_LDC2:
  3732 + case OPC_SWC2:
  3733 + case OPC_SDC2:
  3734 + case OPC_CP2:
  3735 + /* COP2: Not implemented. */
2498 generate_exception_err(ctx, EXCP_CpU, 2); 3736 generate_exception_err(ctx, EXCP_CpU, 2);
2499 break; 3737 break;
2500 3738
2501 - case 0x13: /* CP3 opcode */ 3739 + case OPC_CP3:
  3740 + gen_op_cp1_enabled();
  3741 + op1 = MASK_CP3(ctx->opcode);
  3742 + switch (op1) {
2502 /* Not implemented */ 3743 /* Not implemented */
2503 - generate_exception_err(ctx, EXCP_CpU, 3); 3744 + default:
  3745 + generate_exception_err(ctx, EXCP_RI, 1);
  3746 + break;
  3747 + }
2504 break; 3748 break;
2505 3749
2506 -#if defined (TARGET_MIPS64)  
2507 - case 0x18 ... 0x1B:  
2508 - case 0x27:  
2509 - case 0x34:  
2510 - case 0x37:  
2511 - /* MIPS64 opcodes */ 3750 +#ifdef MIPS_HAS_MIPS64
  3751 + /* MIPS64 opcodes */
  3752 + case OPC_LWU:
  3753 + case OPC_LDL ... OPC_LDR:
  3754 + case OPC_SDL ... OPC_SDR:
  3755 + case OPC_LLD:
  3756 + case OPC_LD:
  3757 + case OPC_SCD:
  3758 + case OPC_SD:
  3759 + gen_ldst(ctx, op, rt, rs, imm);
  3760 + break;
  3761 + case OPC_DADDI ... OPC_DADDIU:
  3762 + gen_arith_imm(ctx, op, rt, rs, imm);
  3763 + break;
2512 #endif 3764 #endif
2513 -#if defined (MIPS_HAS_JALX)  
2514 - case 0x1D:  
2515 - /* JALX: not implemented */ 3765 +#ifdef MIPS_HAS_MIPS16
  3766 + case OPC_JALX:
  3767 + /* MIPS16: Not implemented. */
  3768 +#endif
  3769 +#ifdef MIPS_HAS_MDMX
  3770 + case OPC_MDMX:
  3771 + /* MDMX: Not implemented. */
2516 #endif 3772 #endif
2517 - case 0x1E:  
2518 - /* ASE specific */  
2519 default: /* Invalid */ 3773 default: /* Invalid */
2520 MIPS_INVAL(""); 3774 MIPS_INVAL("");
2521 generate_exception(ctx, EXCP_RI); 3775 generate_exception(ctx, EXCP_RI);
@@ -2707,7 +3961,6 @@ int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) @@ -2707,7 +3961,6 @@ int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
2707 return gen_intermediate_code_internal(env, tb, 1); 3961 return gen_intermediate_code_internal(env, tb, 1);
2708 } 3962 }
2709 3963
2710 -#ifdef MIPS_USES_FPU  
2711 void fpu_dump_state(CPUState *env, FILE *f, 3964 void fpu_dump_state(CPUState *env, FILE *f,
2712 int (*fpu_fprintf)(FILE *f, const char *fmt, ...), 3965 int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
2713 int flags) 3966 int flags)
@@ -2721,19 +3974,19 @@ void fpu_dump_state(CPUState *env, FILE *f, @@ -2721,19 +3974,19 @@ void fpu_dump_state(CPUState *env, FILE *f,
2721 3974
2722 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d\n", 3975 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d\n",
2723 env->fcr0, env->fcr31, 3976 env->fcr0, env->fcr31,
2724 - (env->CP0_Status & (1<<CP0St_FR)) != 0); 3977 + (env->CP0_Status & (1 << CP0St_FR)) != 0);
2725 fpu_fprintf(f, "FT0: "); printfpr(&env->ft0); 3978 fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
2726 fpu_fprintf(f, "FT1: "); printfpr(&env->ft1); 3979 fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
2727 fpu_fprintf(f, "FT2: "); printfpr(&env->ft2); 3980 fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
2728 - for(i=0; i < 32; i+=2) {  
2729 - fpu_fprintf(f, "f%02d: ", i); 3981 + for(i = 0; i < 32; i += 2) {
  3982 + fpu_fprintf(f, "%s: ", fregnames[i]);
2730 printfpr(FPR(env, i)); 3983 printfpr(FPR(env, i));
2731 } 3984 }
2732 3985
2733 #undef printfpr 3986 #undef printfpr
2734 } 3987 }
2735 3988
2736 -void dump_fpu(CPUState *env) 3989 +void dump_fpu (CPUState *env)
2737 { 3990 {
2738 if (loglevel) { 3991 if (loglevel) {
2739 fprintf(logfile, "pc=0x%08x HI=0x%08x LO=0x%08x ds %04x %08x %d\n", 3992 fprintf(logfile, "pc=0x%08x HI=0x%08x LO=0x%08x ds %04x %08x %d\n",
@@ -2741,7 +3994,6 @@ void dump_fpu(CPUState *env) @@ -2741,7 +3994,6 @@ void dump_fpu(CPUState *env)
2741 fpu_dump_state(env, logfile, fprintf, 0); 3994 fpu_dump_state(env, logfile, fprintf, 0);
2742 } 3995 }
2743 } 3996 }
2744 -#endif /* MIPS_USES_FPU */  
2745 3997
2746 void cpu_dump_state (CPUState *env, FILE *f, 3998 void cpu_dump_state (CPUState *env, FILE *f,
2747 int (*cpu_fprintf)(FILE *f, const char *fmt, ...), 3999 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
@@ -2772,9 +4024,8 @@ void cpu_dump_state (CPUState *env, FILE *f, @@ -2772,9 +4024,8 @@ void cpu_dump_state (CPUState *env, FILE *f,
2772 c0_status, env->CP0_Cause, env->CP0_EPC); 4024 c0_status, env->CP0_Cause, env->CP0_EPC);
2773 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%08x\n", 4025 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%08x\n",
2774 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr); 4026 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
2775 -#ifdef MIPS_USES_FPU  
2776 - fpu_dump_state(env, f, cpu_fprintf, flags);  
2777 -#endif 4027 + if (c0_status & (1 << CP0St_CU1))
  4028 + fpu_dump_state(env, f, cpu_fprintf, flags);
2778 } 4029 }
2779 4030
2780 CPUMIPSState *cpu_mips_init (void) 4031 CPUMIPSState *cpu_mips_init (void)
@@ -2802,16 +4053,12 @@ void cpu_reset (CPUMIPSState *env) @@ -2802,16 +4053,12 @@ void cpu_reset (CPUMIPSState *env)
2802 env->tlb_in_use = MIPS_TLB_NB; 4053 env->tlb_in_use = MIPS_TLB_NB;
2803 #endif 4054 #endif
2804 env->CP0_Wired = 0; 4055 env->CP0_Wired = 0;
  4056 + /* SMP not implemented */
  4057 + env->CP0_EBase = 0x80000000;
2805 env->CP0_Config0 = MIPS_CONFIG0; 4058 env->CP0_Config0 = MIPS_CONFIG0;
2806 -#if defined (MIPS_CONFIG1)  
2807 - env->CP0_Config1 = MIPS_CONFIG1;  
2808 -#endif  
2809 -#if defined (MIPS_CONFIG2)  
2810 - env->CP0_Config2 = MIPS_CONFIG2;  
2811 -#endif  
2812 -#if defined (MIPS_CONFIG3)  
2813 - env->CP0_Config3 = MIPS_CONFIG3;  
2814 -#endif 4059 + env->CP0_Config1 = MIPS_CONFIG1;
  4060 + env->CP0_Config2 = MIPS_CONFIG2;
  4061 + env->CP0_Config3 = MIPS_CONFIG3;
2815 env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV); 4062 env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV);
2816 env->CP0_WatchLo = 0; 4063 env->CP0_WatchLo = 0;
2817 env->hflags = MIPS_HFLAG_ERL; 4064 env->hflags = MIPS_HFLAG_ERL;
@@ -2825,4 +4072,7 @@ void cpu_reset (CPUMIPSState *env) @@ -2825,4 +4072,7 @@ void cpu_reset (CPUMIPSState *env)
2825 #ifdef MIPS_USES_FPU 4072 #ifdef MIPS_USES_FPU
2826 env->fcr0 = MIPS_FCR0; 4073 env->fcr0 = MIPS_FCR0;
2827 #endif 4074 #endif
  4075 + /* XXX some guesswork here, values are CPU specific */
  4076 + env->SYNCI_Step = 16;
  4077 + env->CCRes = 2;
2828 } 4078 }