Commit 3a95e3a7d9a6fd7610fe483778ff7016d23be5ec
1 parent
2538deb2
Check for R2 instructions, and throw RI if we don't emulate R2.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2921 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
50 additions
and
18 deletions
target-mips/translate.c
@@ -732,6 +732,14 @@ void check_cp1_registers(DisasContext *ctx, int regs) | @@ -732,6 +732,14 @@ void check_cp1_registers(DisasContext *ctx, int regs) | ||
732 | generate_exception(ctx, EXCP_RI); | 732 | generate_exception(ctx, EXCP_RI); |
733 | } | 733 | } |
734 | 734 | ||
735 | +/* This code generates a "reserved instruction" exception if the | ||
736 | + CPU is not a MIPS R2 (or higher) CPU. */ | ||
737 | +static inline void check_mips_r2(CPUState *env, DisasContext *ctx) | ||
738 | +{ | ||
739 | + if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) < (1 << CP0C0_AR)) | ||
740 | + generate_exception(ctx, EXCP_RI); | ||
741 | +} | ||
742 | + | ||
735 | #if defined(CONFIG_USER_ONLY) | 743 | #if defined(CONFIG_USER_ONLY) |
736 | #define op_ldst(name) gen_op_##name##_raw() | 744 | #define op_ldst(name) gen_op_##name##_raw() |
737 | #define OP_LD_TABLE(width) | 745 | #define OP_LD_TABLE(width) |
@@ -1866,7 +1874,7 @@ fail: | @@ -1866,7 +1874,7 @@ fail: | ||
1866 | } | 1874 | } |
1867 | 1875 | ||
1868 | /* CP0 (MMU and control) */ | 1876 | /* CP0 (MMU and control) */ |
1869 | -static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | 1877 | +static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) |
1870 | { | 1878 | { |
1871 | const char *rn = "invalid"; | 1879 | const char *rn = "invalid"; |
1872 | 1880 | ||
@@ -2000,6 +2008,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | @@ -2000,6 +2008,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | ||
2000 | rn = "PageMask"; | 2008 | rn = "PageMask"; |
2001 | break; | 2009 | break; |
2002 | case 1: | 2010 | case 1: |
2011 | + check_mips_r2(env, ctx); | ||
2003 | gen_op_mfc0_pagegrain(); | 2012 | gen_op_mfc0_pagegrain(); |
2004 | rn = "PageGrain"; | 2013 | rn = "PageGrain"; |
2005 | break; | 2014 | break; |
@@ -2040,6 +2049,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | @@ -2040,6 +2049,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | ||
2040 | case 7: | 2049 | case 7: |
2041 | switch (sel) { | 2050 | switch (sel) { |
2042 | case 0: | 2051 | case 0: |
2052 | + check_mips_r2(env, ctx); | ||
2043 | gen_op_mfc0_hwrena(); | 2053 | gen_op_mfc0_hwrena(); |
2044 | rn = "HWREna"; | 2054 | rn = "HWREna"; |
2045 | break; | 2055 | break; |
@@ -2096,14 +2106,17 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | @@ -2096,14 +2106,17 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | ||
2096 | rn = "Status"; | 2106 | rn = "Status"; |
2097 | break; | 2107 | break; |
2098 | case 1: | 2108 | case 1: |
2109 | + check_mips_r2(env, ctx); | ||
2099 | gen_op_mfc0_intctl(); | 2110 | gen_op_mfc0_intctl(); |
2100 | rn = "IntCtl"; | 2111 | rn = "IntCtl"; |
2101 | break; | 2112 | break; |
2102 | case 2: | 2113 | case 2: |
2114 | + check_mips_r2(env, ctx); | ||
2103 | gen_op_mfc0_srsctl(); | 2115 | gen_op_mfc0_srsctl(); |
2104 | rn = "SRSCtl"; | 2116 | rn = "SRSCtl"; |
2105 | break; | 2117 | break; |
2106 | case 3: | 2118 | case 3: |
2119 | + check_mips_r2(env, ctx); | ||
2107 | gen_op_mfc0_srsmap(); | 2120 | gen_op_mfc0_srsmap(); |
2108 | rn = "SRSMap"; | 2121 | rn = "SRSMap"; |
2109 | break; | 2122 | break; |
@@ -2138,6 +2151,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | @@ -2138,6 +2151,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | ||
2138 | rn = "PRid"; | 2151 | rn = "PRid"; |
2139 | break; | 2152 | break; |
2140 | case 1: | 2153 | case 1: |
2154 | + check_mips_r2(env, ctx); | ||
2141 | gen_op_mfc0_ebase(); | 2155 | gen_op_mfc0_ebase(); |
2142 | rn = "EBase"; | 2156 | rn = "EBase"; |
2143 | break; | 2157 | break; |
@@ -2402,7 +2416,7 @@ die: | @@ -2402,7 +2416,7 @@ die: | ||
2402 | generate_exception(ctx, EXCP_RI); | 2416 | generate_exception(ctx, EXCP_RI); |
2403 | } | 2417 | } |
2404 | 2418 | ||
2405 | -static void gen_mtc0 (DisasContext *ctx, int reg, int sel) | 2419 | +static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) |
2406 | { | 2420 | { |
2407 | const char *rn = "invalid"; | 2421 | const char *rn = "invalid"; |
2408 | 2422 | ||
@@ -2536,6 +2550,7 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) | @@ -2536,6 +2550,7 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) | ||
2536 | rn = "PageMask"; | 2550 | rn = "PageMask"; |
2537 | break; | 2551 | break; |
2538 | case 1: | 2552 | case 1: |
2553 | + check_mips_r2(env, ctx); | ||
2539 | gen_op_mtc0_pagegrain(); | 2554 | gen_op_mtc0_pagegrain(); |
2540 | rn = "PageGrain"; | 2555 | rn = "PageGrain"; |
2541 | break; | 2556 | break; |
@@ -2576,6 +2591,7 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) | @@ -2576,6 +2591,7 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) | ||
2576 | case 7: | 2591 | case 7: |
2577 | switch (sel) { | 2592 | switch (sel) { |
2578 | case 0: | 2593 | case 0: |
2594 | + check_mips_r2(env, ctx); | ||
2579 | gen_op_mtc0_hwrena(); | 2595 | gen_op_mtc0_hwrena(); |
2580 | rn = "HWREna"; | 2596 | rn = "HWREna"; |
2581 | break; | 2597 | break; |
@@ -2633,18 +2649,21 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) | @@ -2633,18 +2649,21 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) | ||
2633 | rn = "Status"; | 2649 | rn = "Status"; |
2634 | break; | 2650 | break; |
2635 | case 1: | 2651 | case 1: |
2652 | + check_mips_r2(env, ctx); | ||
2636 | gen_op_mtc0_intctl(); | 2653 | gen_op_mtc0_intctl(); |
2637 | /* Stop translation as we may have switched the execution mode */ | 2654 | /* Stop translation as we may have switched the execution mode */ |
2638 | ctx->bstate = BS_STOP; | 2655 | ctx->bstate = BS_STOP; |
2639 | rn = "IntCtl"; | 2656 | rn = "IntCtl"; |
2640 | break; | 2657 | break; |
2641 | case 2: | 2658 | case 2: |
2659 | + check_mips_r2(env, ctx); | ||
2642 | gen_op_mtc0_srsctl(); | 2660 | gen_op_mtc0_srsctl(); |
2643 | /* Stop translation as we may have switched the execution mode */ | 2661 | /* Stop translation as we may have switched the execution mode */ |
2644 | ctx->bstate = BS_STOP; | 2662 | ctx->bstate = BS_STOP; |
2645 | rn = "SRSCtl"; | 2663 | rn = "SRSCtl"; |
2646 | break; | 2664 | break; |
2647 | case 3: | 2665 | case 3: |
2666 | + check_mips_r2(env, ctx); | ||
2648 | gen_op_mtc0_srsmap(); | 2667 | gen_op_mtc0_srsmap(); |
2649 | /* Stop translation as we may have switched the execution mode */ | 2668 | /* Stop translation as we may have switched the execution mode */ |
2650 | ctx->bstate = BS_STOP; | 2669 | ctx->bstate = BS_STOP; |
@@ -2683,6 +2702,7 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) | @@ -2683,6 +2702,7 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) | ||
2683 | rn = "PRid"; | 2702 | rn = "PRid"; |
2684 | break; | 2703 | break; |
2685 | case 1: | 2704 | case 1: |
2705 | + check_mips_r2(env, ctx); | ||
2686 | gen_op_mtc0_ebase(); | 2706 | gen_op_mtc0_ebase(); |
2687 | rn = "EBase"; | 2707 | rn = "EBase"; |
2688 | break; | 2708 | break; |
@@ -2970,7 +2990,7 @@ die: | @@ -2970,7 +2990,7 @@ die: | ||
2970 | } | 2990 | } |
2971 | 2991 | ||
2972 | #ifdef TARGET_MIPS64 | 2992 | #ifdef TARGET_MIPS64 |
2973 | -static void gen_dmfc0 (DisasContext *ctx, int reg, int sel) | 2993 | +static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) |
2974 | { | 2994 | { |
2975 | const char *rn = "invalid"; | 2995 | const char *rn = "invalid"; |
2976 | 2996 | ||
@@ -3104,6 +3124,7 @@ static void gen_dmfc0 (DisasContext *ctx, int reg, int sel) | @@ -3104,6 +3124,7 @@ static void gen_dmfc0 (DisasContext *ctx, int reg, int sel) | ||
3104 | rn = "PageMask"; | 3124 | rn = "PageMask"; |
3105 | break; | 3125 | break; |
3106 | case 1: | 3126 | case 1: |
3127 | + check_mips_r2(env, ctx); | ||
3107 | gen_op_mfc0_pagegrain(); | 3128 | gen_op_mfc0_pagegrain(); |
3108 | rn = "PageGrain"; | 3129 | rn = "PageGrain"; |
3109 | break; | 3130 | break; |
@@ -3144,6 +3165,7 @@ static void gen_dmfc0 (DisasContext *ctx, int reg, int sel) | @@ -3144,6 +3165,7 @@ static void gen_dmfc0 (DisasContext *ctx, int reg, int sel) | ||
3144 | case 7: | 3165 | case 7: |
3145 | switch (sel) { | 3166 | switch (sel) { |
3146 | case 0: | 3167 | case 0: |
3168 | + check_mips_r2(env, ctx); | ||
3147 | gen_op_mfc0_hwrena(); | 3169 | gen_op_mfc0_hwrena(); |
3148 | rn = "HWREna"; | 3170 | rn = "HWREna"; |
3149 | break; | 3171 | break; |
@@ -3200,14 +3222,17 @@ static void gen_dmfc0 (DisasContext *ctx, int reg, int sel) | @@ -3200,14 +3222,17 @@ static void gen_dmfc0 (DisasContext *ctx, int reg, int sel) | ||
3200 | rn = "Status"; | 3222 | rn = "Status"; |
3201 | break; | 3223 | break; |
3202 | case 1: | 3224 | case 1: |
3225 | + check_mips_r2(env, ctx); | ||
3203 | gen_op_mfc0_intctl(); | 3226 | gen_op_mfc0_intctl(); |
3204 | rn = "IntCtl"; | 3227 | rn = "IntCtl"; |
3205 | break; | 3228 | break; |
3206 | case 2: | 3229 | case 2: |
3230 | + check_mips_r2(env, ctx); | ||
3207 | gen_op_mfc0_srsctl(); | 3231 | gen_op_mfc0_srsctl(); |
3208 | rn = "SRSCtl"; | 3232 | rn = "SRSCtl"; |
3209 | break; | 3233 | break; |
3210 | case 3: | 3234 | case 3: |
3235 | + check_mips_r2(env, ctx); | ||
3211 | gen_op_mfc0_srsmap(); /* shadow registers */ | 3236 | gen_op_mfc0_srsmap(); /* shadow registers */ |
3212 | rn = "SRSMap"; | 3237 | rn = "SRSMap"; |
3213 | break; | 3238 | break; |
@@ -3242,6 +3267,7 @@ static void gen_dmfc0 (DisasContext *ctx, int reg, int sel) | @@ -3242,6 +3267,7 @@ static void gen_dmfc0 (DisasContext *ctx, int reg, int sel) | ||
3242 | rn = "PRid"; | 3267 | rn = "PRid"; |
3243 | break; | 3268 | break; |
3244 | case 1: | 3269 | case 1: |
3270 | + check_mips_r2(env, ctx); | ||
3245 | gen_op_mfc0_ebase(); | 3271 | gen_op_mfc0_ebase(); |
3246 | rn = "EBase"; | 3272 | rn = "EBase"; |
3247 | break; | 3273 | break; |
@@ -3497,7 +3523,7 @@ die: | @@ -3497,7 +3523,7 @@ die: | ||
3497 | generate_exception(ctx, EXCP_RI); | 3523 | generate_exception(ctx, EXCP_RI); |
3498 | } | 3524 | } |
3499 | 3525 | ||
3500 | -static void gen_dmtc0 (DisasContext *ctx, int reg, int sel) | 3526 | +static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) |
3501 | { | 3527 | { |
3502 | const char *rn = "invalid"; | 3528 | const char *rn = "invalid"; |
3503 | 3529 | ||
@@ -3631,6 +3657,7 @@ static void gen_dmtc0 (DisasContext *ctx, int reg, int sel) | @@ -3631,6 +3657,7 @@ static void gen_dmtc0 (DisasContext *ctx, int reg, int sel) | ||
3631 | rn = "PageMask"; | 3657 | rn = "PageMask"; |
3632 | break; | 3658 | break; |
3633 | case 1: | 3659 | case 1: |
3660 | + check_mips_r2(env, ctx); | ||
3634 | gen_op_mtc0_pagegrain(); | 3661 | gen_op_mtc0_pagegrain(); |
3635 | rn = "PageGrain"; | 3662 | rn = "PageGrain"; |
3636 | break; | 3663 | break; |
@@ -3671,6 +3698,7 @@ static void gen_dmtc0 (DisasContext *ctx, int reg, int sel) | @@ -3671,6 +3698,7 @@ static void gen_dmtc0 (DisasContext *ctx, int reg, int sel) | ||
3671 | case 7: | 3698 | case 7: |
3672 | switch (sel) { | 3699 | switch (sel) { |
3673 | case 0: | 3700 | case 0: |
3701 | + check_mips_r2(env, ctx); | ||
3674 | gen_op_mtc0_hwrena(); | 3702 | gen_op_mtc0_hwrena(); |
3675 | rn = "HWREna"; | 3703 | rn = "HWREna"; |
3676 | break; | 3704 | break; |
@@ -3728,18 +3756,21 @@ static void gen_dmtc0 (DisasContext *ctx, int reg, int sel) | @@ -3728,18 +3756,21 @@ static void gen_dmtc0 (DisasContext *ctx, int reg, int sel) | ||
3728 | rn = "Status"; | 3756 | rn = "Status"; |
3729 | break; | 3757 | break; |
3730 | case 1: | 3758 | case 1: |
3759 | + check_mips_r2(env, ctx); | ||
3731 | gen_op_mtc0_intctl(); | 3760 | gen_op_mtc0_intctl(); |
3732 | /* Stop translation as we may have switched the execution mode */ | 3761 | /* Stop translation as we may have switched the execution mode */ |
3733 | ctx->bstate = BS_STOP; | 3762 | ctx->bstate = BS_STOP; |
3734 | rn = "IntCtl"; | 3763 | rn = "IntCtl"; |
3735 | break; | 3764 | break; |
3736 | case 2: | 3765 | case 2: |
3766 | + check_mips_r2(env, ctx); | ||
3737 | gen_op_mtc0_srsctl(); | 3767 | gen_op_mtc0_srsctl(); |
3738 | /* Stop translation as we may have switched the execution mode */ | 3768 | /* Stop translation as we may have switched the execution mode */ |
3739 | ctx->bstate = BS_STOP; | 3769 | ctx->bstate = BS_STOP; |
3740 | rn = "SRSCtl"; | 3770 | rn = "SRSCtl"; |
3741 | break; | 3771 | break; |
3742 | case 3: | 3772 | case 3: |
3773 | + check_mips_r2(env, ctx); | ||
3743 | gen_op_mtc0_srsmap(); | 3774 | gen_op_mtc0_srsmap(); |
3744 | /* Stop translation as we may have switched the execution mode */ | 3775 | /* Stop translation as we may have switched the execution mode */ |
3745 | ctx->bstate = BS_STOP; | 3776 | ctx->bstate = BS_STOP; |
@@ -3778,6 +3809,7 @@ static void gen_dmtc0 (DisasContext *ctx, int reg, int sel) | @@ -3778,6 +3809,7 @@ static void gen_dmtc0 (DisasContext *ctx, int reg, int sel) | ||
3778 | rn = "PRid"; | 3809 | rn = "PRid"; |
3779 | break; | 3810 | break; |
3780 | case 1: | 3811 | case 1: |
3812 | + check_mips_r2(env, ctx); | ||
3781 | gen_op_mtc0_ebase(); | 3813 | gen_op_mtc0_ebase(); |
3782 | rn = "EBase"; | 3814 | rn = "EBase"; |
3783 | break; | 3815 | break; |
@@ -4064,13 +4096,13 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int | @@ -4064,13 +4096,13 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int | ||
4064 | /* Treat as NOP */ | 4096 | /* Treat as NOP */ |
4065 | return; | 4097 | return; |
4066 | } | 4098 | } |
4067 | - gen_mfc0(ctx, rd, ctx->opcode & 0x7); | 4099 | + gen_mfc0(env, ctx, rd, ctx->opcode & 0x7); |
4068 | gen_op_store_T0_gpr(rt); | 4100 | gen_op_store_T0_gpr(rt); |
4069 | opn = "mfc0"; | 4101 | opn = "mfc0"; |
4070 | break; | 4102 | break; |
4071 | case OPC_MTC0: | 4103 | case OPC_MTC0: |
4072 | GEN_LOAD_REG_TN(T0, rt); | 4104 | GEN_LOAD_REG_TN(T0, rt); |
4073 | - gen_mtc0(ctx, rd, ctx->opcode & 0x7); | 4105 | + gen_mtc0(env, ctx, rd, ctx->opcode & 0x7); |
4074 | opn = "mtc0"; | 4106 | opn = "mtc0"; |
4075 | break; | 4107 | break; |
4076 | #ifdef TARGET_MIPS64 | 4108 | #ifdef TARGET_MIPS64 |
@@ -4079,13 +4111,13 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int | @@ -4079,13 +4111,13 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int | ||
4079 | /* Treat as NOP */ | 4111 | /* Treat as NOP */ |
4080 | return; | 4112 | return; |
4081 | } | 4113 | } |
4082 | - gen_dmfc0(ctx, rd, ctx->opcode & 0x7); | 4114 | + gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7); |
4083 | gen_op_store_T0_gpr(rt); | 4115 | gen_op_store_T0_gpr(rt); |
4084 | opn = "dmfc0"; | 4116 | opn = "dmfc0"; |
4085 | break; | 4117 | break; |
4086 | case OPC_DMTC0: | 4118 | case OPC_DMTC0: |
4087 | GEN_LOAD_REG_TN(T0, rt); | 4119 | GEN_LOAD_REG_TN(T0, rt); |
4088 | - gen_dmtc0(ctx, rd, ctx->opcode & 0x7); | 4120 | + gen_dmtc0(env,ctx, rd, ctx->opcode & 0x7); |
4089 | opn = "dmtc0"; | 4121 | opn = "dmtc0"; |
4090 | break; | 4122 | break; |
4091 | #endif | 4123 | #endif |
@@ -5501,6 +5533,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -5501,6 +5533,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
5501 | } | 5533 | } |
5502 | break; | 5534 | break; |
5503 | case OPC_SPECIAL3: | 5535 | case OPC_SPECIAL3: |
5536 | + check_mips_r2(env, ctx); | ||
5504 | op1 = MASK_SPECIAL3(ctx->opcode); | 5537 | op1 = MASK_SPECIAL3(ctx->opcode); |
5505 | switch (op1) { | 5538 | switch (op1) { |
5506 | case OPC_EXT: | 5539 | case OPC_EXT: |
@@ -5604,6 +5637,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -5604,6 +5637,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
5604 | gen_trap(ctx, op1, rs, -1, imm); | 5637 | gen_trap(ctx, op1, rs, -1, imm); |
5605 | break; | 5638 | break; |
5606 | case OPC_SYNCI: | 5639 | case OPC_SYNCI: |
5640 | + check_mips_r2(env, ctx); | ||
5607 | /* treat as noop */ | 5641 | /* treat as noop */ |
5608 | break; | 5642 | break; |
5609 | default: /* Invalid */ | 5643 | default: /* Invalid */ |
@@ -5629,6 +5663,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -5629,6 +5663,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
5629 | gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); | 5663 | gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); |
5630 | break; | 5664 | break; |
5631 | case OPC_MFMC0: | 5665 | case OPC_MFMC0: |
5666 | + check_mips_r2(env, ctx); | ||
5632 | op2 = MASK_MFMC0(ctx->opcode); | 5667 | op2 = MASK_MFMC0(ctx->opcode); |
5633 | switch (op2) { | 5668 | switch (op2) { |
5634 | case OPC_DI: | 5669 | case OPC_DI: |
@@ -5650,14 +5685,10 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -5650,14 +5685,10 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
5650 | break; | 5685 | break; |
5651 | case OPC_RDPGPR: | 5686 | case OPC_RDPGPR: |
5652 | case OPC_WRPGPR: | 5687 | case OPC_WRPGPR: |
5653 | - if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR)) { | ||
5654 | - /* Shadow registers not implemented. */ | ||
5655 | - GEN_LOAD_REG_TN(T0, rt); | ||
5656 | - GEN_STORE_TN_REG(rd, T0); | ||
5657 | - } else { | ||
5658 | - MIPS_INVAL("shadow register move"); | ||
5659 | - generate_exception(ctx, EXCP_RI); | ||
5660 | - } | 5688 | + check_mips_r2(env, ctx); |
5689 | + /* Shadow registers not implemented. */ | ||
5690 | + GEN_LOAD_REG_TN(T0, rt); | ||
5691 | + GEN_STORE_TN_REG(rd, T0); | ||
5661 | break; | 5692 | break; |
5662 | default: | 5693 | default: |
5663 | MIPS_INVAL("cp0"); | 5694 | MIPS_INVAL("cp0"); |
@@ -5710,6 +5741,9 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -5710,6 +5741,9 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
5710 | check_cp1_enabled(ctx); | 5741 | check_cp1_enabled(ctx); |
5711 | op1 = MASK_CP1(ctx->opcode); | 5742 | op1 = MASK_CP1(ctx->opcode); |
5712 | switch (op1) { | 5743 | switch (op1) { |
5744 | + case OPC_MFHC1: | ||
5745 | + case OPC_MTHC1: | ||
5746 | + check_mips_r2(env, ctx); | ||
5713 | case OPC_MFC1: | 5747 | case OPC_MFC1: |
5714 | case OPC_CFC1: | 5748 | case OPC_CFC1: |
5715 | case OPC_MTC1: | 5749 | case OPC_MTC1: |
@@ -5718,8 +5752,6 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -5718,8 +5752,6 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
5718 | case OPC_DMFC1: | 5752 | case OPC_DMFC1: |
5719 | case OPC_DMTC1: | 5753 | case OPC_DMTC1: |
5720 | #endif | 5754 | #endif |
5721 | - case OPC_MFHC1: | ||
5722 | - case OPC_MTHC1: | ||
5723 | gen_cp1(ctx, op1, rt, rd); | 5755 | gen_cp1(ctx, op1, rt, rd); |
5724 | break; | 5756 | break; |
5725 | case OPC_BC1: | 5757 | case OPC_BC1: |