Revision e189e748 target-mips/translate.c
b/target-mips/translate.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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); |
Also available in: Unified diff