Commit e189e7486867e36c35f99cbac27d503ce4e7c71d

Authored by ths
1 parent 92a34c10

Per-CPU instruction decoding implementation, by Aurelien Jarno.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3228 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/cpu.h
... ... @@ -441,6 +441,7 @@ struct CPUMIPSState {
441 441 int CCRes; /* Cycle count resolution/divisor */
442 442 uint32_t CP0_Status_rw_bitmask; /* Read/write bits in CP0_Status */
443 443 uint32_t CP0_TCStatus_rw_bitmask; /* Read/write bits in CP0_TCStatus */
  444 + int insn_flags; /* Supported instruction set */
444 445  
445 446 #ifdef CONFIG_USER_ONLY
446 447 target_ulong tls_value;
... ...
target-mips/helper.c
... ... @@ -369,8 +369,7 @@ void do_interrupt (CPUState *env)
369 369 }
370 370 enter_debug_mode:
371 371 env->hflags |= MIPS_HFLAG_DM;
372   - if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
373   - env->hflags |= MIPS_HFLAG_64;
  372 + env->hflags |= MIPS_HFLAG_64;
374 373 env->hflags &= ~MIPS_HFLAG_UM;
375 374 /* EJTAG probe trap enable is not implemented... */
376 375 if (!(env->CP0_Status & (1 << CP0St_EXL)))
... ... @@ -396,8 +395,7 @@ void do_interrupt (CPUState *env)
396 395 env->CP0_ErrorEPC = env->PC[env->current_tc];
397 396 }
398 397 env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
399   - if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
400   - env->hflags |= MIPS_HFLAG_64;
  398 + env->hflags |= MIPS_HFLAG_64;
401 399 env->hflags &= ~MIPS_HFLAG_UM;
402 400 if (!(env->CP0_Status & (1 << CP0St_EXL)))
403 401 env->CP0_Cause &= ~(1 << CP0Ca_BD);
... ... @@ -499,8 +497,7 @@ void do_interrupt (CPUState *env)
499 497 env->CP0_Cause &= ~(1 << CP0Ca_BD);
500 498 }
501 499 env->CP0_Status |= (1 << CP0St_EXL);
502   - if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
503   - env->hflags |= MIPS_HFLAG_64;
  500 + env->hflags |= MIPS_HFLAG_64;
504 501 env->hflags &= ~MIPS_HFLAG_UM;
505 502 }
506 503 env->hflags &= ~MIPS_HFLAG_BMASK;
... ...
target-mips/mips-defs.h
... ... @@ -14,6 +14,41 @@
14 14 #define TARGET_LONG_BITS 32
15 15 #endif
16 16  
  17 +/* Masks used to mark instructions to indicate which ISA level they
  18 + were introduced in. */
  19 +#define ISA_MIPS1 0x00000001
  20 +#define ISA_MIPS2 0x00000002
  21 +#define ISA_MIPS3 0x00000004
  22 +#define ISA_MIPS4 0x00000008
  23 +#define ISA_MIPS5 0x00000010
  24 +#define ISA_MIPS32 0x00000020
  25 +#define ISA_MIPS32R2 0x00000040
  26 +#define ISA_MIPS64 0x00000080
  27 +#define ISA_MIPS64R2 0x00000100
  28 +
  29 +/* MIPS ASE */
  30 +#define ASE_MIPS16 0x00001000
  31 +#define ASE_MIPS3D 0x00002000
  32 +#define ASE_MDMX 0x00004000
  33 +#define ASE_DSP 0x00008000
  34 +#define ASE_DSPR2 0x00010000
  35 +
  36 +/* Chip specific instructions. */
  37 +/* Currently void */
  38 +
  39 +/* MIPS CPU defines. */
  40 +#define CPU_MIPS1 (ISA_MIPS1)
  41 +#define CPU_MIPS2 (CPU_MIPS1 | ISA_MIPS2)
  42 +#define CPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3)
  43 +#define CPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4)
  44 +#define CPU_MIPS5 (CPU_MIPS4 | ISA_MIPS5)
  45 +
  46 +#define CPU_MIPS32 (CPU_MIPS2 | ISA_MIPS32)
  47 +#define CPU_MIPS64 (CPU_MIPS5 | CPU_MIPS32 | ISA_MIPS64)
  48 +
  49 +#define CPU_MIPS32R2 (CPU_MIPS32 | ISA_MIPS32R2)
  50 +#define CPU_MIPS64R2 (CPU_MIPS64 | CPU_MIPS32R2 | ISA_MIPS64R2)
  51 +
17 52 /* Strictly follow the architecture standard:
18 53 - Disallow "special" instruction handling for PMON/SPIM.
19 54 Note that we still maintain Count/Compare to match the host clock. */
... ...
target-mips/op.c
... ... @@ -1847,10 +1847,9 @@ void op_mtc0_status (void)
1847 1847 (val & (1 << CP0St_UM)))
1848 1848 env->hflags |= MIPS_HFLAG_UM;
1849 1849 #ifdef TARGET_MIPS64
1850   - if (!(env->CP0_Config0 & (0x3 << CP0C0_AT)) ||
1851   - ((env->hflags & MIPS_HFLAG_UM) &&
  1850 + if ((env->hflags & MIPS_HFLAG_UM) &&
1852 1851 !(val & (1 << CP0St_PX)) &&
1853   - !(val & (1 << CP0St_UX))))
  1852 + !(val & (1 << CP0St_UX)))
1854 1853 env->hflags &= ~MIPS_HFLAG_64;
1855 1854 #endif
1856 1855 if (val & (1 << CP0St_CU1))
... ... @@ -1906,7 +1905,7 @@ void op_mtc0_cause (void)
1906 1905 {
1907 1906 uint32_t mask = 0x00C00300;
1908 1907  
1909   - if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR))
  1908 + if (env->insn_flags & ISA_MIPS32R2)
1910 1909 mask |= 1 << CP0Ca_DC;
1911 1910  
1912 1911 env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask);
... ... @@ -3014,10 +3013,9 @@ void op_eret (void)
3014 3013 (env->CP0_Status & (1 << CP0St_UM)))
3015 3014 env->hflags |= MIPS_HFLAG_UM;
3016 3015 #ifdef TARGET_MIPS64
3017   - if (!(env->CP0_Config0 & (0x3 << CP0C0_AT)) ||
3018   - ((env->hflags & MIPS_HFLAG_UM) &&
  3016 + if ((env->hflags & MIPS_HFLAG_UM) &&
3019 3017 !(env->CP0_Status & (1 << CP0St_PX)) &&
3020   - !(env->CP0_Status & (1 << CP0St_UX))))
  3018 + !(env->CP0_Status & (1 << CP0St_UX)))
3021 3019 env->hflags &= ~MIPS_HFLAG_64;
3022 3020 #endif
3023 3021 if (loglevel & CPU_LOG_EXEC)
... ... @@ -3038,10 +3036,9 @@ void op_deret (void)
3038 3036 (env->CP0_Status & (1 << CP0St_UM)))
3039 3037 env->hflags |= MIPS_HFLAG_UM;
3040 3038 #ifdef TARGET_MIPS64
3041   - if (!(env->CP0_Config0 & (0x3 << CP0C0_AT)) ||
3042   - ((env->hflags & MIPS_HFLAG_UM) &&
  3039 + if ((env->hflags & MIPS_HFLAG_UM) &&
3043 3040 !(env->CP0_Status & (1 << CP0St_PX)) &&
3044   - !(env->CP0_Status & (1 << CP0St_UX))))
  3041 + !(env->CP0_Status & (1 << CP0St_UX)))
3045 3042 env->hflags &= ~MIPS_HFLAG_64;
3046 3043 #endif
3047 3044 if (loglevel & CPU_LOG_EXEC)
... ...
target-mips/translate.c
... ... @@ -142,7 +142,7 @@ enum {
142 142 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
143 143 OPC_SRA = 0x03 | OPC_SPECIAL,
144 144 OPC_SLLV = 0x04 | OPC_SPECIAL,
145   - OPC_SRLV = 0x06 | OPC_SPECIAL,
  145 + OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
146 146 OPC_SRAV = 0x07 | OPC_SPECIAL,
147 147 OPC_DSLLV = 0x14 | OPC_SPECIAL,
148 148 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
... ... @@ -761,10 +761,10 @@ void check_cp1_registers(DisasContext *ctx, int regs)
761 761 }
762 762  
763 763 /* This code generates a "reserved instruction" exception if the
764   - CPU is not a MIPS R2 (or higher) CPU. */
765   -static inline void check_mips_r2(CPUState *env, DisasContext *ctx)
  764 + CPU does not support the instruction set corresponding to flags. */
  765 +static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
766 766 {
767   - if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) < (1 << CP0C0_AR))
  767 + if (unlikely(!(env->insn_flags & flags)))
768 768 generate_exception(ctx, EXCP_RI);
769 769 }
770 770  
... ... @@ -776,6 +776,14 @@ static inline void check_mips_mt(CPUState *env, DisasContext *ctx)
776 776 generate_exception(ctx, EXCP_RI);
777 777 }
778 778  
  779 +/* This code generates a "reserved instruction" exception if 64-bit
  780 + instructions are not enabled. */
  781 +static inline void check_mips_64(DisasContext *ctx)
  782 +{
  783 + if (!(ctx->hflags & MIPS_HFLAG_64))
  784 + generate_exception(ctx, EXCP_RI);
  785 +}
  786 +
779 787 #if defined(CONFIG_USER_ONLY)
780 788 #define op_ldst(name) gen_op_##name##_raw()
781 789 #define OP_LD_TABLE(width)
... ... @@ -1024,8 +1032,8 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1024 1032 }
1025 1033  
1026 1034 /* Arithmetic with immediate operand */
1027   -static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
1028   - int rs, int16_t imm)
  1035 +static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
  1036 + int rt, int rs, int16_t imm)
1029 1037 {
1030 1038 target_ulong uimm;
1031 1039 const char *opn = "imm arith";
... ... @@ -1132,8 +1140,14 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
1132 1140 opn = "srl";
1133 1141 break;
1134 1142 case 1:
1135   - gen_op_rotr();
1136   - opn = "rotr";
  1143 + /* rotr is decoded as srl on non-R2 CPUs */
  1144 + if (env->insn_flags & ISA_MIPS32R2) {
  1145 + gen_op_rotr();
  1146 + opn = "rotr";
  1147 + } else {
  1148 + gen_op_srl();
  1149 + opn = "srl";
  1150 + }
1137 1151 break;
1138 1152 default:
1139 1153 MIPS_INVAL("invalid srl flag");
... ... @@ -1157,8 +1171,14 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
1157 1171 opn = "dsrl";
1158 1172 break;
1159 1173 case 1:
1160   - gen_op_drotr();
1161   - opn = "drotr";
  1174 + /* drotr is decoded as dsrl on non-R2 CPUs */
  1175 + if (env->insn_flags & ISA_MIPS32R2) {
  1176 + gen_op_drotr();
  1177 + opn = "drotr";
  1178 + } else {
  1179 + gen_op_dsrl();
  1180 + opn = "dsrl";
  1181 + }
1162 1182 break;
1163 1183 default:
1164 1184 MIPS_INVAL("invalid dsrl flag");
... ... @@ -1181,8 +1201,14 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
1181 1201 opn = "dsrl32";
1182 1202 break;
1183 1203 case 1:
1184   - gen_op_drotr32();
1185   - opn = "drotr32";
  1204 + /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
  1205 + if (env->insn_flags & ISA_MIPS32R2) {
  1206 + gen_op_drotr32();
  1207 + opn = "drotr32";
  1208 + } else {
  1209 + gen_op_dsrl32();
  1210 + opn = "dsrl32";
  1211 + }
1186 1212 break;
1187 1213 default:
1188 1214 MIPS_INVAL("invalid dsrl32 flag");
... ... @@ -1201,7 +1227,7 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
1201 1227 }
1202 1228  
1203 1229 /* Arithmetic */
1204   -static void gen_arith (DisasContext *ctx, uint32_t opc,
  1230 +static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1205 1231 int rd, int rs, int rt)
1206 1232 {
1207 1233 const char *opn = "arith";
... ... @@ -1305,8 +1331,14 @@ static void gen_arith (DisasContext *ctx, uint32_t opc,
1305 1331 opn = "srlv";
1306 1332 break;
1307 1333 case 1:
1308   - gen_op_rotrv();
1309   - opn = "rotrv";
  1334 + /* rotrv is decoded as srlv on non-R2 CPUs */
  1335 + if (env->insn_flags & ISA_MIPS32R2) {
  1336 + gen_op_rotrv();
  1337 + opn = "rotrv";
  1338 + } else {
  1339 + gen_op_srlv();
  1340 + opn = "srlv";
  1341 + }
1310 1342 break;
1311 1343 default:
1312 1344 MIPS_INVAL("invalid srlv flag");
... ... @@ -1330,8 +1362,14 @@ static void gen_arith (DisasContext *ctx, uint32_t opc,
1330 1362 opn = "dsrlv";
1331 1363 break;
1332 1364 case 1:
1333   - gen_op_drotrv();
1334   - opn = "drotrv";
  1365 + /* drotrv is decoded as dsrlv on non-R2 CPUs */
  1366 + if (env->insn_flags & ISA_MIPS32R2) {
  1367 + gen_op_drotrv();
  1368 + opn = "drotrv";
  1369 + } else {
  1370 + gen_op_dsrlv();
  1371 + opn = "dsrlv";
  1372 + }
1335 1373 break;
1336 1374 default:
1337 1375 MIPS_INVAL("invalid dsrlv flag");
... ... @@ -1910,6 +1948,9 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1910 1948 {
1911 1949 const char *rn = "invalid";
1912 1950  
  1951 + if (sel != 0)
  1952 + check_insn(env, ctx, ISA_MIPS32);
  1953 +
1913 1954 switch (reg) {
1914 1955 case 0:
1915 1956 switch (sel) {
... ... @@ -2057,7 +2098,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2057 2098 rn = "PageMask";
2058 2099 break;
2059 2100 case 1:
2060   - check_mips_r2(env, ctx);
  2101 + check_insn(env, ctx, ISA_MIPS32R2);
2061 2102 gen_op_mfc0_pagegrain();
2062 2103 rn = "PageGrain";
2063 2104 break;
... ... @@ -2072,22 +2113,27 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2072 2113 rn = "Wired";
2073 2114 break;
2074 2115 case 1:
  2116 + check_insn(env, ctx, ISA_MIPS32R2);
2075 2117 gen_op_mfc0_srsconf0();
2076 2118 rn = "SRSConf0";
2077 2119 break;
2078 2120 case 2:
  2121 + check_insn(env, ctx, ISA_MIPS32R2);
2079 2122 gen_op_mfc0_srsconf1();
2080 2123 rn = "SRSConf1";
2081 2124 break;
2082 2125 case 3:
  2126 + check_insn(env, ctx, ISA_MIPS32R2);
2083 2127 gen_op_mfc0_srsconf2();
2084 2128 rn = "SRSConf2";
2085 2129 break;
2086 2130 case 4:
  2131 + check_insn(env, ctx, ISA_MIPS32R2);
2087 2132 gen_op_mfc0_srsconf3();
2088 2133 rn = "SRSConf3";
2089 2134 break;
2090 2135 case 5:
  2136 + check_insn(env, ctx, ISA_MIPS32R2);
2091 2137 gen_op_mfc0_srsconf4();
2092 2138 rn = "SRSConf4";
2093 2139 break;
... ... @@ -2098,7 +2144,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2098 2144 case 7:
2099 2145 switch (sel) {
2100 2146 case 0:
2101   - check_mips_r2(env, ctx);
  2147 + check_insn(env, ctx, ISA_MIPS32R2);
2102 2148 gen_op_mfc0_hwrena();
2103 2149 rn = "HWREna";
2104 2150 break;
... ... @@ -2155,17 +2201,17 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2155 2201 rn = "Status";
2156 2202 break;
2157 2203 case 1:
2158   - check_mips_r2(env, ctx);
  2204 + check_insn(env, ctx, ISA_MIPS32R2);
2159 2205 gen_op_mfc0_intctl();
2160 2206 rn = "IntCtl";
2161 2207 break;
2162 2208 case 2:
2163   - check_mips_r2(env, ctx);
  2209 + check_insn(env, ctx, ISA_MIPS32R2);
2164 2210 gen_op_mfc0_srsctl();
2165 2211 rn = "SRSCtl";
2166 2212 break;
2167 2213 case 3:
2168   - check_mips_r2(env, ctx);
  2214 + check_insn(env, ctx, ISA_MIPS32R2);
2169 2215 gen_op_mfc0_srsmap();
2170 2216 rn = "SRSMap";
2171 2217 break;
... ... @@ -2200,7 +2246,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2200 2246 rn = "PRid";
2201 2247 break;
2202 2248 case 1:
2203   - check_mips_r2(env, ctx);
  2249 + check_insn(env, ctx, ISA_MIPS32R2);
2204 2250 gen_op_mfc0_ebase();
2205 2251 rn = "EBase";
2206 2252 break;
... ... @@ -2274,8 +2320,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2274 2320 switch (sel) {
2275 2321 case 0:
2276 2322 #ifdef TARGET_MIPS64
2277   - if (!(ctx->hflags & MIPS_HFLAG_64))
2278   - goto die;
  2323 + check_insn(env, ctx, ISA_MIPS3);
2279 2324 gen_op_mfc0_xcontext();
2280 2325 rn = "XContext";
2281 2326 break;
... ... @@ -2471,6 +2516,9 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2471 2516 {
2472 2517 const char *rn = "invalid";
2473 2518  
  2519 + if (sel != 0)
  2520 + check_insn(env, ctx, ISA_MIPS32);
  2521 +
2474 2522 switch (reg) {
2475 2523 case 0:
2476 2524 switch (sel) {
... ... @@ -2618,7 +2666,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2618 2666 rn = "PageMask";
2619 2667 break;
2620 2668 case 1:
2621   - check_mips_r2(env, ctx);
  2669 + check_insn(env, ctx, ISA_MIPS32R2);
2622 2670 gen_op_mtc0_pagegrain();
2623 2671 rn = "PageGrain";
2624 2672 break;
... ... @@ -2633,22 +2681,27 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2633 2681 rn = "Wired";
2634 2682 break;
2635 2683 case 1:
  2684 + check_insn(env, ctx, ISA_MIPS32R2);
2636 2685 gen_op_mtc0_srsconf0();
2637 2686 rn = "SRSConf0";
2638 2687 break;
2639 2688 case 2:
  2689 + check_insn(env, ctx, ISA_MIPS32R2);
2640 2690 gen_op_mtc0_srsconf1();
2641 2691 rn = "SRSConf1";
2642 2692 break;
2643 2693 case 3:
  2694 + check_insn(env, ctx, ISA_MIPS32R2);
2644 2695 gen_op_mtc0_srsconf2();
2645 2696 rn = "SRSConf2";
2646 2697 break;
2647 2698 case 4:
  2699 + check_insn(env, ctx, ISA_MIPS32R2);
2648 2700 gen_op_mtc0_srsconf3();
2649 2701 rn = "SRSConf3";
2650 2702 break;
2651 2703 case 5:
  2704 + check_insn(env, ctx, ISA_MIPS32R2);
2652 2705 gen_op_mtc0_srsconf4();
2653 2706 rn = "SRSConf4";
2654 2707 break;
... ... @@ -2659,7 +2712,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2659 2712 case 7:
2660 2713 switch (sel) {
2661 2714 case 0:
2662   - check_mips_r2(env, ctx);
  2715 + check_insn(env, ctx, ISA_MIPS32R2);
2663 2716 gen_op_mtc0_hwrena();
2664 2717 rn = "HWREna";
2665 2718 break;
... ... @@ -2717,21 +2770,21 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2717 2770 rn = "Status";
2718 2771 break;
2719 2772 case 1:
2720   - check_mips_r2(env, ctx);
  2773 + check_insn(env, ctx, ISA_MIPS32R2);
2721 2774 gen_op_mtc0_intctl();
2722 2775 /* Stop translation as we may have switched the execution mode */
2723 2776 ctx->bstate = BS_STOP;
2724 2777 rn = "IntCtl";
2725 2778 break;
2726 2779 case 2:
2727   - check_mips_r2(env, ctx);
  2780 + check_insn(env, ctx, ISA_MIPS32R2);
2728 2781 gen_op_mtc0_srsctl();
2729 2782 /* Stop translation as we may have switched the execution mode */
2730 2783 ctx->bstate = BS_STOP;
2731 2784 rn = "SRSCtl";
2732 2785 break;
2733 2786 case 3:
2734   - check_mips_r2(env, ctx);
  2787 + check_insn(env, ctx, ISA_MIPS32R2);
2735 2788 gen_op_mtc0_srsmap();
2736 2789 /* Stop translation as we may have switched the execution mode */
2737 2790 ctx->bstate = BS_STOP;
... ... @@ -2770,7 +2823,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2770 2823 rn = "PRid";
2771 2824 break;
2772 2825 case 1:
2773   - check_mips_r2(env, ctx);
  2826 + check_insn(env, ctx, ISA_MIPS32R2);
2774 2827 gen_op_mtc0_ebase();
2775 2828 rn = "EBase";
2776 2829 break;
... ... @@ -2849,8 +2902,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2849 2902 switch (sel) {
2850 2903 case 0:
2851 2904 #ifdef TARGET_MIPS64
2852   - if (!(ctx->hflags & MIPS_HFLAG_64))
2853   - goto die;
  2905 + check_insn(env, ctx, ISA_MIPS3);
2854 2906 gen_op_mtc0_xcontext();
2855 2907 rn = "XContext";
2856 2908 break;
... ... @@ -3064,6 +3116,9 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3064 3116 {
3065 3117 const char *rn = "invalid";
3066 3118  
  3119 + if (sel != 0)
  3120 + check_insn(env, ctx, ISA_MIPS64);
  3121 +
3067 3122 switch (reg) {
3068 3123 case 0:
3069 3124 switch (sel) {
... ... @@ -3211,7 +3266,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3211 3266 rn = "PageMask";
3212 3267 break;
3213 3268 case 1:
3214   - check_mips_r2(env, ctx);
  3269 + check_insn(env, ctx, ISA_MIPS32R2);
3215 3270 gen_op_mfc0_pagegrain();
3216 3271 rn = "PageGrain";
3217 3272 break;
... ... @@ -3226,22 +3281,27 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3226 3281 rn = "Wired";
3227 3282 break;
3228 3283 case 1:
  3284 + check_insn(env, ctx, ISA_MIPS32R2);
3229 3285 gen_op_mfc0_srsconf0();
3230 3286 rn = "SRSConf0";
3231 3287 break;
3232 3288 case 2:
  3289 + check_insn(env, ctx, ISA_MIPS32R2);
3233 3290 gen_op_mfc0_srsconf1();
3234 3291 rn = "SRSConf1";
3235 3292 break;
3236 3293 case 3:
  3294 + check_insn(env, ctx, ISA_MIPS32R2);
3237 3295 gen_op_mfc0_srsconf2();
3238 3296 rn = "SRSConf2";
3239 3297 break;
3240 3298 case 4:
  3299 + check_insn(env, ctx, ISA_MIPS32R2);
3241 3300 gen_op_mfc0_srsconf3();
3242 3301 rn = "SRSConf3";
3243 3302 break;
3244 3303 case 5:
  3304 + check_insn(env, ctx, ISA_MIPS32R2);
3245 3305 gen_op_mfc0_srsconf4();
3246 3306 rn = "SRSConf4";
3247 3307 break;
... ... @@ -3252,7 +3312,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3252 3312 case 7:
3253 3313 switch (sel) {
3254 3314 case 0:
3255   - check_mips_r2(env, ctx);
  3315 + check_insn(env, ctx, ISA_MIPS32R2);
3256 3316 gen_op_mfc0_hwrena();
3257 3317 rn = "HWREna";
3258 3318 break;
... ... @@ -3309,17 +3369,17 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3309 3369 rn = "Status";
3310 3370 break;
3311 3371 case 1:
3312   - check_mips_r2(env, ctx);
  3372 + check_insn(env, ctx, ISA_MIPS32R2);
3313 3373 gen_op_mfc0_intctl();
3314 3374 rn = "IntCtl";
3315 3375 break;
3316 3376 case 2:
3317   - check_mips_r2(env, ctx);
  3377 + check_insn(env, ctx, ISA_MIPS32R2);
3318 3378 gen_op_mfc0_srsctl();
3319 3379 rn = "SRSCtl";
3320 3380 break;
3321 3381 case 3:
3322   - check_mips_r2(env, ctx);
  3382 + check_insn(env, ctx, ISA_MIPS32R2);
3323 3383 gen_op_mfc0_srsmap();
3324 3384 rn = "SRSMap";
3325 3385 break;
... ... @@ -3354,7 +3414,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3354 3414 rn = "PRid";
3355 3415 break;
3356 3416 case 1:
3357   - check_mips_r2(env, ctx);
  3417 + check_insn(env, ctx, ISA_MIPS32R2);
3358 3418 gen_op_mfc0_ebase();
3359 3419 rn = "EBase";
3360 3420 break;
... ... @@ -3418,6 +3478,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3418 3478 case 20:
3419 3479 switch (sel) {
3420 3480 case 0:
  3481 + check_insn(env, ctx, ISA_MIPS3);
3421 3482 gen_op_dmfc0_xcontext();
3422 3483 rn = "XContext";
3423 3484 break;
... ... @@ -3612,6 +3673,9 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3612 3673 {
3613 3674 const char *rn = "invalid";
3614 3675  
  3676 + if (sel != 0)
  3677 + check_insn(env, ctx, ISA_MIPS64);
  3678 +
3615 3679 switch (reg) {
3616 3680 case 0:
3617 3681 switch (sel) {
... ... @@ -3759,7 +3823,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3759 3823 rn = "PageMask";
3760 3824 break;
3761 3825 case 1:
3762   - check_mips_r2(env, ctx);
  3826 + check_insn(env, ctx, ISA_MIPS32R2);
3763 3827 gen_op_mtc0_pagegrain();
3764 3828 rn = "PageGrain";
3765 3829 break;
... ... @@ -3774,22 +3838,27 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3774 3838 rn = "Wired";
3775 3839 break;
3776 3840 case 1:
  3841 + check_insn(env, ctx, ISA_MIPS32R2);
3777 3842 gen_op_mtc0_srsconf0();
3778 3843 rn = "SRSConf0";
3779 3844 break;
3780 3845 case 2:
  3846 + check_insn(env, ctx, ISA_MIPS32R2);
3781 3847 gen_op_mtc0_srsconf1();
3782 3848 rn = "SRSConf1";
3783 3849 break;
3784 3850 case 3:
  3851 + check_insn(env, ctx, ISA_MIPS32R2);
3785 3852 gen_op_mtc0_srsconf2();
3786 3853 rn = "SRSConf2";
3787 3854 break;
3788 3855 case 4:
  3856 + check_insn(env, ctx, ISA_MIPS32R2);
3789 3857 gen_op_mtc0_srsconf3();
3790 3858 rn = "SRSConf3";
3791 3859 break;
3792 3860 case 5:
  3861 + check_insn(env, ctx, ISA_MIPS32R2);
3793 3862 gen_op_mtc0_srsconf4();
3794 3863 rn = "SRSConf4";
3795 3864 break;
... ... @@ -3800,7 +3869,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3800 3869 case 7:
3801 3870 switch (sel) {
3802 3871 case 0:
3803   - check_mips_r2(env, ctx);
  3872 + check_insn(env, ctx, ISA_MIPS32R2);
3804 3873 gen_op_mtc0_hwrena();
3805 3874 rn = "HWREna";
3806 3875 break;
... ... @@ -3858,21 +3927,21 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3858 3927 rn = "Status";
3859 3928 break;
3860 3929 case 1:
3861   - check_mips_r2(env, ctx);
  3930 + check_insn(env, ctx, ISA_MIPS32R2);
3862 3931 gen_op_mtc0_intctl();
3863 3932 /* Stop translation as we may have switched the execution mode */
3864 3933 ctx->bstate = BS_STOP;
3865 3934 rn = "IntCtl";
3866 3935 break;
3867 3936 case 2:
3868   - check_mips_r2(env, ctx);
  3937 + check_insn(env, ctx, ISA_MIPS32R2);
3869 3938 gen_op_mtc0_srsctl();
3870 3939 /* Stop translation as we may have switched the execution mode */
3871 3940 ctx->bstate = BS_STOP;
3872 3941 rn = "SRSCtl";
3873 3942 break;
3874 3943 case 3:
3875   - check_mips_r2(env, ctx);
  3944 + check_insn(env, ctx, ISA_MIPS32R2);
3876 3945 gen_op_mtc0_srsmap();
3877 3946 /* Stop translation as we may have switched the execution mode */
3878 3947 ctx->bstate = BS_STOP;
... ... @@ -3911,7 +3980,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3911 3980 rn = "PRid";
3912 3981 break;
3913 3982 case 1:
3914   - check_mips_r2(env, ctx);
  3983 + check_insn(env, ctx, ISA_MIPS32R2);
3915 3984 gen_op_mtc0_ebase();
3916 3985 rn = "EBase";
3917 3986 break;
... ... @@ -3980,6 +4049,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3980 4049 case 20:
3981 4050 switch (sel) {
3982 4051 case 0:
  4052 + check_insn(env, ctx, ISA_MIPS3);
3983 4053 gen_op_mtc0_xcontext();
3984 4054 rn = "XContext";
3985 4055 break;
... ... @@ -4535,8 +4605,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
4535 4605 break;
4536 4606 #ifdef TARGET_MIPS64
4537 4607 case OPC_DMFC0:
4538   - if (!(ctx->hflags & MIPS_HFLAG_64))
4539   - generate_exception(ctx, EXCP_RI);
  4608 + check_insn(env, ctx, ISA_MIPS3);
4540 4609 if (rt == 0) {
4541 4610 /* Treat as NOP. */
4542 4611 return;
... ... @@ -4546,8 +4615,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
4546 4615 opn = "dmfc0";
4547 4616 break;
4548 4617 case OPC_DMTC0:
4549   - if (!(ctx->hflags & MIPS_HFLAG_64))
4550   - generate_exception(ctx, EXCP_RI);
  4618 + check_insn(env, ctx, ISA_MIPS3);
4551 4619 GEN_LOAD_REG_TN(T0, rt);
4552 4620 gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
4553 4621 opn = "dmtc0";
... ... @@ -4597,11 +4665,13 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
4597 4665 break;
4598 4666 case OPC_ERET:
4599 4667 opn = "eret";
  4668 + check_insn(env, ctx, ISA_MIPS2);
4600 4669 gen_op_eret();
4601 4670 ctx->bstate = BS_EXCP;
4602 4671 break;
4603 4672 case OPC_DERET:
4604 4673 opn = "deret";
  4674 + check_insn(env, ctx, ISA_MIPS32);
4605 4675 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4606 4676 MIPS_INVAL(opn);
4607 4677 generate_exception(ctx, EXCP_RI);
... ... @@ -4612,6 +4682,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
4612 4682 break;
4613 4683 case OPC_WAIT:
4614 4684 opn = "wait";
  4685 + check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
4615 4686 /* If we get an exception, we want to restart at next instruction */
4616 4687 ctx->pc += 4;
4617 4688 save_cpu_state(ctx, 1);
... ... @@ -4629,12 +4700,15 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
4629 4700 }
4630 4701  
4631 4702 /* CP1 Branches (before delay slot) */
4632   -static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
  4703 +static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
4633 4704 int32_t cc, int32_t offset)
4634 4705 {
4635 4706 target_ulong btarget;
4636 4707 const char *opn = "cp1 cond branch";
4637 4708  
  4709 + if (cc != 0)
  4710 + check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
  4711 +
4638 4712 btarget = ctx->pc + 4 + offset;
4639 4713  
4640 4714 switch (op) {
... ... @@ -5843,14 +5917,15 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5843 5917 switch (op1) {
5844 5918 case OPC_SLL: /* Arithmetic with immediate */
5845 5919 case OPC_SRL ... OPC_SRA:
5846   - gen_arith_imm(ctx, op1, rd, rt, sa);
  5920 + gen_arith_imm(env, ctx, op1, rd, rt, sa);
5847 5921 break;
  5922 + case OPC_MOVZ ... OPC_MOVN:
  5923 + check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5848 5924 case OPC_SLLV: /* Arithmetic */
5849 5925 case OPC_SRLV ... OPC_SRAV:
5850   - case OPC_MOVZ ... OPC_MOVN:
5851 5926 case OPC_ADD ... OPC_NOR:
5852 5927 case OPC_SLT ... OPC_SLTU:
5853   - gen_arith(ctx, op1, rd, rs, rt);
  5928 + gen_arith(env, ctx, op1, rd, rs, rt);
5854 5929 break;
5855 5930 case OPC_MULT ... OPC_DIVU:
5856 5931 gen_muldiv(ctx, op1, rs, rt);
... ... @@ -5899,6 +5974,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5899 5974 break;
5900 5975  
5901 5976 case OPC_MOVCI:
  5977 + check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5902 5978 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5903 5979 save_cpu_state(ctx, 1);
5904 5980 check_cp1_enabled(ctx);
... ... @@ -5915,20 +5991,20 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5915 5991 case OPC_DSRL ... OPC_DSRA:
5916 5992 case OPC_DSLL32:
5917 5993 case OPC_DSRL32 ... OPC_DSRA32:
5918   - if (!(ctx->hflags & MIPS_HFLAG_64))
5919   - generate_exception(ctx, EXCP_RI);
5920   - gen_arith_imm(ctx, op1, rd, rt, sa);
  5994 + check_insn(env, ctx, ISA_MIPS3);
  5995 + check_mips_64(ctx);
  5996 + gen_arith_imm(env, ctx, op1, rd, rt, sa);
5921 5997 break;
5922 5998 case OPC_DSLLV:
5923 5999 case OPC_DSRLV ... OPC_DSRAV:
5924 6000 case OPC_DADD ... OPC_DSUBU:
5925   - if (!(ctx->hflags & MIPS_HFLAG_64))
5926   - generate_exception(ctx, EXCP_RI);
5927   - gen_arith(ctx, op1, rd, rs, rt);
  6001 + check_insn(env, ctx, ISA_MIPS3);
  6002 + check_mips_64(ctx);
  6003 + gen_arith(env, ctx, op1, rd, rs, rt);
5928 6004 break;
5929 6005 case OPC_DMULT ... OPC_DDIVU:
5930   - if (!(ctx->hflags & MIPS_HFLAG_64))
5931   - generate_exception(ctx, EXCP_RI);
  6006 + check_insn(env, ctx, ISA_MIPS3);
  6007 + check_mips_64(ctx);
5932 6008 gen_muldiv(ctx, op1, rs, rt);
5933 6009 break;
5934 6010 #endif
... ... @@ -5943,18 +6019,21 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5943 6019 switch (op1) {
5944 6020 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
5945 6021 case OPC_MSUB ... OPC_MSUBU:
  6022 + check_insn(env, ctx, ISA_MIPS32);
5946 6023 gen_muldiv(ctx, op1, rs, rt);
5947 6024 break;
5948 6025 case OPC_MUL:
5949   - gen_arith(ctx, op1, rd, rs, rt);
  6026 + gen_arith(env, ctx, op1, rd, rs, rt);
5950 6027 break;
5951 6028 case OPC_CLZ ... OPC_CLO:
  6029 + check_insn(env, ctx, ISA_MIPS32);
5952 6030 gen_cl(ctx, op1, rd, rs);
5953 6031 break;
5954 6032 case OPC_SDBBP:
5955 6033 /* XXX: not clear which exception should be raised
5956 6034 * when in debug mode...
5957 6035 */
  6036 + check_insn(env, ctx, ISA_MIPS32);
5958 6037 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5959 6038 generate_exception(ctx, EXCP_DBp);
5960 6039 } else {
... ... @@ -5964,8 +6043,8 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5964 6043 break;
5965 6044 #ifdef TARGET_MIPS64
5966 6045 case OPC_DCLZ ... OPC_DCLO:
5967   - if (!(ctx->hflags & MIPS_HFLAG_64))
5968   - generate_exception(ctx, EXCP_RI);
  6046 + check_insn(env, ctx, ISA_MIPS64);
  6047 + check_mips_64(ctx);
5969 6048 gen_cl(ctx, op1, rd, rs);
5970 6049 break;
5971 6050 #endif
... ... @@ -5976,14 +6055,15 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5976 6055 }
5977 6056 break;
5978 6057 case OPC_SPECIAL3:
5979   - check_mips_r2(env, ctx);
5980 6058 op1 = MASK_SPECIAL3(ctx->opcode);
5981 6059 switch (op1) {
5982 6060 case OPC_EXT:
5983 6061 case OPC_INS:
  6062 + check_insn(env, ctx, ISA_MIPS32R2);
5984 6063 gen_bitops(ctx, op1, rt, rs, sa, rd);
5985 6064 break;
5986 6065 case OPC_BSHFL:
  6066 + check_insn(env, ctx, ISA_MIPS32R2);
5987 6067 op2 = MASK_BSHFL(ctx->opcode);
5988 6068 switch (op2) {
5989 6069 case OPC_WSBH:
... ... @@ -6006,6 +6086,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
6006 6086 GEN_STORE_TN_REG(rd, T0);
6007 6087 break;
6008 6088 case OPC_RDHWR:
  6089 + check_insn(env, ctx, ISA_MIPS32R2);
6009 6090 switch (rd) {
6010 6091 case 0:
6011 6092 save_cpu_state(ctx, 1);
... ... @@ -6050,13 +6131,13 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
6050 6131 #ifdef TARGET_MIPS64
6051 6132 case OPC_DEXTM ... OPC_DEXT:
6052 6133 case OPC_DINSM ... OPC_DINS:
6053   - if (!(ctx->hflags & MIPS_HFLAG_64))
6054   - generate_exception(ctx, EXCP_RI);
  6134 + check_insn(env, ctx, ISA_MIPS64R2);
  6135 + check_mips_64(ctx);
6055 6136 gen_bitops(ctx, op1, rt, rs, sa, rd);
6056 6137 break;
6057 6138 case OPC_DBSHFL:
6058   - if (!(ctx->hflags & MIPS_HFLAG_64))
6059   - generate_exception(ctx, EXCP_RI);
  6139 + check_insn(env, ctx, ISA_MIPS64R2);
  6140 + check_mips_64(ctx);
6060 6141 op2 = MASK_DBSHFL(ctx->opcode);
6061 6142 switch (op2) {
6062 6143 case OPC_DSBH:
... ... @@ -6092,7 +6173,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
6092 6173 gen_trap(ctx, op1, rs, -1, imm);
6093 6174 break;
6094 6175 case OPC_SYNCI:
6095   - check_mips_r2(env, ctx);
  6176 + check_insn(env, ctx, ISA_MIPS32R2);
6096 6177 /* Treat as NOP. */
6097 6178 break;
6098 6179 default: /* Invalid */
... ... @@ -6120,7 +6201,6 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
6120 6201 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6121 6202 break;
6122 6203 case OPC_MFMC0:
6123   - check_mips_r2(env, ctx);
6124 6204 op2 = MASK_MFMC0(ctx->opcode);
6125 6205 switch (op2) {
6126 6206 case OPC_DMT:
... ... @@ -6140,11 +6220,13 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
6140 6220 gen_op_evpe();
6141 6221 break;
6142 6222 case OPC_DI:
  6223 + check_insn(env, ctx, ISA_MIPS32R2);
6143 6224 gen_op_di();
6144 6225 /* Stop translation as we may have switched the execution mode */
6145 6226 ctx->bstate = BS_STOP;
6146 6227 break;
6147 6228 case OPC_EI:
  6229 + check_insn(env, ctx, ISA_MIPS32R2);
6148 6230 gen_op_ei();
6149 6231 /* Stop translation as we may have switched the execution mode */
6150 6232 ctx->bstate = BS_STOP;
... ... @@ -6157,12 +6239,12 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
6157 6239 GEN_STORE_TN_REG(rt, T0);
6158 6240 break;
6159 6241 case OPC_RDPGPR:
6160   - check_mips_r2(env, ctx);
  6242 + check_insn(env, ctx, ISA_MIPS32R2);
6161 6243 GEN_LOAD_SRSREG_TN(T0, rt);
6162 6244 GEN_STORE_TN_REG(rd, T0);
6163 6245 break;
6164 6246 case OPC_WRPGPR:
6165   - check_mips_r2(env, ctx);
  6247 + check_insn(env, ctx, ISA_MIPS32R2);
6166 6248 GEN_LOAD_REG_TN(T0, rt);
6167 6249 GEN_STORE_TN_SRSREG(rd, T0);
6168 6250 break;
... ... @@ -6173,7 +6255,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
6173 6255 }
6174 6256 break;
6175 6257 case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
6176   - gen_arith_imm(ctx, op, rt, rs, imm);
  6258 + gen_arith_imm(env, ctx, op, rt, rs, imm);
6177 6259 break;
6178 6260 case OPC_J ... OPC_JAL: /* Jump */
6179 6261 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
... ... @@ -6191,9 +6273,11 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
6191 6273 gen_ldst(ctx, op, rt, rs, imm);
6192 6274 break;
6193 6275 case OPC_CACHE:
  6276 + check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6194 6277 /* Treat as NOP. */
6195 6278 break;
6196 6279 case OPC_PREF:
  6280 + check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6197 6281 /* Treat as NOP. */
6198 6282 break;
6199 6283  
... ... @@ -6219,21 +6303,24 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
6219 6303 switch (op1) {
6220 6304 case OPC_MFHC1:
6221 6305 case OPC_MTHC1:
6222   - check_mips_r2(env, ctx);
  6306 + check_insn(env, ctx, ISA_MIPS32R2);
6223 6307 case OPC_MFC1:
6224 6308 case OPC_CFC1:
6225 6309 case OPC_MTC1:
6226 6310 case OPC_CTC1:
  6311 + gen_cp1(ctx, op1, rt, rd);
  6312 + break;
6227 6313 #ifdef TARGET_MIPS64
6228 6314 case OPC_DMFC1:
6229 6315 case OPC_DMTC1:
6230   -#endif
  6316 + check_insn(env, ctx, ISA_MIPS3);
6231 6317 gen_cp1(ctx, op1, rt, rd);
6232 6318 break;
  6319 +#endif
6233 6320 case OPC_BC1:
6234 6321 case OPC_BC1ANY2:
6235 6322 case OPC_BC1ANY4:
6236   - gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
  6323 + gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
6237 6324 (rt >> 2) & 0x7, imm << 2);
6238 6325 return;
6239 6326 case OPC_S_FMT:
... ... @@ -6315,24 +6402,22 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
6315 6402 case OPC_LD:
6316 6403 case OPC_SCD:
6317 6404 case OPC_SD:
6318   - if (!(ctx->hflags & MIPS_HFLAG_64))
6319   - generate_exception(ctx, EXCP_RI);
  6405 + check_insn(env, ctx, ISA_MIPS3);
  6406 + check_mips_64(ctx);
6320 6407 gen_ldst(ctx, op, rt, rs, imm);
6321 6408 break;
6322 6409 case OPC_DADDI ... OPC_DADDIU:
6323   - if (!(ctx->hflags & MIPS_HFLAG_64))
6324   - generate_exception(ctx, EXCP_RI);
6325   - gen_arith_imm(ctx, op, rt, rs, imm);
  6410 + check_insn(env, ctx, ISA_MIPS3);
  6411 + check_mips_64(ctx);
  6412 + gen_arith_imm(env, ctx, op, rt, rs, imm);
6326 6413 break;
6327 6414 #endif
6328   -#ifdef MIPS_HAS_MIPS16
6329 6415 case OPC_JALX:
  6416 + check_insn(env, ctx, ASE_MIPS16);
6330 6417 /* MIPS16: Not implemented. */
6331   -#endif
6332   -#ifdef MIPS_HAS_MDMX
6333 6418 case OPC_MDMX:
  6419 + check_insn(env, ctx, ASE_MDMX);
6334 6420 /* MDMX: Not implemented. */
6335   -#endif
6336 6421 default: /* Invalid */
6337 6422 MIPS_INVAL("major opcode");
6338 6423 generate_exception(ctx, EXCP_RI);
... ...
target-mips/translate_init.c
... ... @@ -80,6 +80,7 @@ struct mips_def_t {
80 80 int32_t CP0_SRSConf3;
81 81 int32_t CP0_SRSConf4_rw_bitmask;
82 82 int32_t CP0_SRSConf4;
  83 + int insn_flags;
83 84 };
84 85  
85 86 /*****************************************************************************/
... ... @@ -98,6 +99,7 @@ static mips_def_t mips_defs[] =
98 99 .SYNCI_Step = 32,
99 100 .CCRes = 2,
100 101 .CP0_Status_rw_bitmask = 0x1278FF17,
  102 + .insn_flags = CPU_MIPS32 | ASE_MIPS16,
101 103 },
102 104 {
103 105 .name = "4KEcR1",
... ... @@ -111,6 +113,7 @@ static mips_def_t mips_defs[] =
111 113 .SYNCI_Step = 32,
112 114 .CCRes = 2,
113 115 .CP0_Status_rw_bitmask = 0x1278FF17,
  116 + .insn_flags = CPU_MIPS32 | ASE_MIPS16,
114 117 },
115 118 {
116 119 .name = "4KEc",
... ... @@ -124,6 +127,7 @@ static mips_def_t mips_defs[] =
124 127 .SYNCI_Step = 32,
125 128 .CCRes = 2,
126 129 .CP0_Status_rw_bitmask = 0x1278FF17,
  130 + .insn_flags = CPU_MIPS32R2 | ASE_MIPS16,
127 131 },
128 132 {
129 133 .name = "24Kc",
... ... @@ -138,6 +142,7 @@ static mips_def_t mips_defs[] =
138 142 .CCRes = 2,
139 143 /* No DSP implemented. */
140 144 .CP0_Status_rw_bitmask = 0x1278FF17,
  145 + .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP,
141 146 },
142 147 {
143 148 .name = "24Kf",
... ... @@ -154,6 +159,7 @@ static mips_def_t mips_defs[] =
154 159 .CP0_Status_rw_bitmask = 0x3678FF17,
155 160 .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
156 161 (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
  162 + .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP,
157 163 },
158 164 {
159 165 .name = "34Kf",
... ... @@ -193,6 +199,7 @@ static mips_def_t mips_defs[] =
193 199 .CP0_SRSConf4_rw_bitmask = 0x3fffffff,
194 200 .CP0_SRSConf4 = (0x3fe << CP0SRSC4_SRS15) |
195 201 (0x3fe << CP0SRSC4_SRS14) | (0x3fe << CP0SRSC4_SRS13),
  202 + .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP,
196 203 },
197 204 #ifdef TARGET_MIPS64
198 205 {
... ... @@ -210,6 +217,7 @@ static mips_def_t mips_defs[] =
210 217 /* The R4000 has a full 64bit FPU doesn't use the fcr0 bits. */
211 218 .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
212 219 .SEGBITS = 40,
  220 + .insn_flags = CPU_MIPS3,
213 221 },
214 222 {
215 223 .name = "5Kc",
... ... @@ -225,6 +233,7 @@ static mips_def_t mips_defs[] =
225 233 .CCRes = 2,
226 234 .CP0_Status_rw_bitmask = 0x32F8FFFF,
227 235 .SEGBITS = 42,
  236 + .insn_flags = CPU_MIPS64,
228 237 },
229 238 {
230 239 .name = "5Kf",
... ... @@ -243,6 +252,7 @@ static mips_def_t mips_defs[] =
243 252 .CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) |
244 253 (0x81 << FCR0_PRID) | (0x0 << FCR0_REV),
245 254 .SEGBITS = 42,
  255 + .insn_flags = CPU_MIPS64,
246 256 },
247 257 {
248 258 .name = "20Kc",
... ... @@ -264,6 +274,7 @@ static mips_def_t mips_defs[] =
264 274 (1 << FCR0_D) | (1 << FCR0_S) |
265 275 (0x82 << FCR0_PRID) | (0x0 << FCR0_REV),
266 276 .SEGBITS = 40,
  277 + .insn_flags = CPU_MIPS64 | ASE_MIPS3D,
267 278 },
268 279 #endif
269 280 };
... ... @@ -406,7 +417,7 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
406 417 env->CP0_TCStatus_rw_bitmask = def->CP0_TCStatus_rw_bitmask;
407 418 env->CP0_SRSCtl = def->CP0_SRSCtl;
408 419 #ifdef TARGET_MIPS64
409   - if ((env->CP0_Config0 & (0x3 << CP0C0_AT)))
  420 + if (def->insn_flags & ISA_MIPS3)
410 421 {
411 422 env->hflags |= MIPS_HFLAG_64;
412 423 env->SEGBITS = def->SEGBITS;
... ... @@ -426,6 +437,7 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def)
426 437 env->CP0_SRSConf3 = def->CP0_SRSConf3;
427 438 env->CP0_SRSConf4_rw_bitmask = def->CP0_SRSConf4_rw_bitmask;
428 439 env->CP0_SRSConf4 = def->CP0_SRSConf4;
  440 + env->insn_flags = def->insn_flags;
429 441  
430 442 #ifndef CONFIG_USER_ONLY
431 443 mmu_init(env, def);
... ...