]> xenbits.xensource.com Git - qemu-xen-4.0-testing.git/commitdiff
Don't check the FPU state for each FPU instruction, use hflags to
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Tue, 29 May 2007 16:52:57 +0000 (16:52 +0000)
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Tue, 29 May 2007 16:52:57 +0000 (16:52 +0000)
handle this per-tb.

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

target-mips/cpu.h
target-mips/fop_template.c
target-mips/op.c
target-mips/translate.c

index 17ac4ac8759d377509f4fbe2deed943f18a96b84..2736614cd4783dfdf16e489733719433a39f1cce 100644 (file)
@@ -258,9 +258,11 @@ struct CPUMIPSState {
 #define MIPS_HFLAG_TMASK  0x007F
 #define MIPS_HFLAG_MODE   0x001F /* execution modes                    */
 #define MIPS_HFLAG_UM     0x0001 /* user mode                          */
-#define MIPS_HFLAG_DM     0x0008 /* Debug mode                         */
-#define MIPS_HFLAG_SM     0x0010 /* Supervisor mode                    */
-#define MIPS_HFLAG_64     0x0020 /* 64-bit instructions enabled        */
+#define MIPS_HFLAG_DM     0x0002 /* Debug mode                         */
+#define MIPS_HFLAG_SM     0x0004 /* Supervisor mode                    */
+#define MIPS_HFLAG_64     0x0008 /* 64-bit instructions enabled        */
+#define MIPS_HFLAG_FPU    0x0010 /* FPU enabled                        */
+#define MIPS_HFLAG_F64    0x0020 /* 64-bit FPU enabled                 */
 #define MIPS_HFLAG_RE     0x0040 /* Reversed endianness                */
     /* If translation is interrupted between the branch instruction and
      * the delay slot, record what type of branch it is so that we can
index bb288f11eef8e79be6507af575ec35ee2bde577b..0f1595ff87d6e123e0512f30d813f2d43cf87ed4 100644 (file)
@@ -49,7 +49,7 @@ OP_WSTORE_FREG(WT2, WT2_fpr, FREG)
 #define OP_DLOAD_FREG(treg, tregname, FREG)              \
     void glue(glue(op_load_fpr_,tregname), FREG) (void)  \
     {                                                    \
-        if (env->CP0_Status & (1 << CP0St_FR))           \
+        if (env->hflags & MIPS_HFLAG_F64)                \
             treg = env->fpr[FREG].fd;                    \
         else                                             \
             treg = (uint64_t)(env->fpr[FREG | 1].fs[FP_ENDIAN_IDX]) << 32 | \
@@ -60,7 +60,7 @@ OP_WSTORE_FREG(WT2, WT2_fpr, FREG)
 #define OP_DSTORE_FREG(treg, tregname, FREG)             \
     void glue(glue(op_store_fpr_,tregname), FREG) (void) \
     {                                                    \
-        if (env->CP0_Status & (1 << CP0St_FR))           \
+        if (env->hflags & MIPS_HFLAG_F64)                \
             env->fpr[FREG].fd = treg;                    \
         else {                                           \
             env->fpr[FREG | 1].fs[FP_ENDIAN_IDX] = treg >> 32; \
index bc4d51a8f8b1e3e1aa1623a6eaf5de599956031e..a65977af4cba661370b6d4e0c5725247b653a828 100644 (file)
@@ -1349,8 +1349,7 @@ void op_mtc0_status (void)
     uint32_t val, old;
     uint32_t mask = env->Status_rw_bitmask;
 
-    /* No reverse endianness, no MDMX/DSP, no 64bit ops
-       implemented. */
+    /* No reverse endianness, no MDMX/DSP implemented. */
     val = T0 & mask;
     old = env->CP0_Status;
     if (!(val & (1 << CP0St_EXL)) &&
@@ -1364,6 +1363,14 @@ void op_mtc0_status (void)
         !(val & (1 << CP0St_UX)))
         env->hflags &= ~MIPS_HFLAG_64;
 #endif
+    if (val & (1 << CP0St_CU1))
+        env->hflags |= MIPS_HFLAG_FPU;
+    else
+        env->hflags &= ~MIPS_HFLAG_FPU;
+    if (val & (1 << CP0St_FR))
+        env->hflags |= MIPS_HFLAG_F64;
+    else
+        env->hflags &= ~MIPS_HFLAG_F64;
     env->CP0_Status = (env->CP0_Status & ~mask) | val;
     if (loglevel & CPU_LOG_EXEC)
         CALL_FROM_TB2(do_mtc0_status_debug, old, val);
@@ -1606,41 +1613,6 @@ void op_cp0_enabled(void)
     RETURN();
 }
 
-void op_cp1_enabled(void)
-{
-    if (!(env->CP0_Status & (1 << CP0St_CU1))) {
-        CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 1);
-    }
-    RETURN();
-}
-
-void op_cp1_64bitmode(void)
-{
-    if (!(env->CP0_Status & (1 << CP0St_FR))) {
-        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
-    }
-    RETURN();
-}
-
-/*
- * Verify if floating point register is valid; an operation is not defined
- * if bit 0 of any register specification is set and the FR bit in the
- * Status register equals zero, since the register numbers specify an
- * even-odd pair of adjacent coprocessor general registers. When the FR bit
- * in the Status register equals one, both even and odd register numbers
- * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
- *
- * Multiple 64 bit wide registers can be checked by calling
- * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
- */
-void op_cp1_registers(void)
-{
-    if (!(env->CP0_Status & (1 << CP0St_FR)) && (PARAM1 & 1)) {
-        CALL_FROM_TB1(do_raise_exception, EXCP_RI);
-    }
-    RETURN();
-}
-
 void op_cfc1 (void)
 {
     switch (T1) {
index c0f2b812296b1eef05207a9a5230c55b144ab0fe..e092439cfbfa8ccd7dec270685b0813f04cf739d 100644 (file)
@@ -703,6 +703,35 @@ static inline void generate_exception (DisasContext *ctx, int excp)
     generate_exception_err (ctx, excp, 0);
 }
 
+static inline void check_cp1_enabled(DisasContext *ctx)
+{
+    if (!(ctx->hflags & MIPS_HFLAG_FPU))
+        generate_exception_err(ctx, EXCP_CpU, 1);
+}
+
+static inline void check_cp1_64bitmode(DisasContext *ctx)
+{
+    if (!(ctx->hflags & MIPS_HFLAG_F64))
+        generate_exception(ctx, EXCP_RI);
+}
+
+/*
+ * Verify if floating point register is valid; an operation is not defined
+ * if bit 0 of any register specification is set and the FR bit in the
+ * Status register equals zero, since the register numbers specify an
+ * even-odd pair of adjacent coprocessor general registers. When the FR bit
+ * in the Status register equals one, both even and odd register numbers
+ * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
+ *
+ * Multiple 64 bit wide registers can be checked by calling
+ * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
+ */
+void check_cp1_registers(DisasContext *ctx, int regs)
+{
+    if (!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))
+        generate_exception(ctx, EXCP_RI);
+}
+
 #if defined(CONFIG_USER_ONLY)
 #define op_ldst(name)        gen_op_##name##_raw()
 #define OP_LD_TABLE(width)
@@ -4243,8 +4272,8 @@ GEN_MOVCF(s);
 GEN_MOVCF(ps);
 #undef GEN_MOVCF
 
-static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
-                        int fs, int fd, int cc)
+static void gen_farith (DisasContext *ctx, uint32_t op1,
+                        int ft, int fs, int fd, int cc)
 {
     const char *opn = "farith";
     const char *condnames[] = {
@@ -4344,28 +4373,28 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "neg.s";
         break;
     case FOP(8, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_roundl_s();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "round.l.s";
         break;
     case FOP(9, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_truncl_s();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "trunc.l.s";
         break;
     case FOP(10, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_ceill_s();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "ceil.l.s";
         break;
     case FOP(11, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_floorl_s();
         GEN_STORE_FTN_FREG(fd, DT2);
@@ -4432,7 +4461,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "rsqrt.s";
         break;
     case FOP(28, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WT2, fd);
         gen_op_float_recip2_s();
@@ -4440,21 +4469,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "recip2.s";
         break;
     case FOP(29, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_recip1_s();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "recip1.s";
         break;
     case FOP(30, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_rsqrt1_s();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "rsqrt1.s";
         break;
     case FOP(31, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WT2, fd);
         gen_op_float_rsqrt2_s();
@@ -4462,7 +4491,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "rsqrt2.s";
         break;
     case FOP(33, 16):
-        gen_op_cp1_registers(fd);
+        check_cp1_registers(ctx, fd);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_cvtd_s();
         GEN_STORE_FTN_FREG(fd, DT2);
@@ -4475,14 +4504,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "cvt.w.s";
         break;
     case FOP(37, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_cvtl_s();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "cvt.l.s";
         break;
     case FOP(38, 16):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT1, fs);
         GEN_LOAD_FREG_FTN(WT0, ft);
         gen_op_float_cvtps_s();
@@ -4508,7 +4537,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WT1, ft);
         if (ctx->opcode & (1 << 6)) {
-            gen_op_cp1_64bitmode();
+            check_cp1_64bitmode(ctx);
             gen_cmpabs_s(func-48, cc);
             opn = condnames_abs[func-48];
         } else {
@@ -4517,7 +4546,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         }
         break;
     case FOP(0, 17):
-        gen_op_cp1_registers(fs | ft | fd);
+        check_cp1_registers(ctx, fs | ft | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT1, ft);
         gen_op_float_add_d();
@@ -4526,7 +4555,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         optype = BINOP;
         break;
     case FOP(1, 17):
-        gen_op_cp1_registers(fs | ft | fd);
+        check_cp1_registers(ctx, fs | ft | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT1, ft);
         gen_op_float_sub_d();
@@ -4535,7 +4564,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         optype = BINOP;
         break;
     case FOP(2, 17):
-        gen_op_cp1_registers(fs | ft | fd);
+        check_cp1_registers(ctx, fs | ft | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT1, ft);
         gen_op_float_mul_d();
@@ -4544,7 +4573,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         optype = BINOP;
         break;
     case FOP(3, 17):
-        gen_op_cp1_registers(fs | ft | fd);
+        check_cp1_registers(ctx, fs | ft | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT1, ft);
         gen_op_float_div_d();
@@ -4553,84 +4582,84 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         optype = BINOP;
         break;
     case FOP(4, 17):
-        gen_op_cp1_registers(fs | fd);
+        check_cp1_registers(ctx, fs | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_sqrt_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "sqrt.d";
         break;
     case FOP(5, 17):
-        gen_op_cp1_registers(fs | fd);
+        check_cp1_registers(ctx, fs | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_abs_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "abs.d";
         break;
     case FOP(6, 17):
-        gen_op_cp1_registers(fs | fd);
+        check_cp1_registers(ctx, fs | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_mov_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "mov.d";
         break;
     case FOP(7, 17):
-        gen_op_cp1_registers(fs | fd);
+        check_cp1_registers(ctx, fs | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_chs_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "neg.d";
         break;
     case FOP(8, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_roundl_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "round.l.d";
         break;
     case FOP(9, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_truncl_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "trunc.l.d";
         break;
     case FOP(10, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_ceill_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "ceil.l.d";
         break;
     case FOP(11, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_floorl_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "floor.l.d";
         break;
     case FOP(12, 17):
-        gen_op_cp1_registers(fs);
+        check_cp1_registers(ctx, fs);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_roundw_d();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "round.w.d";
         break;
     case FOP(13, 17):
-        gen_op_cp1_registers(fs);
+        check_cp1_registers(ctx, fs);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_truncw_d();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "trunc.w.d";
         break;
     case FOP(14, 17):
-        gen_op_cp1_registers(fs);
+        check_cp1_registers(ctx, fs);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_ceilw_d();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "ceil.w.d";
         break;
     case FOP(15, 17):
-        gen_op_cp1_registers(fs);
+        check_cp1_registers(ctx, fs);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_floorw_d();
         GEN_STORE_FTN_FREG(fd, WT2);
@@ -4661,21 +4690,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "movn.d";
         break;
     case FOP(21, 17):
-        gen_op_cp1_registers(fs | fd);
+        check_cp1_registers(ctx, fs | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_recip_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "recip.d";
         break;
     case FOP(22, 17):
-        gen_op_cp1_registers(fs | fd);
+        check_cp1_registers(ctx, fs | fd);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_rsqrt_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "rsqrt.d";
         break;
     case FOP(28, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT2, ft);
         gen_op_float_recip2_d();
@@ -4683,21 +4712,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "recip2.d";
         break;
     case FOP(29, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_recip1_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "recip1.d";
         break;
     case FOP(30, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_rsqrt1_d();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "rsqrt1.d";
         break;
     case FOP(31, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT2, ft);
         gen_op_float_rsqrt2_d();
@@ -4723,31 +4752,31 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         GEN_LOAD_FREG_FTN(DT0, fs);
         GEN_LOAD_FREG_FTN(DT1, ft);
         if (ctx->opcode & (1 << 6)) {
-            gen_op_cp1_64bitmode();
+            check_cp1_64bitmode(ctx);
             gen_cmpabs_d(func-48, cc);
             opn = condnames_abs[func-48];
         } else {
-            gen_op_cp1_registers(fs | ft);
+            check_cp1_registers(ctx, fs | ft);
             gen_cmp_d(func-48, cc);
             opn = condnames[func-48];
         }
         break;
     case FOP(32, 17):
-        gen_op_cp1_registers(fs);
+        check_cp1_registers(ctx, fs);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_cvts_d();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "cvt.s.d";
         break;
     case FOP(36, 17):
-        gen_op_cp1_registers(fs);
+        check_cp1_registers(ctx, fs);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_cvtw_d();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "cvt.w.d";
         break;
     case FOP(37, 17):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_cvtl_d();
         GEN_STORE_FTN_FREG(fd, DT2);
@@ -4760,21 +4789,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "cvt.s.w";
         break;
     case FOP(33, 20):
-        gen_op_cp1_registers(fd);
+        check_cp1_registers(ctx, fd);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_cvtd_w();
         GEN_STORE_FTN_FREG(fd, DT2);
         opn = "cvt.d.w";
         break;
     case FOP(32, 21):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_cvts_l();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "cvt.s.l";
         break;
     case FOP(33, 21):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(DT0, fs);
         gen_op_float_cvtd_l();
         GEN_STORE_FTN_FREG(fd, DT2);
@@ -4782,7 +4811,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         break;
     case FOP(38, 20):
     case FOP(38, 21):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_float_cvtps_pw();
@@ -4791,7 +4820,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "cvt.ps.pw";
         break;
     case FOP(0, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT1, ft);
@@ -4802,7 +4831,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "add.ps";
         break;
     case FOP(1, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT1, ft);
@@ -4813,7 +4842,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "sub.ps";
         break;
     case FOP(2, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT1, ft);
@@ -4824,7 +4853,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "mul.ps";
         break;
     case FOP(5, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_float_abs_ps();
@@ -4833,7 +4862,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "abs.ps";
         break;
     case FOP(6, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_float_mov_ps();
@@ -4842,7 +4871,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "mov.ps";
         break;
     case FOP(7, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_float_chs_ps();
@@ -4851,7 +4880,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "neg.ps";
         break;
     case FOP(17, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_REG_TN(T0, ft);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
@@ -4863,7 +4892,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "movcf.ps";
         break;
     case FOP(18, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_REG_TN(T0, ft);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
@@ -4875,7 +4904,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "movz.ps";
         break;
     case FOP(19, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_REG_TN(T0, ft);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
@@ -4887,7 +4916,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "movn.ps";
         break;
     case FOP(24, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, ft);
         GEN_LOAD_FREG_FTN(WTH0, ft);
         GEN_LOAD_FREG_FTN(WT1, fs);
@@ -4898,7 +4927,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "addr.ps";
         break;
     case FOP(26, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, ft);
         GEN_LOAD_FREG_FTN(WTH0, ft);
         GEN_LOAD_FREG_FTN(WT1, fs);
@@ -4909,7 +4938,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "mulr.ps";
         break;
     case FOP(28, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT2, fd);
@@ -4920,7 +4949,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "recip2.ps";
         break;
     case FOP(29, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_float_recip1_ps();
@@ -4929,7 +4958,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "recip1.ps";
         break;
     case FOP(30, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_float_rsqrt1_ps();
@@ -4938,7 +4967,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "rsqrt1.ps";
         break;
     case FOP(31, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT2, fd);
@@ -4949,14 +4978,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "rsqrt2.ps";
         break;
     case FOP(32, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_float_cvts_pu();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "cvt.s.pu";
         break;
     case FOP(36, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         gen_op_float_cvtpw_ps();
@@ -4965,14 +4994,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "cvt.pw.ps";
         break;
     case FOP(40, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         gen_op_float_cvts_pl();
         GEN_STORE_FTN_FREG(fd, WT2);
         opn = "cvt.s.pl";
         break;
     case FOP(44, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WT1, ft);
         gen_op_float_pll_ps();
@@ -4980,7 +5009,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "pll.ps";
         break;
     case FOP(45, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH1, ft);
         gen_op_float_plu_ps();
@@ -4988,7 +5017,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "plu.ps";
         break;
     case FOP(46, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT1, ft);
         gen_op_float_pul_ps();
@@ -4996,7 +5025,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
         opn = "pul.ps";
         break;
     case FOP(47, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WTH1, ft);
         gen_op_float_puu_ps();
@@ -5019,7 +5048,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
     case FOP(61, 22):
     case FOP(62, 22):
     case FOP(63, 22):
-        gen_op_cp1_64bitmode();
+        check_cp1_64bitmode(ctx);
         GEN_LOAD_FREG_FTN(WT0, fs);
         GEN_LOAD_FREG_FTN(WTH0, fs);
         GEN_LOAD_FREG_FTN(WT1, ft);
@@ -5051,14 +5080,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
 }
 
 /* Coprocessor 3 (FPU) */
-static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
-                           int fs, int base, int index)
+static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
+                           int fd, int fs, int base, int index)
 {
     const char *opn = "extended float load/store";
     int store = 0;
 
     /* All of those work only on 64bit FPUs. */
-    gen_op_cp1_64bitmode();
+    check_cp1_64bitmode(ctx);
     if (base == 0) {
         if (index == 0)
             gen_op_reset_T0();
@@ -5117,13 +5146,13 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, int fd,
                regnames[index], regnames[base]);
 }
 
-static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
-                            int fr, int fs, int ft)
+static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
+                            int fd, int fr, int fs, int ft)
 {
     const char *opn = "flt3_arith";
 
     /* All of those work only on 64bit FPUs. */
-    gen_op_cp1_64bitmode();
+    check_cp1_64bitmode(ctx);
     switch (opc) {
     case OPC_ALNV_PS:
         GEN_LOAD_REG_TN(T0, fr);
@@ -5363,7 +5392,7 @@ 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();
+                check_cp1_enabled(ctx);
                 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
                           (ctx->opcode >> 16) & 1);
             } else {
@@ -5634,7 +5663,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
     case OPC_SDC1:
         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
             save_cpu_state(ctx, 1);
-            gen_op_cp1_enabled();
+            check_cp1_enabled(ctx);
             gen_flt_ldst(ctx, op, rt, rs, imm);
         } else {
             generate_exception_err(ctx, EXCP_CpU, 1);
@@ -5644,7 +5673,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
     case OPC_CP1:
         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
             save_cpu_state(ctx, 1);
-            gen_op_cp1_enabled();
+            check_cp1_enabled(ctx);
             op1 = MASK_CP1(ctx->opcode);
             switch (op1) {
             case OPC_MFC1:
@@ -5696,7 +5725,7 @@ 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();
+            check_cp1_enabled(ctx);
             op1 = MASK_CP3(ctx->opcode);
             switch (op1) {
             case OPC_LWXC1:
@@ -5960,7 +5989,7 @@ void fpu_dump_state(CPUState *env, FILE *f,
                     int flags)
 {
     int i;
-    int is_fpu64 = !!(env->CP0_Status & (1 << CP0St_FR));
+    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
 
 #define printfpr(fp)                                                        \
     do {                                                                    \
@@ -6038,7 +6067,6 @@ void cpu_dump_state (CPUState *env, FILE *f,
                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                      int flags)
 {
-    uint32_t c0_status;
     int i;
     
     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
@@ -6051,13 +6079,11 @@ void cpu_dump_state (CPUState *env, FILE *f,
             cpu_fprintf(f, "\n");
     }
 
-    c0_status = env->CP0_Status;
-
     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
-                c0_status, env->CP0_Cause, env->CP0_EPC);
+                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
                 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
-    if (c0_status & (1 << CP0St_CU1))
+    if (env->hflags & MIPS_HFLAG_FPU)
         fpu_dump_state(env, f, cpu_fprintf, flags);
 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
     cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);