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 99 #endif
100 100 uint32_t CP0_index;
101 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 105 uint32_t CP0_PageMask;
  106 + uint32_t CP0_PageGrain;
106 107 uint32_t CP0_Wired;
  108 + uint32_t CP0_HWREna;
107 109 uint32_t CP0_BadVAddr;
108 110 uint32_t CP0_Count;
109   - uint32_t CP0_EntryHi;
  111 + uint64_t CP0_EntryHi;
110 112 uint32_t CP0_Compare;
111 113 uint32_t CP0_Status;
112 114 #define CP0St_CU3 31
... ... @@ -116,19 +118,36 @@ struct CPUMIPSState {
116 118 #define CP0St_RP 27
117 119 #define CP0St_FR 26
118 120 #define CP0St_RE 25
  121 +#define CP0St_MX 24
  122 +#define CP0St_PX 23
119 123 #define CP0St_BEV 22
120 124 #define CP0St_TS 21
121 125 #define CP0St_SR 20
122 126 #define CP0St_NMI 19
123 127 #define CP0St_IM 8
  128 +#define CP0St_KX 7
  129 +#define CP0St_SX 6
  130 +#define CP0St_UX 5
124 131 #define CP0St_UM 4
  132 +#define CP0St_R0 3
125 133 #define CP0St_ERL 2
126 134 #define CP0St_EXL 1
127 135 #define CP0St_IE 0
  136 + uint32_t CP0_IntCtl;
  137 + uint32_t CP0_SRSCtl;
128 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 144 #define CP0Ca_IV 23
  145 +#define CP0Ca_WP 22
  146 +#define CP0Ca_IP 8
  147 +#define CP0Ca_EC 2
130 148 uint32_t CP0_EPC;
131 149 uint32_t CP0_PRid;
  150 + uint32_t CP0_EBase;
132 151 uint32_t CP0_Config0;
133 152 #define CP0C0_M 31
134 153 #define CP0C0_K23 28
... ... @@ -140,8 +159,10 @@ struct CPUMIPSState {
140 159 #define CP0C0_AT 13
141 160 #define CP0C0_AR 10
142 161 #define CP0C0_MT 7
  162 +#define CP0C0_VI 3
143 163 #define CP0C0_K0 0
144 164 uint32_t CP0_Config1;
  165 +#define CP0C1_M 31
145 166 #define CP0C1_MMU 25
146 167 #define CP0C1_IS 22
147 168 #define CP0C1_IL 19
... ... @@ -149,14 +170,38 @@ struct CPUMIPSState {
149 170 #define CP0C1_DS 13
150 171 #define CP0C1_DL 10
151 172 #define CP0C1_DA 7
  173 +#define CP0C1_C2 6
  174 +#define CP0C1_MD 5
152 175 #define CP0C1_PC 4
153 176 #define CP0C1_WR 3
154 177 #define CP0C1_CA 2
155 178 #define CP0C1_EP 1
156 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 200 uint32_t CP0_LLAddr;
158 201 uint32_t CP0_WatchLo;
159 202 uint32_t CP0_WatchHi;
  203 + uint32_t CP0_XContext;
  204 + uint32_t CP0_Framemask;
160 205 uint32_t CP0_Debug;
161 206 #define CPDB_DBD 31
162 207 #define CP0DB_DM 30
... ... @@ -177,8 +222,11 @@ struct CPUMIPSState {
177 222 #define CP0DB_DBp 1
178 223 #define CP0DB_DSS 0
179 224 uint32_t CP0_DEPC;
  225 + uint32_t CP0_Performance0;
180 226 uint32_t CP0_TagLo;
181 227 uint32_t CP0_DataLo;
  228 + uint32_t CP0_TagHi;
  229 + uint32_t CP0_DataHi;
182 230 uint32_t CP0_ErrorEPC;
183 231 uint32_t CP0_DESAVE;
184 232 /* Qemu */
... ... @@ -211,6 +259,9 @@ struct CPUMIPSState {
211 259  
212 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 265 CPU_COMMON
215 266  
216 267 int ram_size;
... ...
target-mips/exec.h
... ... @@ -68,6 +68,7 @@ void do_msubu (void);
68 68 #endif
69 69 void do_mfc0_random(void);
70 70 void do_mfc0_count(void);
  71 +void do_mtc0_entryhi(uint32_t in);
71 72 void do_mtc0_status_debug(uint32_t old, uint32_t val);
72 73 void do_mtc0_status_irqraise_debug(void);
73 74 void do_tlbwi (void);
... ...
target-mips/helper.c
... ... @@ -302,15 +302,9 @@ void do_interrupt (CPUState *env)
302 302 #endif
303 303 env->CP0_Wired = 0;
304 304 env->CP0_Config0 = MIPS_CONFIG0;
305   -#if defined (MIPS_CONFIG1)
306 305 env->CP0_Config1 = MIPS_CONFIG1;
307   -#endif
308   -#if defined (MIPS_CONFIG2)
309 306 env->CP0_Config2 = MIPS_CONFIG2;
310   -#endif
311   -#if defined (MIPS_CONFIG3)
312 307 env->CP0_Config3 = MIPS_CONFIG3;
313   -#endif
314 308 env->CP0_WatchLo = 0;
315 309 env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV);
316 310 goto set_error_EPC;
... ...
target-mips/mips-defs.h
... ... @@ -29,26 +29,44 @@
29 29 * Define a major version 1, minor version 0.
30 30 */
31 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 38 #ifdef TARGET_WORDS_BIGENDIAN
37 39 #define MIPS_CONFIG0 (MIPS_CONFIG0_1 | (1 << CP0C0_BE))
38 40 #else
39 41 #define MIPS_CONFIG0 MIPS_CONFIG0_1
40 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 70 #elif (MIPS_CPU == MIPS_R4Kp)
53 71 /* 32 bits target */
54 72 #define TARGET_LONG_BITS 32
... ... @@ -60,7 +78,7 @@
60 78 #define MIPS_USES_R4K_FPM
61 79 #else
62 80 #error "MIPS CPU not defined"
63   -/* Remainder for other flags */
  81 +/* Reminder for other flags */
64 82 //#define TARGET_MIPS64
65 83 //#define MIPS_USES_FPU
66 84 #endif
... ...
target-mips/op.c
... ... @@ -437,6 +437,18 @@ void op_srl (void)
437 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 452 void op_sllv (void)
441 453 {
442 454 T0 = T1 << (T0 & 0x1F);
... ... @@ -455,6 +467,19 @@ void op_srlv (void)
455 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 483 void op_clo (void)
459 484 {
460 485 int n;
... ... @@ -602,6 +627,20 @@ void op_movz (void)
602 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 644 /* Tests */
606 645 #define OP_COND(name, cond) \
607 646 void glue(op_, name) (void) \
... ... @@ -625,28 +664,32 @@ OP_COND(gtz, (int32_t)T0 &gt; 0);
625 664 OP_COND(lez, (int32_t)T0 <= 0);
626 665 OP_COND(ltz, (int32_t)T0 < 0);
627 666  
628   -/* Branchs */
  667 +/* Branches */
629 668 //#undef USE_DIRECT_JUMP
630 669  
631 670 void OPPROTO op_goto_tb0(void)
632 671 {
633 672 GOTO_TB(op_goto_tb0, PARAM1, 0);
  673 + RETURN();
634 674 }
635 675  
636 676 void OPPROTO op_goto_tb1(void)
637 677 {
638 678 GOTO_TB(op_goto_tb1, PARAM1, 1);
  679 + RETURN();
639 680 }
640 681  
641 682 /* Branch to register */
642 683 void op_save_breg_target (void)
643 684 {
644 685 env->btarget = T2;
  686 + RETURN();
645 687 }
646 688  
647 689 void op_restore_breg_target (void)
648 690 {
649 691 T2 = env->btarget;
  692 + RETURN();
650 693 }
651 694  
652 695 void op_breg (void)
... ... @@ -724,12 +767,24 @@ void op_mfc0_pagemask (void)
724 767 RETURN();
725 768 }
726 769  
  770 +void op_mfc0_pagegrain (void)
  771 +{
  772 + T0 = env->CP0_PageGrain;
  773 + RETURN();
  774 +}
  775 +
727 776 void op_mfc0_wired (void)
728 777 {
729 778 T0 = env->CP0_Wired;
730 779 RETURN();
731 780 }
732 781  
  782 +void op_mfc0_hwrena (void)
  783 +{
  784 + T0 = env->CP0_HWREna;
  785 + RETURN();
  786 +}
  787 +
733 788 void op_mfc0_badvaddr (void)
734 789 {
735 790 T0 = env->CP0_BadVAddr;
... ... @@ -766,6 +821,18 @@ void op_mfc0_status (void)
766 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 836 void op_mfc0_cause (void)
770 837 {
771 838 T0 = env->CP0_Cause;
... ... @@ -784,6 +851,12 @@ void op_mfc0_prid (void)
784 851 RETURN();
785 852 }
786 853  
  854 +void op_mfc0_ebase (void)
  855 +{
  856 + T0 = env->CP0_EBase;
  857 + RETURN();
  858 +}
  859 +
787 860 void op_mfc0_config0 (void)
788 861 {
789 862 T0 = env->CP0_Config0;
... ... @@ -796,24 +869,48 @@ void op_mfc0_config1 (void)
796 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 884 void op_mfc0_lladdr (void)
800 885 {
801 886 T0 = env->CP0_LLAddr >> 4;
802 887 RETURN();
803 888 }
804 889  
805   -void op_mfc0_watchlo (void)
  890 +void op_mfc0_watchlo0 (void)
806 891 {
807 892 T0 = env->CP0_WatchLo;
808 893 RETURN();
809 894 }
810 895  
811   -void op_mfc0_watchhi (void)
  896 +void op_mfc0_watchhi0 (void)
812 897 {
813 898 T0 = env->CP0_WatchHi;
814 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 914 void op_mfc0_debug (void)
818 915 {
819 916 T0 = env->CP0_Debug;
... ... @@ -828,6 +925,12 @@ void op_mfc0_depc (void)
828 925 RETURN();
829 926 }
830 927  
  928 +void op_mfc0_performance0 (void)
  929 +{
  930 + T0 = env->CP0_Performance0;
  931 + RETURN();
  932 +}
  933 +
831 934 void op_mfc0_taglo (void)
832 935 {
833 936 T0 = env->CP0_TagLo;
... ... @@ -840,6 +943,18 @@ void op_mfc0_datalo (void)
840 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 958 void op_mfc0_errorepc (void)
844 959 {
845 960 T0 = env->CP0_ErrorEPC;
... ... @@ -854,37 +969,57 @@ void op_mfc0_desave (void)
854 969  
855 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 973 RETURN();
859 974 }
860 975  
861 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 981 RETURN();
865 982 }
866 983  
867 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 989 RETURN();
871 990 }
872 991  
873 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 995 RETURN();
877 996 }
878 997  
879 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 1011 RETURN();
883 1012 }
884 1013  
885 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 1023 RETURN();
889 1024 }
890 1025  
... ... @@ -898,6 +1033,8 @@ void op_mtc0_entryhi (void)
898 1033 {
899 1034 uint32_t old, val;
900 1035  
  1036 + /* 1k pages not implemented */
  1037 + /* Ignore MIPS64 TLB for now */
901 1038 val = T0 & 0xFFFFE0FF;
902 1039 old = env->CP0_EntryHi;
903 1040 env->CP0_EntryHi = val;
... ... @@ -950,6 +1087,20 @@ void op_mtc0_status (void)
950 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 1104 void op_mtc0_cause (void)
954 1105 {
955 1106 uint32_t val, old;
... ... @@ -960,7 +1111,6 @@ void op_mtc0_cause (void)
960 1111 #if 0
961 1112 {
962 1113 int i, mask;
963   -
964 1114 /* Check if we ever asserted a software IRQ */
965 1115 for (i = 0; i < 2; i++) {
966 1116 mask = 0x100 << i;
... ... @@ -978,28 +1128,56 @@ void op_mtc0_epc (void)
978 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 1139 void op_mtc0_config0 (void)
982 1140 {
983 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 1144 #else
986   - env->CP0_Config0 = (env->CP0_Config0 & 0xFE17FF80) | (T0 & 0x00000001);
  1145 + env->CP0_Config0 = (env->CP0_Config0 & 0xFE17FF88) | (T0 & 0x00000001);
987 1146 #endif
988 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 1159 env->CP0_WatchLo = T0;
994 1160 RETURN();
995 1161 }
996 1162  
997   -void op_mtc0_watchhi (void)
  1163 +void op_mtc0_watchhi0 (void)
998 1164 {
999 1165 env->CP0_WatchHi = T0 & 0x40FF0FF8;
1000 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 1181 void op_mtc0_debug (void)
1004 1182 {
1005 1183 env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120);
... ... @@ -1016,12 +1194,36 @@ void op_mtc0_depc (void)
1016 1194 RETURN();
1017 1195 }
1018 1196  
  1197 +void op_mtc0_performance0 (void)
  1198 +{
  1199 + env->CP0_Performance0 = T0; /* XXX */
  1200 + RETURN();
  1201 +}
  1202 +
1019 1203 void op_mtc0_taglo (void)
1020 1204 {
1021 1205 env->CP0_TagLo = T0 & 0xFFFFFCF6;
1022 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 1227 void op_mtc0_errorepc (void)
1026 1228 {
1027 1229 env->CP0_ErrorEPC = T0;
... ... @@ -1422,6 +1624,42 @@ void op_tlbr (void)
1422 1624 void op_pmon (void)
1423 1625 {
1424 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 1665 void op_trap (void)
... ... @@ -1434,12 +1672,14 @@ void op_trap (void)
1434 1672  
1435 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 1679 void op_set_lladdr (void)
1441 1680 {
1442 1681 env->CP0_LLAddr = T2;
  1682 + RETURN();
1443 1683 }
1444 1684  
1445 1685 void debug_eret (void);
... ... @@ -1456,12 +1696,50 @@ void op_eret (void)
1456 1696 env->CP0_Status &= ~(1 << CP0St_EXL);
1457 1697 }
1458 1698 env->CP0_LLAddr = 1;
  1699 + RETURN();
1459 1700 }
1460 1701  
1461 1702 void op_deret (void)
1462 1703 {
1463 1704 CALL_FROM_TB0(debug_eret);
1464 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 1745 void op_save_state (void)
... ... @@ -1491,10 +1769,62 @@ void op_raise_exception_err (void)
1491 1769 void op_exit_tb (void)
1492 1770 {
1493 1771 EXIT_TB();
  1772 + RETURN();
1494 1773 }
1495 1774  
1496 1775 void op_wait (void)
1497 1776 {
1498 1777 env->halted = 1;
1499 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 153  
154 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 164 void do_tlbwi (void)
... ...
target-mips/translate.c
... ... @@ -50,184 +50,313 @@ static uint32_t *gen_opparam_ptr;
50 50  
51 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 56 enum {
63 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 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 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 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 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 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 131 /* MIPS special opcodes */
  132 +#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
  133 +
123 134 enum {
124 135 /* Shifts */
125   - OPC_SLL = 0x00 | EXT_SPECIAL,
  136 + OPC_SLL = 0x00 | OPC_SPECIAL,
126 137 /* NOP is SLL r0, r0, 0 */
127 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 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 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 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 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 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 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 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 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 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 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 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 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 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 361 const unsigned char *regnames[] =
233 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 389 GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
261 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 393 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
266 394 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
267 395 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
... ... @@ -344,8 +472,6 @@ static inline void gen_cmp_ ## fmt(int n) \
344 472 FOP_CONDS(d)
345 473 FOP_CONDS(s)
346 474  
347   -#endif
348   -
349 475 typedef struct DisasContext {
350 476 struct TranslationBlock *tb;
351 477 target_ulong pc, saved_pc;
... ... @@ -410,9 +536,7 @@ do { \
410 536 } \
411 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 540 do { \
417 541 glue(gen_op_load_fpr_, FTn)(Fn); \
418 542 } while (0)
... ... @@ -422,8 +546,6 @@ do { \
422 546 glue(gen_op_store_fpr_, FTn)(Fn); \
423 547 } while (0)
424 548  
425   -#endif
426   -
427 549 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
428 550 {
429 551 #if defined MIPS_DEBUG_DISAS
... ... @@ -487,7 +609,7 @@ static GenOpFunc *gen_op_s##width[] = { \
487 609 }
488 610 #endif
489 611  
490   -#ifdef TARGET_MIPS64
  612 +#ifdef MIPS_HAS_MIPS64
491 613 OP_LD_TABLE(d);
492 614 OP_LD_TABLE(dl);
493 615 OP_LD_TABLE(dr);
... ... @@ -510,18 +632,16 @@ OP_LD_TABLE(bu);
510 632 OP_ST_TABLE(b);
511 633 OP_LD_TABLE(l);
512 634 OP_ST_TABLE(c);
513   -#ifdef MIPS_USES_FPU
514 635 OP_LD_TABLE(wc1);
515 636 OP_ST_TABLE(wc1);
516 637 OP_LD_TABLE(dc1);
517 638 OP_ST_TABLE(dc1);
518   -#endif
519 639  
520 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 642 int base, int16_t offset)
523 643 {
524   - const unsigned char *opn = "unk";
  644 + const char *opn = "unk";
525 645  
526 646 if (base == 0) {
527 647 GEN_LOAD_IMM_TN(T0, offset);
... ... @@ -536,23 +656,27 @@ static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt,
536 656 * memory access
537 657 */
538 658 switch (opc) {
539   -#if defined(TARGET_MIPS64)
  659 +#ifdef MIPS_HAS_MIPS64
540 660 case OPC_LD:
541   -#if defined (MIPS_HAS_UNALIGNED_LS)
542   - case OPC_ULD:
543   -#endif
544 661 op_ldst(ld);
545 662 GEN_STORE_TN_REG(rt, T0);
546 663 opn = "ld";
547 664 break;
  665 + case OPC_LLD:
  666 + op_ldst(lld);
  667 + GEN_STORE_TN_REG(rt, T0);
  668 + opn = "lld";
  669 + break;
548 670 case OPC_SD:
549   -#if defined (MIPS_HAS_UNALIGNED_LS)
550   - case OPC_USD:
551   -#endif
552 671 GEN_LOAD_REG_TN(T1, rt);
553 672 op_ldst(sd);
554 673 opn = "sd";
555 674 break;
  675 + case OPC_SCD:
  676 + GEN_LOAD_REG_TN(T1, rt);
  677 + op_ldst(scd);
  678 + opn = "scd";
  679 + break;
556 680 case OPC_LDL:
557 681 op_ldst(ldl);
558 682 GEN_STORE_TN_REG(rt, T0);
... ... @@ -575,9 +699,6 @@ static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt,
575 699 break;
576 700 #endif
577 701 case OPC_LW:
578   -#if defined (MIPS_HAS_UNALIGNED_LS)
579   - case OPC_ULW:
580   -#endif
581 702 op_ldst(lw);
582 703 GEN_STORE_TN_REG(rt, T0);
583 704 opn = "lw";
... ... @@ -588,33 +709,21 @@ static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt,
588 709 opn = "lwu";
589 710 break;
590 711 case OPC_SW:
591   -#if defined (MIPS_HAS_UNALIGNED_LS)
592   - case OPC_USW:
593   -#endif
594 712 GEN_LOAD_REG_TN(T1, rt);
595 713 op_ldst(sw);
596 714 opn = "sw";
597 715 break;
598 716 case OPC_LH:
599   -#if defined (MIPS_HAS_UNALIGNED_LS)
600   - case OPC_ULH:
601   -#endif
602 717 op_ldst(lh);
603 718 GEN_STORE_TN_REG(rt, T0);
604 719 opn = "lh";
605 720 break;
606 721 case OPC_SH:
607   -#if defined (MIPS_HAS_UNALIGNED_LS)
608   - case OPC_USH:
609   -#endif
610 722 GEN_LOAD_REG_TN(T1, rt);
611 723 op_ldst(sh);
612 724 opn = "sh";
613 725 break;
614 726 case OPC_LHU:
615   -#if defined (MIPS_HAS_UNALIGNED_LS)
616   - case OPC_ULHU:
617   -#endif
618 727 op_ldst(lhu);
619 728 GEN_STORE_TN_REG(rt, T0);
620 729 opn = "lhu";
... ... @@ -675,13 +784,11 @@ static void gen_ldst (DisasContext *ctx, uint16_t opc, int rt,
675 784 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
676 785 }
677 786  
678   -#ifdef MIPS_USES_FPU
679   -
680 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 789 int base, int16_t offset)
683 790 {
684   - const unsigned char *opn = "unk";
  791 + const char *opn = "unk";
685 792  
686 793 if (base == 0) {
687 794 GEN_LOAD_IMM_TN(T0, offset);
... ... @@ -718,21 +825,20 @@ static void gen_flt_ldst (DisasContext *ctx, uint16_t opc, int ft,
718 825 break;
719 826 default:
720 827 MIPS_INVAL("float load/store");
721   - generate_exception(ctx, EXCP_CpU);
  828 + generate_exception_err(ctx, EXCP_CpU, 1);
722 829 return;
723 830 }
724 831 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
725 832 }
726   -#endif
727 833  
728 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 836 int rs, int16_t imm)
731 837 {
732 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 842 /* if no destination, treat it as a NOP
737 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 846 return;
741 847 }
742 848 if (opc == OPC_ADDI || opc == OPC_ADDIU ||
  849 + opc == OPC_DADDI || opc == OPC_DADDIU ||
743 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 852 else
746 853 uimm = (uint16_t)imm;
747 854 if (opc != OPC_LUI) {
... ... @@ -761,6 +868,17 @@ static void gen_arith_imm (DisasContext *ctx, uint16_t opc, int rt,
761 868 gen_op_add();
762 869 opn = "addiu";
763 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 882 case OPC_SLTI:
765 883 gen_op_lt();
766 884 opn = "slti";
... ... @@ -793,9 +911,50 @@ static void gen_arith_imm (DisasContext *ctx, uint16_t opc, int rt,
793 911 opn = "sra";
794 912 break;
795 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 956 break;
  957 +#endif
799 958 default:
800 959 MIPS_INVAL("imm arith");
801 960 generate_exception(ctx, EXCP_RI);
... ... @@ -806,12 +965,13 @@ static void gen_arith_imm (DisasContext *ctx, uint16_t opc, int rt,
806 965 }
807 966  
808 967 /* Arithmetic */
809   -static void gen_arith (DisasContext *ctx, uint16_t opc,
  968 +static void gen_arith (DisasContext *ctx, uint32_t opc,
810 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 975 /* if no destination, treat it as a NOP
816 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 999 gen_op_sub();
840 1000 opn = "subu";
841 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 1022 case OPC_SLT:
843 1023 gen_op_lt();
844 1024 opn = "slt";
... ... @@ -884,9 +1064,33 @@ static void gen_arith (DisasContext *ctx, uint16_t opc,
884 1064 opn = "srav";
885 1065 break;
886 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 1092 break;
  1093 +#endif
890 1094 default:
891 1095 MIPS_INVAL("arith");
892 1096 generate_exception(ctx, EXCP_RI);
... ... @@ -898,9 +1102,9 @@ static void gen_arith (DisasContext *ctx, uint16_t opc,
898 1102 }
899 1103  
900 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 1109 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
906 1110 /* Treat as a NOP */
... ... @@ -936,10 +1140,10 @@ static void gen_HILO (DisasContext *ctx, uint16_t opc, int reg)
936 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 1144 int rs, int rt)
941 1145 {
942   - const unsigned char *opn = "unk";
  1146 + const char *opn = "unk";
943 1147  
944 1148 GEN_LOAD_REG_TN(T0, rs);
945 1149 GEN_LOAD_REG_TN(T1, rt);
... ... @@ -960,6 +1164,24 @@ static void gen_muldiv (DisasContext *ctx, uint16_t opc,
960 1164 gen_op_multu();
961 1165 opn = "multu";
962 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 1185 case OPC_MADD:
964 1186 gen_op_madd();
965 1187 opn = "madd";
... ... @@ -984,10 +1206,10 @@ static void gen_muldiv (DisasContext *ctx, uint16_t opc,
984 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 1210 int rd, int rs)
989 1211 {
990   - const unsigned char *opn = "unk";
  1212 + const char *opn = "unk";
991 1213 if (rd == 0) {
992 1214 /* Treat as a NOP */
993 1215 MIPS_DEBUG("NOP");
... ... @@ -996,15 +1218,23 @@ static void gen_cl (DisasContext *ctx, uint16_t opc,
996 1218 GEN_LOAD_REG_TN(T0, rs);
997 1219 switch (opc) {
998 1220 case OPC_CLO:
999   - /* CLO */
1000 1221 gen_op_clo();
1001 1222 opn = "clo";
1002 1223 break;
1003 1224 case OPC_CLZ:
1004   - /* CLZ */
1005 1225 gen_op_clz();
1006 1226 opn = "clz";
1007 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 1238 default:
1009 1239 MIPS_INVAL("CLx");
1010 1240 generate_exception(ctx, EXCP_RI);
... ... @@ -1015,7 +1245,7 @@ static void gen_cl (DisasContext *ctx, uint16_t opc,
1015 1245 }
1016 1246  
1017 1247 /* Traps */
1018   -static void gen_trap (DisasContext *ctx, uint16_t opc,
  1248 +static void gen_trap (DisasContext *ctx, uint32_t opc,
1019 1249 int rs, int rt, int16_t imm)
1020 1250 {
1021 1251 int cond;
... ... @@ -1130,7 +1360,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1130 1360 }
1131 1361  
1132 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 1364 int rs, int rt, int32_t offset)
1135 1365 {
1136 1366 target_ulong btarget;
... ... @@ -1180,8 +1410,9 @@ static void gen_compute_branch (DisasContext *ctx, uint16_t opc,
1180 1410 case OPC_JR:
1181 1411 case OPC_JALR:
1182 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 1416 generate_exception(ctx, EXCP_RI);
1186 1417 return;
1187 1418 }
... ... @@ -1348,80 +1579,342 @@ static void gen_compute_branch (DisasContext *ctx, uint16_t opc,
1348 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 1639 /* CP0 (MMU and control) */
1352 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 1644 switch (reg) {
1361 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 1666 break;
1365 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 1704 break;
1369 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 1742 break;
1373 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 1752 break;
1378 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 1766 break;
1382 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 1780 break;
1386 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 1810 break;
1390 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 1820 break;
1394 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 1830 break;
1398 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 1841 break;
1402 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 1851 break;
1406 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 1862 break;
1410 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 1884 break;
1414 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 1894 break;
1418 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 1904 break;
1422 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 1918 break;
1426 1919 case 16:
1427 1920 switch (sel) {
... ... @@ -1433,91 +1926,285 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1433 1926 gen_op_mfc0_config1();
1434 1927 rn = "Config1";
1435 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 1938 default:
1437   - rn = "Unknown config register";
1438 1939 goto die;
1439 1940 }
1440 1941 break;
1441 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 1951 break;
1445 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 1989 break;
1449 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 2027 break;
1453 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 2038 break;
1458 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 2049 break;
1462 2050 case 22:
1463   -// gen_op_mfc0_diagnostic();
1464   - rn = "'Diagnostic";
1465   - break;
  2051 + /* ignored */
  2052 + rn = "'Diagnostic"; /* implementation dependent */
  2053 + break;
1466 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 2079 break;
1470 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 2089 break;
1474 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 2127 break;
1478 2128 case 26:
1479   -// gen_op_mfc0_ecc();
1480   - rn = "ECC";
1481   - break;
  2129 + rn = "ECC";
  2130 + break;
1482 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 2140 break;
1486 2141 case 28:
1487 2142 switch (sel) {
1488 2143 case 0:
  2144 + case 2:
  2145 + case 4:
  2146 + case 6:
1489 2147 gen_op_mfc0_taglo();
1490 2148 rn = "TagLo";
1491 2149 break;
1492 2150 case 1:
  2151 + case 3:
  2152 + case 5:
  2153 + case 7:
1493 2154 gen_op_mfc0_datalo();
1494 2155 rn = "DataLo";
1495 2156 break;
1496 2157 default:
1497   - rn = "unknown sel";
1498 2158 goto die;
1499 2159 }
1500 2160 break;
1501 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 2180 break;
1505 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 2190 break;
1509 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 2200 break;
1513 2201 default:
1514   - rn = "unknown";
1515 2202 goto die;
1516 2203 }
1517 2204 #if defined MIPS_DEBUG_DISAS
1518 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 2209 #endif
1523 2210 return;
... ... @@ -1525,8 +2212,8 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1525 2212 die:
1526 2213 #if defined MIPS_DEBUG_DISAS
1527 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 2218 #endif
1532 2219 generate_exception(ctx, EXCP_RI);
... ... @@ -1534,167 +2221,583 @@ die:
1534 2221  
1535 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 2226 switch (reg) {
1547 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 2248 break;
1551 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 2286 break;
1555 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 2324 break;
1559 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 2334 break;
1563 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 2348 break;
1567 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 2362 break;
1571 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 2392 break;
1575 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 2402 break;
1579 2403 case 8:
1580   -// ignore or except?
  2404 + /* ignored */
1581 2405 rn = "BadVaddr";
1582 2406 break;
1583 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 2419 break;
1587 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 2429 break;
1591 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 2442 break;
1595 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 2466 break;
1599 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 2478 break;
1603 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 2488 break;
1607 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 2502 break;
1611 2503 case 16:
1612 2504 switch (sel) {
1613 2505 case 0:
1614 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 2516 break;
  2517 + case 3:
  2518 + /* ignored */
  2519 + rn = "Config3";
  2520 + break;
  2521 + /* 6,7 are implementation dependent */
1617 2522 default:
1618 2523 rn = "Invalid config selector";
1619 2524 goto die;
1620 2525 }
  2526 + /* Stop translation as we may have switched the execution mode */
  2527 + ctx->bstate = BS_STOP;
1621 2528 break;
1622 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 2538 break;
1626 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 2576 break;
1630 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 2614 break;
1634 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 2625 break;
1639 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 2637 case 22:
1644   -// ignore or except?
1645   - rn = "Diagnostic";
  2638 + /* ignored */
  2639 + rn = "Diagnostic"; /* implementation dependent */
1646 2640 break;
1647 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 2668 break;
1651 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 2678 break;
1655 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 2716 break;
1659 2717 case 26:
1660   -// ignore or except?
  2718 + /* ignored */
1661 2719 rn = "ECC";
1662 2720 break;
1663 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 2730 break;
1667 2731 case 28:
1668 2732 switch (sel) {
1669 2733 case 0:
  2734 + case 2:
  2735 + case 4:
  2736 + case 6:
1670 2737 gen_op_mtc0_taglo();
1671 2738 rn = "TagLo";
1672 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 2747 default:
1674   - rn = "invalid sel";
1675 2748 goto die;
1676 2749 }
1677 2750 break;
1678 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 2771 break;
1682 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 2781 break;
1686 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 2793 break;
1690 2794 default:
1691   - rn = "unknown";
1692 2795 goto die;
1693 2796 }
1694 2797 #if defined MIPS_DEBUG_DISAS
1695 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 2802 #endif
1700 2803 return;
... ... @@ -1702,16 +2805,16 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
1702 2805 die:
1703 2806 #if defined MIPS_DEBUG_DISAS
1704 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 2811 #endif
1709 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 2819 if (!(ctx->CP0_Status & (1 << CP0St_CU0)) &&
1717 2820 (ctx->hflags & MIPS_HFLAG_UM) &&
... ... @@ -1720,7 +2823,7 @@ static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd)
1720 2823 if (loglevel & CPU_LOG_TB_IN_ASM) {
1721 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 2827 return;
1725 2828 }
1726 2829  
... ... @@ -1736,13 +2839,12 @@ static void gen_cp0 (DisasContext *ctx, uint16_t opc, int rt, int rd)
1736 2839 break;
1737 2840 case OPC_MTC0:
1738 2841 /* If we get an exception, we want to restart at next instruction */
  2842 + /* XXX: breaks for mtc in delay slot */
1739 2843 ctx->pc += 4;
1740 2844 save_cpu_state(ctx, 1);
1741 2845 ctx->pc -= 4;
1742 2846 GEN_LOAD_REG_TN(T0, rt);
1743 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 2848 opn = "mtc0";
1747 2849 break;
1748 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 2902 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
1801 2903 }
1802 2904  
1803   -#ifdef MIPS_USES_FPU
1804 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 2907 int32_t offset)
1807 2908 {
1808 2909 target_ulong btarget;
1809 2910  
1810 2911 btarget = ctx->pc + 4 + offset;
1811 2912  
1812   - switch (cond) {
1813   - case 0x0000: /* bc1f */
  2913 + switch (op) {
  2914 + case OPC_BC1F:
1814 2915 gen_op_bc1f();
1815 2916 MIPS_DEBUG("bc1f %08x", btarget);
1816 2917 goto not_likely;
1817   - case 0x0002: /* bc1fl */
  2918 + case OPC_BC1FL:
1818 2919 gen_op_bc1f();
1819 2920 MIPS_DEBUG("bc1fl %08x", btarget);
1820 2921 goto likely;
1821   - case 0x0001: /* bc1t */
  2922 + case OPC_BC1T:
1822 2923 gen_op_bc1t();
1823 2924 MIPS_DEBUG("bc1t %08x", btarget);
1824 2925 not_likely:
1825 2926 ctx->hflags |= MIPS_HFLAG_BC;
1826 2927 break;
1827   - case 0x0003: /* bc1tl */
  2928 + case OPC_BC1TL:
1828 2929 gen_op_bc1t();
1829 2930 MIPS_DEBUG("bc1tl %08x", btarget);
1830 2931 likely:
... ... @@ -1832,7 +2933,7 @@ static void gen_compute_branch1 (DisasContext *ctx, uint16_t cond,
1832 2933 break;
1833 2934 default:
1834 2935 MIPS_INVAL("cp1 branch/jump");
1835   - generate_exception(ctx, EXCP_RI);
  2936 + generate_exception_err (ctx, EXCP_RI, 1);
1836 2937 return;
1837 2938 }
1838 2939 gen_op_set_bcond();
... ... @@ -1845,9 +2946,9 @@ static void gen_compute_branch1 (DisasContext *ctx, uint16_t cond,
1845 2946 }
1846 2947  
1847 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 2953 switch (opc) {
1853 2954 case OPC_MFC1:
... ... @@ -1865,7 +2966,7 @@ static void gen_cp1 (DisasContext *ctx, uint16_t opc, int rt, int fs)
1865 2966 case OPC_CFC1:
1866 2967 if (fs != 0 && fs != 31) {
1867 2968 MIPS_INVAL("cfc1 freg");
1868   - generate_exception(ctx, EXCP_RI);
  2969 + generate_exception_err (ctx, EXCP_RI, 1);
1869 2970 return;
1870 2971 }
1871 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 2975 opn = "cfc1";
1875 2976 break;
1876 2977 case OPC_CTC1:
1877   - if (fs != 0 && fs != 31) {
  2978 + if (fs != 0 && fs != 31) {
1878 2979 MIPS_INVAL("ctc1 freg");
1879   - generate_exception(ctx, EXCP_RI);
  2980 + generate_exception_err (ctx, EXCP_RI, 1);
1880 2981 return;
1881 2982 }
1882 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 2991 ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
1891 2992 ((ctx->opcode >> 16) & 0x1F));
1892 2993 }
1893   - generate_exception(ctx, EXCP_RI);
  2994 + generate_exception_err (ctx, EXCP_RI, 1);
1894 2995 return;
1895 2996 }
1896 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 3009 */
1909 3010 #define CHECK_FR(ctx, freg) do { \
1910 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 3013 return; \
1913 3014 } \
1914 3015 } while(0)
1915 3016  
1916 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 3022 const char *condnames[] = {
1922 3023 "c.f",
1923 3024 "c.un",
... ... @@ -1937,7 +3038,8 @@ static void gen_farith (DisasContext *ctx, int fmt, int ft, int fs, int fd, int
1937 3038 "c.ngt",
1938 3039 };
1939 3040 int binary = 0;
1940   -
  3041 + uint32_t func = ctx->opcode & 0x3f;
  3042 +
1941 3043 switch (ctx->opcode & FOP(0x3f, 0x1f)) {
1942 3044 case FOP(0, 17):
1943 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 3135 GEN_LOAD_FREG_FTN(DT0, fs);
2034 3136 gen_op_float_floorw_d();
2035 3137 GEN_STORE_FTN_FREG(fd, WT2);
2036   - opn = "ceil.w.d";
  3138 + opn = "floor.w.d";
2037 3139 break;
2038 3140 case FOP(33, 16): /* cvt.d.s */
2039 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 3303 break;
2202 3304 default:
2203 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 3307 ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
2206 3308 ((ctx->opcode >> 16) & 0x1F));
2207 3309 }
2208   - generate_exception(ctx, EXCP_RI);
  3310 + generate_exception_err (ctx, EXCP_RI, 1);
2209 3311 return;
2210 3312 }
2211 3313 if (binary)
... ... @@ -2213,14 +3315,27 @@ static void gen_farith (DisasContext *ctx, int fmt, int ft, int fs, int fd, int
2213 3315 else
2214 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 3334 /* MIPS16 extension to MIPS32 */
2220 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 3340 if (func == 0x02 && rd == 0) {
2226 3341 /* NOP */
... ... @@ -2265,7 +3380,7 @@ static void decode_opc (DisasContext *ctx)
2265 3380 {
2266 3381 int32_t offset;
2267 3382 int rs, rt, rd, sa;
2268   - uint16_t op, op1;
  3383 + uint32_t op, op1, op2;
2269 3384 int16_t imm;
2270 3385  
2271 3386 /* make sure instructions are on a word boundary */
... ... @@ -2279,76 +3394,86 @@ static void decode_opc (DisasContext *ctx)
2279 3394 MIPS_DEBUG("blikely condition (%08x)", ctx->pc + 4);
2280 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 3402 imm = (int16_t)ctx->opcode;
2288 3403 switch (op) {
2289   - case 0x00: /* Special opcode */
2290   - op1 = ctx->opcode & 0x3F;
  3404 + case OPC_SPECIAL:
  3405 + op1 = MASK_SPECIAL(ctx->opcode);
2291 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 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 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 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 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 3440 generate_exception(ctx, EXCP_SYSCALL);
  3441 + ctx->bstate = BS_EXCP;
2323 3442 break;
2324   - case 0x0D: /* BREAK */
  3443 + case OPC_BREAK:
2325 3444 generate_exception(ctx, EXCP_BREAK);
2326 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 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 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 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 3477 #endif
2353 3478 default: /* Invalid */
2354 3479 MIPS_INVAL("special");
... ... @@ -2356,23 +3481,20 @@ static void decode_opc (DisasContext *ctx)
2356 3481 break;
2357 3482 }
2358 3483 break;
2359   - case 0x1C: /* Special2 opcode */
2360   - op1 = ctx->opcode & 0x3F;
  3484 + case OPC_SPECIAL2:
  3485 + op1 = MASK_SPECIAL2(ctx->opcode);
2361 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 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 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 3496 break;
2374   -#endif
2375   - case 0x3F: /* SDBBP */
  3497 + case OPC_SDBBP:
2376 3498 /* XXX: not clear which exception should be raised
2377 3499 * when in debug mode...
2378 3500 */
... ... @@ -2383,22 +3505,109 @@ static void decode_opc (DisasContext *ctx)
2383 3505 }
2384 3506 /* Treat as a noop */
2385 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 3513 default: /* Invalid */
2387 3514 MIPS_INVAL("special2");
2388 3515 generate_exception(ctx, EXCP_RI);
2389 3516 break;
2390 3517 }
2391 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 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 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 3611 break;
2403 3612 default: /* Invalid */
2404 3613 MIPS_INVAL("REGIMM");
... ... @@ -2406,48 +3615,78 @@ static void decode_opc (DisasContext *ctx)
2406 3615 break;
2407 3616 }
2408 3617 break;
2409   - case 0x10: /* CP0 opcode */
2410   - op1 = ((ctx->opcode >> 21) & 0x1F);
  3618 + case OPC_CP0:
  3619 + op1 = MASK_CP0(ctx->opcode);
2411 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 3651 break;
  3652 + /* Shadow registers (not implemented). */
  3653 + case OPC_RDPGPR:
  3654 + case OPC_WRPGPR:
2416 3655 default:
2417   - gen_cp0(ctx, (ctx->opcode & 0x3F) | EXT_CP0, rt, rd);
  3656 + generate_exception(ctx, EXCP_RI);
2418 3657 break;
2419 3658 }
2420 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 3682 /* Treat as a noop */
2442 3683 break;
2443   - case 0x3F: /* HACK */
2444   - break;
2445 3684  
2446 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 3690 #if defined(MIPS_USES_FPU)
2452 3691 save_cpu_state(ctx, 1);
2453 3692 gen_op_cp1_enabled();
... ... @@ -2457,65 +3696,80 @@ static void decode_opc (DisasContext *ctx)
2457 3696 #endif
2458 3697 break;
2459 3698  
2460   - case 0x11: /* CP1 opcode */
  3699 + case OPC_CP1:
2461 3700 #if defined(MIPS_USES_FPU)
2462 3701 save_cpu_state(ctx, 1);
2463 3702 gen_op_cp1_enabled();
2464   - op1 = ((ctx->opcode >> 21) & 0x1F);
  3703 + op1 = MASK_CP1(ctx->opcode);
2465 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 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 3719 break;
2481 3720 default:
2482 3721 generate_exception_err(ctx, EXCP_RI, 1);
2483 3722 break;
2484 3723 }
2485   - break;
2486 3724 #else
2487 3725 generate_exception_err(ctx, EXCP_CpU, 1);
2488 3726 #endif
2489 3727 break;
2490 3728  
2491 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 3736 generate_exception_err(ctx, EXCP_CpU, 2);
2499 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 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 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 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 3772 #endif
2517   - case 0x1E:
2518   - /* ASE specific */
2519 3773 default: /* Invalid */
2520 3774 MIPS_INVAL("");
2521 3775 generate_exception(ctx, EXCP_RI);
... ... @@ -2707,7 +3961,6 @@ int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
2707 3961 return gen_intermediate_code_internal(env, tb, 1);
2708 3962 }
2709 3963  
2710   -#ifdef MIPS_USES_FPU
2711 3964 void fpu_dump_state(CPUState *env, FILE *f,
2712 3965 int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
2713 3966 int flags)
... ... @@ -2721,19 +3974,19 @@ void fpu_dump_state(CPUState *env, FILE *f,
2721 3974  
2722 3975 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d\n",
2723 3976 env->fcr0, env->fcr31,
2724   - (env->CP0_Status & (1<<CP0St_FR)) != 0);
  3977 + (env->CP0_Status & (1 << CP0St_FR)) != 0);
2725 3978 fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
2726 3979 fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
2727 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 3983 printfpr(FPR(env, i));
2731 3984 }
2732 3985  
2733 3986 #undef printfpr
2734 3987 }
2735 3988  
2736   -void dump_fpu(CPUState *env)
  3989 +void dump_fpu (CPUState *env)
2737 3990 {
2738 3991 if (loglevel) {
2739 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 3994 fpu_dump_state(env, logfile, fprintf, 0);
2742 3995 }
2743 3996 }
2744   -#endif /* MIPS_USES_FPU */
2745 3997  
2746 3998 void cpu_dump_state (CPUState *env, FILE *f,
2747 3999 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
... ... @@ -2772,9 +4024,8 @@ void cpu_dump_state (CPUState *env, FILE *f,
2772 4024 c0_status, env->CP0_Cause, env->CP0_EPC);
2773 4025 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%08x\n",
2774 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 4031 CPUMIPSState *cpu_mips_init (void)
... ... @@ -2802,16 +4053,12 @@ void cpu_reset (CPUMIPSState *env)
2802 4053 env->tlb_in_use = MIPS_TLB_NB;
2803 4054 #endif
2804 4055 env->CP0_Wired = 0;
  4056 + /* SMP not implemented */
  4057 + env->CP0_EBase = 0x80000000;
2805 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 4062 env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV);
2816 4063 env->CP0_WatchLo = 0;
2817 4064 env->hflags = MIPS_HFLAG_ERL;
... ... @@ -2825,4 +4072,7 @@ void cpu_reset (CPUMIPSState *env)
2825 4072 #ifdef MIPS_USES_FPU
2826 4073 env->fcr0 = MIPS_FCR0;
2827 4074 #endif
  4075 + /* XXX some guesswork here, values are CPU specific */
  4076 + env->SYNCI_Step = 16;
  4077 + env->CCRes = 2;
2828 4078 }
... ...