Fix enough FPU/R2 support to get 24Kf going.
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 23 Mar 2007 00:43:28 +0000 (00:43 +0000)
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 23 Mar 2007 00:43:28 +0000 (00:43 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2528 c046a42c-6fe2-441c-8c8c-71466251a162

target-mips/cpu.h
target-mips/exec.h
target-mips/op.c
target-mips/op_helper.c
target-mips/translate.c

index 276910aaedc24d2c4852d06c64ff1fdb30ba89b5..f0f3ab2d73892db8179b66380aede31d5216ec8f 100644 (file)
@@ -203,6 +203,8 @@ struct CPUMIPSState {
 #define CP0C3_MT   2
 #define CP0C3_SM   1
 #define CP0C3_TL   0
+    int32_t CP0_Config6;
+    int32_t CP0_Config7;
     target_ulong CP0_LLAddr;
     target_ulong CP0_WatchLo;
     int32_t CP0_WatchHi;
index 877221e5617908539ebe141cede5965c3df6eb94..9816d4246a6d22494e7fe83d083193e8269890e1 100644 (file)
@@ -152,6 +152,7 @@ void invalidate_tlb (CPUState *env, int idx, int use_extra);
 void cpu_loop_exit(void);
 void do_raise_exception_err (uint32_t exception, int error_code);
 void do_raise_exception (uint32_t exception);
+void do_raise_exception_direct_err (uint32_t exception, int error_code);
 void do_raise_exception_direct (uint32_t exception);
 
 void cpu_dump_state(CPUState *env, FILE *f, 
index a286cefe5d0bd097b3889bee37073c9d19f4b3ee..f97ec429286746da3231fc59c4741f2a13cca996 100644 (file)
@@ -1180,6 +1180,18 @@ void op_mfc0_config3 (void)
     RETURN();
 }
 
+void op_mfc0_config6 (void)
+{
+    T0 = env->CP0_Config6;
+    RETURN();
+}
+
+void op_mfc0_config7 (void)
+{
+    T0 = env->CP0_Config7;
+    RETURN();
+}
+
 void op_mfc0_lladdr (void)
 {
     T0 = (int32_t)env->CP0_LLAddr >> 4;
@@ -1653,7 +1665,7 @@ void op_dmtc0_errorepc (void)
 void op_cp1_enabled(void)
 {
     if (!(env->CP0_Status & (1 << CP0St_CU1))) {
-        CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 1);
+        CALL_FROM_TB2(do_raise_exception_direct_err, EXCP_CpU, 1);
     }
     RETURN();
 }
index a262ea6684925b1d089e4e736ce8fad1e6eeb669..8ab7bf57d49e19ba864ef27d31eb6035ce74aa71 100644 (file)
@@ -56,10 +56,15 @@ void do_restore_state (void *pc_ptr)
   cpu_restore_state (tb, env, pc, NULL);
 }
 
-void do_raise_exception_direct (uint32_t exception)
+void do_raise_exception_direct_err (uint32_t exception, int error_code)
 {
     do_restore_state (GETPC ());
-    do_raise_exception_err (exception, 0);
+    do_raise_exception_err (exception, error_code);
+}
+
+void do_raise_exception_direct (uint32_t exception)
+{
+    do_raise_exception_direct_err (exception, 0);
 }
 
 #define MEMSUFFIX _raw
index 89061db9aaba6c1b87427c05832334dacb1d6b68..5cc922b57eaf63acb1090500a5eaae459be3aec4 100644 (file)
@@ -829,7 +829,7 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
         break;
     default:
         MIPS_INVAL("float load/store");
-        generate_exception_err(ctx, EXCP_CpU, 1);
+        generate_exception(ctx, EXCP_RI);
         return;
     }
     MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
@@ -1932,22 +1932,31 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
     case 16:
         switch (sel) {
         case 0:
-           gen_op_mfc0_config0();
+            gen_op_mfc0_config0();
             rn = "Config";
             break;
         case 1:
-           gen_op_mfc0_config1();
+            gen_op_mfc0_config1();
             rn = "Config1";
             break;
         case 2:
-           gen_op_mfc0_config2();
+            gen_op_mfc0_config2();
             rn = "Config2";
             break;
         case 3:
-           gen_op_mfc0_config3();
+            gen_op_mfc0_config3();
             rn = "Config3";
             break;
-       /* 6,7 are implementation dependent */
+        /* 4,5 are reserved */
+        /* 6,7 are implementation dependent */
+        case 6:
+            gen_op_mfc0_config6();
+            rn = "Config6";
+            break;
+        case 7:
+            gen_op_mfc0_config7();
+            rn = "Config7";
+            break;
         default:
             goto die;
         }
@@ -2516,28 +2525,37 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
     case 16:
         switch (sel) {
         case 0:
-           gen_op_mtc0_config0();
+            gen_op_mtc0_config0();
             rn = "Config";
             break;
         case 1:
-           /* ignored */
+            /* ignored, read only */
             rn = "Config1";
             break;
         case 2:
-           gen_op_mtc0_config2();
+            gen_op_mtc0_config2();
             rn = "Config2";
             break;
         case 3:
-           /* ignored */
+            /* ignored, read only */
             rn = "Config3";
             break;
-       /* 6,7 are implementation dependent */
+        /* 4,5 are reserved */
+        /* 6,7 are implementation dependent */
+        case 6:
+            /* ignored */
+            rn = "Config6";
+            break;
+        case 7:
+            /* ignored */
+            rn = "Config7";
+            break;
         default:
             rn = "Invalid config selector";
             goto die;
         }
-       /* Stop translation as we may have switched the execution mode */
-       ctx->bstate = BS_STOP;
+        /* Stop translation as we may have switched the execution mode */
+        ctx->bstate = BS_STOP;
         break;
     case 17:
         switch (sel) {
@@ -4140,7 +4158,7 @@ static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
         break;
     default:    
         MIPS_INVAL("cp1 branch/jump");
-        generate_exception_err (ctx, EXCP_RI, 1);
+        generate_exception (ctx, EXCP_RI);
         return;
     }
     gen_op_set_bcond();
@@ -4173,7 +4191,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
     case OPC_CFC1:
         if (fs != 0 && fs != 31) {
             MIPS_INVAL("cfc1 freg");
-            generate_exception_err (ctx, EXCP_RI, 1);
+            generate_exception (ctx, EXCP_RI);
             return;
         }
         GEN_LOAD_IMM_TN(T1, fs);
@@ -4184,7 +4202,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
     case OPC_CTC1:
          if (fs != 0 && fs != 31) {
             MIPS_INVAL("ctc1 freg");
-            generate_exception_err (ctx, EXCP_RI, 1);
+            generate_exception (ctx, EXCP_RI);
             return;
         }
         GEN_LOAD_IMM_TN(T1, fs);
@@ -4201,7 +4219,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
                     ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
                     ((ctx->opcode >> 16) & 0x1F));
         }
-        generate_exception_err (ctx, EXCP_RI, 1);
+        generate_exception (ctx, EXCP_RI);
         return;
     }
     MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
@@ -4219,7 +4237,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
  */
 #define CHECK_FR(ctx, freg) do { \
         if (!((ctx)->CP0_Status & (1<<CP0St_FR)) && ((freg) & 1)) { \
-            generate_exception_err (ctx, EXCP_RI, 1); \
+            generate_exception (ctx, EXCP_RI); \
             return; \
         } \
     } while(0)
@@ -4504,7 +4522,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd)
                     ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
                     ((ctx->opcode >> 16) & 0x1F));
         }
-        generate_exception_err (ctx, EXCP_RI, 1);
+        generate_exception (ctx, EXCP_RI);
         return;
     }
     if (binary)
@@ -4627,11 +4645,12 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
 
         case OPC_MOVCI:
             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
+                save_cpu_state(ctx, 1);
                 gen_op_cp1_enabled();
                 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
                           (ctx->opcode >> 16) & 1);
             } else {
-                generate_exception(ctx, EXCP_RI);
+                generate_exception_err(ctx, EXCP_CpU, 1);
             }
             break;
 
@@ -4905,7 +4924,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
                 gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa);
                 break;
             default:
-                generate_exception_err(ctx, EXCP_RI, 1);
+                generate_exception (ctx, EXCP_RI);
                 break;
             }
         } else {
@@ -4925,16 +4944,17 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
 
     case OPC_CP3:
         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
+            save_cpu_state(ctx, 1);
             gen_op_cp1_enabled();
             op1 = MASK_CP3(ctx->opcode);
             switch (op1) {
             /* Not implemented */
             default:
-                generate_exception_err(ctx, EXCP_RI, 1);
+                generate_exception (ctx, EXCP_RI);
                 break;
             }
         } else {
-            generate_exception(ctx, EXCP_RI);
+            generate_exception_err(ctx, EXCP_CpU, 1);
         }
         break;