Fix RDHWR handling. Code formatting. Don't use *_direct versions to raise
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Thu, 5 Apr 2007 23:16:25 +0000 (23:16 +0000)
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Thu, 5 Apr 2007 23:16:25 +0000 (23:16 +0000)
exceptions.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2611 c046a42c-6fe2-441c-8c8c-71466251a162

target-mips/op.c
target-mips/translate.c

index db430a7..d09b8da 100644 (file)
@@ -336,7 +336,7 @@ void op_addo (void)
     T0 = (int32_t)T0 + (int32_t)T1;
     if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) {
         /* operands of same sign, result different sign */
-        CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
+        CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
     }
     T0 = (int32_t)T0;
     RETURN();
@@ -356,7 +356,7 @@ void op_subo (void)
     T0 = (int32_t)T0 - (int32_t)T1;
     if (((tmp ^ T1) & (tmp ^ T0)) >> 31) {
         /* operands of different sign, first operand and result different sign */
-        CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
+        CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
     }
     T0 = (int32_t)T0;
     RETURN();
@@ -402,7 +402,7 @@ void op_daddo (void)
     T0 += T1;
     if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) {
         /* operands of same sign, result different sign */
-        CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
+        CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
     }
     RETURN();
 }
@@ -421,7 +421,7 @@ void op_dsubo (void)
     T0 = (int64_t)T0 - (int64_t)T1;
     if (((tmp ^ T1) & (tmp ^ T0)) >> 63) {
         /* operands of different sign, first operand and result different sign */
-        CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
+        CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW);
     }
     RETURN();
 }
@@ -1650,7 +1650,7 @@ void op_cp0_enabled(void)
 {
     if (!(env->CP0_Status & (1 << CP0St_CU0)) &&
        (env->hflags & MIPS_HFLAG_UM)) {
-        CALL_FROM_TB2(do_raise_exception_direct_err, EXCP_CpU, 0);
+        CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 0);
     }
     RETURN();
 }
@@ -1658,7 +1658,7 @@ void op_cp0_enabled(void)
 void op_cp1_enabled(void)
 {
     if (!(env->CP0_Status & (1 << CP0St_CU1))) {
-        CALL_FROM_TB2(do_raise_exception_direct_err, EXCP_CpU, 1);
+        CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 1);
     }
     RETURN();
 }
@@ -2063,7 +2063,7 @@ void op_ei (void)
 void op_trap (void)
 {
     if (T0) {
-        CALL_FROM_TB1(do_raise_exception_direct, EXCP_TRAP);
+        CALL_FROM_TB1(do_raise_exception, EXCP_TRAP);
     }
     RETURN();
 }
@@ -2116,37 +2116,67 @@ void op_deret (void)
 
 void op_rdhwr_cpunum(void)
 {
-    if (env->CP0_HWREna & (1 << 0))
-       T0 = env->CP0_EBase & 0x2ff;
+    if (!(env->hflags & MIPS_HFLAG_UM) ||
+       (env->CP0_HWREna & (1 << 0)) ||
+        (env->CP0_Status & (1 << CP0St_CU0)))
+        T0 = env->CP0_EBase & 0x3ff;
     else
-       CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
+        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
     RETURN();
 }
 
 void op_rdhwr_synci_step(void)
 {
-    if (env->CP0_HWREna & (1 << 1))
-       T0 = env->SYNCI_Step;
+    if (!(env->hflags & MIPS_HFLAG_UM) ||
+       (env->CP0_HWREna & (1 << 1)) ||
+        (env->CP0_Status & (1 << CP0St_CU0)))
+        T0 = env->SYNCI_Step;
     else
-       CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
+        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
     RETURN();
 }
 
 void op_rdhwr_cc(void)
 {
-    if (env->CP0_HWREna & (1 << 2))
-       T0 = env->CP0_Count;
+    if (!(env->hflags & MIPS_HFLAG_UM) ||
+       (env->CP0_HWREna & (1 << 2)) ||
+        (env->CP0_Status & (1 << CP0St_CU0)))
+        T0 = env->CP0_Count;
     else
-       CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
+        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
     RETURN();
 }
 
 void op_rdhwr_ccres(void)
 {
-    if (env->CP0_HWREna & (1 << 3))
-       T0 = env->CCRes;
+    if (!(env->hflags & MIPS_HFLAG_UM) ||
+       (env->CP0_HWREna & (1 << 3)) ||
+        (env->CP0_Status & (1 << CP0St_CU0)))
+        T0 = env->CCRes;
     else
-       CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI);
+        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
+    RETURN();
+}
+
+void op_rdhwr_unimpl30(void)
+{
+    if (!(env->hflags & MIPS_HFLAG_UM) ||
+       (env->CP0_HWREna & (1 << 30)) ||
+        (env->CP0_Status & (1 << CP0St_CU0)))
+        T0 = 0;
+    else
+        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
+    RETURN();
+}
+
+void op_rdhwr_unimpl31(void)
+{
+    if (!(env->hflags & MIPS_HFLAG_UM) ||
+       (env->CP0_HWREna & (1 << 31)) ||
+        (env->CP0_Status & (1 << CP0St_CU0)))
+        T0 = 0;
+    else
+        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
     RETURN();
 }
 
index 74bb42d..816b91e 100644 (file)
@@ -1762,7 +1762,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
            break;
         default:
             goto die;
-       }
+        }
         break;
     case 4:
         switch (sel) {
@@ -1776,7 +1776,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
 //         break;
         default:
             goto die;
-       }
+        }
         break;
     case 5:
         switch (sel) {
@@ -1790,7 +1790,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
            break;
         default:
             goto die;
-       }
+        }
         break;
     case 6:
         switch (sel) {
@@ -1820,7 +1820,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
 //         break;
         default:
             goto die;
-       }
+        }
         break;
     case 7:
         switch (sel) {
@@ -1830,7 +1830,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
            break;
         default:
             goto die;
-       }
+        }
         break;
     case 8:
         switch (sel) {
@@ -1861,7 +1861,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
            break;
         default:
             goto die;
-       }
+        }
         break;
     case 11:
         switch (sel) {
@@ -1914,7 +1914,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
            break;
         default:
             goto die;
-       }
+        }
         break;
     case 15:
         switch (sel) {
@@ -2521,7 +2521,7 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
            break;
         default:
             goto die;
-       }
+        }
         break;
     case 16:
         switch (sel) {
@@ -2955,7 +2955,7 @@ static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
            break;
         default:
             goto die;
-       }
+        }
         break;
     case 4:
         switch (sel) {
@@ -4703,83 +4703,92 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
         }
         break;
     case OPC_SPECIAL3:
-        op1 = MASK_SPECIAL3(ctx->opcode);
-        switch (op1) {
-        case OPC_EXT:
-        case OPC_INS:
-            gen_bitops(ctx, op1, rt, rs, sa, rd);
+         op1 = MASK_SPECIAL3(ctx->opcode);
+         switch (op1) {
+         case OPC_EXT:
+         case OPC_INS:
+             gen_bitops(ctx, op1, rt, rs, sa, rd);
+             break;
+         case OPC_BSHFL:
+             op2 = MASK_BSHFL(ctx->opcode);
+             switch (op2) {
+             case OPC_WSBH:
+                 GEN_LOAD_REG_TN(T1, rt);
+                 gen_op_wsbh();
+                 break;
+             case OPC_SEB:
+                 GEN_LOAD_REG_TN(T1, rt);
+                 gen_op_seb();
+                 break;
+             case OPC_SEH:
+                 GEN_LOAD_REG_TN(T1, rt);
+                 gen_op_seh();
+                 break;
+             default:            /* Invalid */
+                 MIPS_INVAL("bshfl");
+                 generate_exception(ctx, EXCP_RI);
+                 break;
+            }
+            GEN_STORE_TN_REG(rd, T0);
             break;
-        case OPC_BSHFL:
-            op2 = MASK_BSHFL(ctx->opcode);
-            switch (op2) {
-            case OPC_WSBH:
-                GEN_LOAD_REG_TN(T1, rt);
-                gen_op_wsbh();
+        case OPC_RDHWR:
+            switch (rd) {
+            case 0:
+                gen_op_rdhwr_cpunum();
                 break;
-            case OPC_SEB:
-                GEN_LOAD_REG_TN(T1, rt);
-                gen_op_seb();
+            case 1:
+                gen_op_rdhwr_synci_step();
                 break;
-            case OPC_SEH:
-                GEN_LOAD_REG_TN(T1, rt);
-                gen_op_seh();
+            case 2:
+                gen_op_rdhwr_cc();
                 break;
-             default:            /* Invalid */
-                MIPS_INVAL("bshfl");
-                generate_exception(ctx, EXCP_RI);
+            case 3:
+                gen_op_rdhwr_ccres();
                 break;
-           }
-           GEN_STORE_TN_REG(rd, T0);
-           break;
-       case OPC_RDHWR:
-           switch (rd) {
-           case 0:
-               gen_op_rdhwr_cpunum();
-               break;
-           case 1:
-               gen_op_rdhwr_synci_step();
-               break;
-           case 2:
-               gen_op_rdhwr_cc();
-               break;
-           case 3:
-               gen_op_rdhwr_ccres();
-               break;
+            case 29:
 #if defined (CONFIG_USER_ONLY)
-           case 29:
-               gen_op_tls_value ();
-               GEN_STORE_TN_REG(rt, T0);
-               break;
+                gen_op_tls_value ();
+#else
+                generate_exception(ctx, EXCP_RI);
 #endif
-           default:            /* Invalid */
-               MIPS_INVAL("rdhwr");
-               generate_exception(ctx, EXCP_RI);
-               break;
-           }
-           GEN_STORE_TN_REG(rt, T0);
-           break;
+                break;
+            case 30:
+                /* Implementation dependent */;
+                gen_op_rdhwr_unimpl30();
+                break;
+            case 31:
+                /* Implementation dependent */;
+                gen_op_rdhwr_unimpl31();
+                break;
+            default:            /* Invalid */
+                MIPS_INVAL("rdhwr");
+                generate_exception(ctx, EXCP_RI);
+                break;
+            }
+            GEN_STORE_TN_REG(rt, T0);
+            break;
 #ifdef TARGET_MIPS64
-       case OPC_DEXTM ... OPC_DEXT:
-       case OPC_DINSM ... OPC_DINS:
-           gen_bitops(ctx, op1, rt, rs, sa, rd);
+        case OPC_DEXTM ... OPC_DEXT:
+        case OPC_DINSM ... OPC_DINS:
+            gen_bitops(ctx, op1, rt, rs, sa, rd);
             break;
-       case OPC_DBSHFL:
-           op2 = MASK_DBSHFL(ctx->opcode);
-           switch (op2) {
-           case OPC_DSBH:
-               GEN_LOAD_REG_TN(T1, rt);
-               gen_op_dsbh();
-               break;
-           case OPC_DSHD:
-               GEN_LOAD_REG_TN(T1, rt);
-               gen_op_dshd();
-               break;
+        case OPC_DBSHFL:
+            op2 = MASK_DBSHFL(ctx->opcode);
+            switch (op2) {
+            case OPC_DSBH:
+                GEN_LOAD_REG_TN(T1, rt);
+                gen_op_dsbh();
+                break;
+            case OPC_DSHD:
+                GEN_LOAD_REG_TN(T1, rt);
+                gen_op_dshd();
+                break;
             default:            /* Invalid */
                 MIPS_INVAL("dbshfl");
                 generate_exception(ctx, EXCP_RI);
                 break;
-           }
-           GEN_STORE_TN_REG(rd, T0);
+            }
+            GEN_STORE_TN_REG(rd, T0);
 #endif
         default:            /* Invalid */
             MIPS_INVAL("special3");