Commit 3a95e3a7d9a6fd7610fe483778ff7016d23be5ec

Authored by ths
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: