qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH, MIPS] MIPS R1/R2 instructions decoding


From: Aurelien Jarno
Subject: [Qemu-devel] [PATCH, MIPS] MIPS R1/R2 instructions decoding
Date: Tue, 29 May 2007 00:15:01 +0200
User-agent: Mutt/1.5.13 (2006-08-11)

Hi,

In the current implementation of the MIPS CPU, all instructions are
regarded as valid, being R1 or R2 instructions.

This patch fixes that by generating a reserved instruction exception
when an R2 instructions is decoded on an R1 only CPU.

Note that I have left the FPU code unchanged, as I don't know a lot
about it. I will do the same later, after reading the FPU part of the 
manuals.

Bye,
Aurelien


Index: target-mips/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/translate.c,v
retrieving revision 1.89
diff -u -d -p -r1.89 translate.c
--- target-mips/translate.c     28 May 2007 20:36:48 -0000      1.89
+++ target-mips/translate.c     28 May 2007 20:42:03 -0000
@@ -1971,6 +1971,8 @@ static void gen_mfc0 (DisasContext *ctx,
             rn = "PageMask";
             break;
         case 1:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mfc0_pagegrain();
             rn = "PageGrain";
             break;
@@ -2011,6 +2013,8 @@ static void gen_mfc0 (DisasContext *ctx,
     case 7:
         switch (sel) {
         case 0:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mfc0_hwrena();
             rn = "HWREna";
             break;
@@ -2067,14 +2071,20 @@ static void gen_mfc0 (DisasContext *ctx,
             rn = "Status";
             break;
         case 1:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mfc0_intctl();
             rn = "IntCtl";
             break;
         case 2:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mfc0_srsctl();
             rn = "SRSCtl";
             break;
         case 3:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mfc0_srsmap();
             rn = "SRSMap";
             break;
@@ -2109,6 +2119,8 @@ static void gen_mfc0 (DisasContext *ctx,
             rn = "PRid";
             break;
         case 1:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mfc0_ebase();
             rn = "EBase";
             break;
@@ -2507,6 +2519,8 @@ static void gen_mtc0 (DisasContext *ctx,
             rn = "PageMask";
             break;
         case 1:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mtc0_pagegrain();
             rn = "PageGrain";
             break;
@@ -2547,6 +2561,8 @@ static void gen_mtc0 (DisasContext *ctx,
     case 7:
         switch (sel) {
         case 0:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mtc0_hwrena();
             rn = "HWREna";
             break;
@@ -2601,14 +2617,20 @@ static void gen_mtc0 (DisasContext *ctx,
             rn = "Status";
             break;
         case 1:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mtc0_intctl();
             rn = "IntCtl";
             break;
         case 2:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mtc0_srsctl();
             rn = "SRSCtl";
             break;
         case 3:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mtc0_srsmap();
             rn = "SRSMap";
             break;
@@ -2647,6 +2669,8 @@ static void gen_mtc0 (DisasContext *ctx,
             rn = "PRid";
             break;
         case 1:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mtc0_ebase();
             rn = "EBase";
             break;
@@ -3057,6 +3081,8 @@ static void gen_dmfc0 (DisasContext *ctx
             rn = "PageMask";
             break;
         case 1:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mfc0_pagegrain();
             rn = "PageGrain";
             break;
@@ -3097,6 +3123,8 @@ static void gen_dmfc0 (DisasContext *ctx
     case 7:
         switch (sel) {
         case 0:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mfc0_hwrena();
             rn = "HWREna";
             break;
@@ -3153,14 +3181,20 @@ static void gen_dmfc0 (DisasContext *ctx
             rn = "Status";
             break;
         case 1:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mfc0_intctl();
             rn = "IntCtl";
             break;
         case 2:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mfc0_srsctl();
             rn = "SRSCtl";
             break;
         case 3:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mfc0_srsmap(); /* shadow registers */
             rn = "SRSMap";
             break;
@@ -3195,6 +3229,8 @@ static void gen_dmfc0 (DisasContext *ctx
             rn = "PRid";
             break;
         case 1:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mfc0_ebase();
             rn = "EBase";
             break;
@@ -3584,6 +3620,8 @@ static void gen_dmtc0 (DisasContext *ctx
             rn = "PageMask";
             break;
         case 1:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mtc0_pagegrain();
             rn = "PageGrain";
             break;
@@ -3624,6 +3662,8 @@ static void gen_dmtc0 (DisasContext *ctx
     case 7:
         switch (sel) {
         case 0:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mtc0_hwrena();
             rn = "HWREna";
             break;
@@ -3678,14 +3718,20 @@ static void gen_dmtc0 (DisasContext *ctx
             rn = "Status";
             break;
         case 1:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mtc0_intctl();
             rn = "IntCtl";
             break;
         case 2:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mtc0_srsctl();
             rn = "SRSCtl";
             break;
         case 3:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mtc0_srsmap();
             rn = "SRSMap";
             break;
@@ -3724,6 +3770,8 @@ static void gen_dmtc0 (DisasContext *ctx
             rn = "PRid";
             break;
         case 1:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR)) 
+                goto die;                
             gen_op_mtc0_ebase();
             rn = "EBase";
             break;
@@ -5438,6 +5486,8 @@ static void decode_opc (CPUState *env, D
         }
         break;
     case OPC_SPECIAL3:
+         if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR))
+             generate_exception(ctx, EXCP_RI);
          op1 = MASK_SPECIAL3(ctx->opcode);
          switch (op1) {
          case OPC_EXT:
@@ -5541,6 +5591,8 @@ static void decode_opc (CPUState *env, D
             gen_trap(ctx, op1, rs, -1, imm);
             break;
         case OPC_SYNCI:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR))
+                generate_exception(ctx, EXCP_RI);
             /* treat as noop */
             break;
         default:            /* Invalid */
@@ -5566,6 +5618,8 @@ static void decode_opc (CPUState *env, D
             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
             break;
         case OPC_MFMC0:
+            if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR))
+                generate_exception(ctx, EXCP_RI);
             op2 = MASK_MFMC0(ctx->opcode);
             switch (op2) {
             case OPC_DI:
@@ -5647,6 +5701,10 @@ static void decode_opc (CPUState *env, D
             gen_op_cp1_enabled();
             op1 = MASK_CP1(ctx->opcode);
             switch (op1) {
+            case OPC_MFHC1:
+            case OPC_MTHC1:
+                if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) != (1 << CP0C0_AR))
+                    generate_exception(ctx, EXCP_RI);
             case OPC_MFC1:
             case OPC_CFC1:
             case OPC_MTC1:
@@ -5655,8 +5713,6 @@ static void decode_opc (CPUState *env, D
             case OPC_DMFC1:
             case OPC_DMTC1:
 #endif
-            case OPC_MFHC1:
-            case OPC_MTHC1:
                 gen_cp1(ctx, op1, rt, rd);
                 break;
             case OPC_BC1:

-- 
  .''`.  Aurelien Jarno             | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   address@hidden         | address@hidden
   `-    people.debian.org/~aurel32 | www.aurel32.net




reply via email to

[Prev in Thread] Current Thread [Next in Thread]