Move the active FPU registers into env again, and use more TCG registers
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Thu, 18 Sep 2008 11:57:27 +0000 (11:57 +0000)
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Thu, 18 Sep 2008 11:57:27 +0000 (11:57 +0000)
to access them.

Signed-off-by: Thiemo Seufer <ths@networkno.de>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5252 c046a42c-6fe2-441c-8c8c-71466251a162

gdbstub.c
target-mips/TODO
target-mips/cpu.h
target-mips/exec.h
target-mips/op_helper.c
target-mips/translate.c
target-mips/translate_init.c

index 117caf9115357582567acbe0eff995ac0eea042e..2c701dd45484e466aa1762f00f54bc1266a8bc1a 100644 (file)
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -731,16 +731,16 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
         for (i = 0; i < 32; i++)
           {
             if (env->CP0_Status & (1 << CP0St_FR))
-              *(target_ulong *)ptr = tswapl(env->fpu->fpr[i].d);
+              *(target_ulong *)ptr = tswapl(env->active_fpu.fpr[i].d);
             else
-              *(target_ulong *)ptr = tswap32(env->fpu->fpr[i].w[FP_ENDIAN_IDX]);
+              *(target_ulong *)ptr = tswap32(env->active_fpu.fpr[i].w[FP_ENDIAN_IDX]);
             ptr += sizeof(target_ulong);
           }
 
-        *(target_ulong *)ptr = (int32_t)tswap32(env->fpu->fcr31);
+        *(target_ulong *)ptr = (int32_t)tswap32(env->active_fpu.fcr31);
         ptr += sizeof(target_ulong);
 
-        *(target_ulong *)ptr = (int32_t)tswap32(env->fpu->fcr0);
+        *(target_ulong *)ptr = (int32_t)tswap32(env->active_fpu.fcr0);
         ptr += sizeof(target_ulong);
       }
 
@@ -771,7 +771,7 @@ static unsigned int ieee_rm[] =
     float_round_down
   };
 #define RESTORE_ROUNDING_MODE \
-    set_float_rounding_mode(ieee_rm[env->fpu->fcr31 & 3], &env->fpu->fp_status)
+    set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], &env->active_fpu.fp_status)
 
 static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
 {
@@ -808,13 +808,13 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
         for (i = 0; i < 32; i++)
           {
             if (env->CP0_Status & (1 << CP0St_FR))
-              env->fpu->fpr[i].d = tswapl(*(target_ulong *)ptr);
+              env->active_fpu.fpr[i].d = tswapl(*(target_ulong *)ptr);
             else
-              env->fpu->fpr[i].w[FP_ENDIAN_IDX] = tswapl(*(target_ulong *)ptr);
+              env->active_fpu.fpr[i].w[FP_ENDIAN_IDX] = tswapl(*(target_ulong *)ptr);
             ptr += sizeof(target_ulong);
           }
 
-        env->fpu->fcr31 = tswapl(*(target_ulong *)ptr) & 0xFF83FFFF;
+        env->active_fpu.fcr31 = tswapl(*(target_ulong *)ptr) & 0xFF83FFFF;
         ptr += sizeof(target_ulong);
 
         /* The remaining registers are assumed to be read-only. */
index bb18fa8d85d633af9bec04d8e6d2af14ead7f5ae..4769e2a3ae5eb1066e608848b182a05a727fcc26 100644 (file)
@@ -30,11 +30,6 @@ General
   each ASID change. Using the MMU modes to implement ASIDs hinges on
   implementing the global bit efficiently.
 - save/restore of the CPU state is not implemented (see machine.c).
-- Improve cpu state handling:
-  Step 1) Collect all the TC state in a single struct, so we need only
-          a single global pointer for the active TC.
-  Step 2) Use only a single TC context as working context, and copy the
-          contexts on TC switch. Likewise for FPU contexts.
 
 MIPS64
 ------
index 8918a868e243a78ac045931ab8fe6e458cb8feba..91734524512070599c62ac51397ee86e948a45d4 100644 (file)
@@ -84,9 +84,9 @@ struct CPUMIPSFPUContext {
 #define FCR0_REV 0
     /* fcsr */
     uint32_t fcr31;
-#define SET_FP_COND(num,env)     do { ((env)->fcr31) |= ((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
-#define CLEAR_FP_COND(num,env)   do { ((env)->fcr31) &= ~((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
-#define GET_FP_COND(env)         ((((env)->fcr31 >> 24) & 0xfe) | (((env)->fcr31 >> 23) & 0x1))
+#define SET_FP_COND(num,env)     do { ((env).fcr31) |= ((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
+#define CLEAR_FP_COND(num,env)   do { ((env).fcr31) &= ~((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
+#define GET_FP_COND(env)         ((((env).fcr31 >> 24) & 0xfe) | (((env).fcr31 >> 23) & 0x1))
 #define GET_FP_CAUSE(reg)        (((reg) >> 12) & 0x3f)
 #define GET_FP_ENABLE(reg)       (((reg) >>  7) & 0x1f)
 #define GET_FP_FLAGS(reg)        (((reg) >>  2) & 0x1f)
@@ -132,6 +132,7 @@ typedef struct mips_def_t mips_def_t;
 
 #define MIPS_SHADOW_SET_MAX 16
 #define MIPS_TC_MAX 5
+#define MIPS_FPU_MAX 1
 #define MIPS_DSP_ACC 4
 
 typedef struct TCState TCState;
@@ -170,11 +171,12 @@ struct TCState {
 typedef struct CPUMIPSState CPUMIPSState;
 struct CPUMIPSState {
     TCState active_tc;
+    CPUMIPSFPUContext active_fpu;
 
     CPUMIPSMVPContext *mvp;
     CPUMIPSTLBContext *tlb;
-    CPUMIPSFPUContext *fpu;
     uint32_t current_tc;
+    uint32_t current_fpu;
 
     uint32_t SEGBITS;
     uint32_t PABITS;
@@ -404,6 +406,7 @@ struct CPUMIPSState {
     int32_t CP0_DESAVE;
     /* We waste some space so we can handle shadow registers like TCs. */
     TCState tcs[MIPS_SHADOW_SET_MAX];
+    CPUMIPSFPUContext fpus[MIPS_FPU_MAX];
     /* Qemu */
     int error_code;
     uint32_t hflags;    /* CPU State */
index de6e6dd103695594e710c46ba11d60077872d78b..28bf466ff50f590695f2f426ed38df7a5aa751a9 100644 (file)
@@ -86,7 +86,7 @@ static inline void compute_hflags(CPUState *env)
     if (env->CP0_Status & (1 << CP0St_FR))
         env->hflags |= MIPS_HFLAG_F64;
     if (env->insn_flags & ISA_MIPS32R2) {
-        if (env->fpu->fcr0 & (1 << FCR0_F64))
+        if (env->active_fpu.fcr0 & (1 << FCR0_F64))
             env->hflags |= MIPS_HFLAG_COP1X;
     } else if (env->insn_flags & ISA_MIPS32) {
         if (env->hflags & MIPS_HFLAG_64)
index dcadd031ed606c6c28433d1956b54db777a1b776..fb7ae537301ed3334e6b80ae5a37e36ef3f4c8b8 100644 (file)
@@ -1940,7 +1940,7 @@ unsigned int ieee_rm[] = {
 };
 
 #define RESTORE_ROUNDING_MODE \
-    set_float_rounding_mode(ieee_rm[env->fpu->fcr31 & 3], &env->fpu->fp_status)
+    set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], &env->active_fpu.fp_status)
 
 target_ulong do_cfc1 (uint32_t reg)
 {
@@ -1948,19 +1948,19 @@ target_ulong do_cfc1 (uint32_t reg)
 
     switch (reg) {
     case 0:
-        t0 = (int32_t)env->fpu->fcr0;
+        t0 = (int32_t)env->active_fpu.fcr0;
         break;
     case 25:
-        t0 = ((env->fpu->fcr31 >> 24) & 0xfe) | ((env->fpu->fcr31 >> 23) & 0x1);
+        t0 = ((env->active_fpu.fcr31 >> 24) & 0xfe) | ((env->active_fpu.fcr31 >> 23) & 0x1);
         break;
     case 26:
-        t0 = env->fpu->fcr31 & 0x0003f07c;
+        t0 = env->active_fpu.fcr31 & 0x0003f07c;
         break;
     case 28:
-        t0 = (env->fpu->fcr31 & 0x00000f83) | ((env->fpu->fcr31 >> 22) & 0x4);
+        t0 = (env->active_fpu.fcr31 & 0x00000f83) | ((env->active_fpu.fcr31 >> 22) & 0x4);
         break;
     default:
-        t0 = (int32_t)env->fpu->fcr31;
+        t0 = (int32_t)env->active_fpu.fcr31;
         break;
     }
 
@@ -1973,32 +1973,32 @@ void do_ctc1 (target_ulong t0, uint32_t reg)
     case 25:
         if (t0 & 0xffffff00)
             return;
-        env->fpu->fcr31 = (env->fpu->fcr31 & 0x017fffff) | ((t0 & 0xfe) << 24) |
+        env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0x017fffff) | ((t0 & 0xfe) << 24) |
                      ((t0 & 0x1) << 23);
         break;
     case 26:
         if (t0 & 0x007c0000)
             return;
-        env->fpu->fcr31 = (env->fpu->fcr31 & 0xfffc0f83) | (t0 & 0x0003f07c);
+        env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfffc0f83) | (t0 & 0x0003f07c);
         break;
     case 28:
         if (t0 & 0x007c0000)
             return;
-        env->fpu->fcr31 = (env->fpu->fcr31 & 0xfefff07c) | (t0 & 0x00000f83) |
+        env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfefff07c) | (t0 & 0x00000f83) |
                      ((t0 & 0x4) << 22);
         break;
     case 31:
         if (t0 & 0x007c0000)
             return;
-        env->fpu->fcr31 = t0;
+        env->active_fpu.fcr31 = t0;
         break;
     default:
         return;
     }
     /* set rounding mode */
     RESTORE_ROUNDING_MODE;
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    if ((GET_FP_ENABLE(env->fpu->fcr31) | 0x20) & GET_FP_CAUSE(env->fpu->fcr31))
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    if ((GET_FP_ENABLE(env->active_fpu.fcr31) | 0x20) & GET_FP_CAUSE(env->active_fpu.fcr31))
         do_raise_exception(EXCP_FPE);
 }
 
@@ -2022,13 +2022,13 @@ static inline char mips_ex_to_ieee(char xcpt)
 
 static inline void update_fcr31(void)
 {
-    int tmp = ieee_ex_to_mips(get_float_exception_flags(&env->fpu->fp_status));
+    int tmp = ieee_ex_to_mips(get_float_exception_flags(&env->active_fpu.fp_status));
 
-    SET_FP_CAUSE(env->fpu->fcr31, tmp);
-    if (GET_FP_ENABLE(env->fpu->fcr31) & tmp)
+    SET_FP_CAUSE(env->active_fpu.fcr31, tmp);
+    if (GET_FP_ENABLE(env->active_fpu.fcr31) & tmp)
         do_raise_exception(EXCP_FPE);
     else
-        UPDATE_FP_FLAGS(env->fpu->fcr31, tmp);
+        UPDATE_FP_FLAGS(env->active_fpu.fcr31, tmp);
 }
 
 /* Float support.
@@ -2039,20 +2039,20 @@ static inline void update_fcr31(void)
 /* unary operations, modifying fp status  */
 uint64_t do_float_sqrt_d(uint64_t fdt0)
 {
-    return float64_sqrt(fdt0, &env->fpu->fp_status);
+    return float64_sqrt(fdt0, &env->active_fpu.fp_status);
 }
 
 uint32_t do_float_sqrt_s(uint32_t fst0)
 {
-    return float32_sqrt(fst0, &env->fpu->fp_status);
+    return float32_sqrt(fst0, &env->active_fpu.fp_status);
 }
 
 uint64_t do_float_cvtd_s(uint32_t fst0)
 {
     uint64_t fdt2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fdt2 = float32_to_float64(fst0, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status);
     update_fcr31();
     return fdt2;
 }
@@ -2061,8 +2061,8 @@ uint64_t do_float_cvtd_w(uint32_t wt0)
 {
     uint64_t fdt2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fdt2 = int32_to_float64(wt0, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status);
     update_fcr31();
     return fdt2;
 }
@@ -2071,8 +2071,8 @@ uint64_t do_float_cvtd_l(uint64_t dt0)
 {
     uint64_t fdt2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fdt2 = int64_to_float64(dt0, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status);
     update_fcr31();
     return fdt2;
 }
@@ -2081,10 +2081,10 @@ uint64_t do_float_cvtl_d(uint64_t fdt0)
 {
     uint64_t dt2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    dt2 = float64_to_int64(fdt0, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         dt2 = FLOAT_SNAN64;
     return dt2;
 }
@@ -2093,10 +2093,10 @@ uint64_t do_float_cvtl_s(uint32_t fst0)
 {
     uint64_t dt2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    dt2 = float32_to_int64(fst0, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         dt2 = FLOAT_SNAN64;
     return dt2;
 }
@@ -2106,9 +2106,9 @@ uint64_t do_float_cvtps_pw(uint64_t dt0)
     uint32_t fst2;
     uint32_t fsth2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fst2 = int32_to_float32(dt0 & 0XFFFFFFFF, &env->fpu->fp_status);
-    fsth2 = int32_to_float32(dt0 >> 32, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fst2 = int32_to_float32(dt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
+    fsth2 = int32_to_float32(dt0 >> 32, &env->active_fpu.fp_status);
     update_fcr31();
     return ((uint64_t)fsth2 << 32) | fst2;
 }
@@ -2118,11 +2118,11 @@ uint64_t do_float_cvtpw_ps(uint64_t fdt0)
     uint32_t wt2;
     uint32_t wth2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    wt2 = float32_to_int32(fdt0 & 0XFFFFFFFF, &env->fpu->fp_status);
-    wth2 = float32_to_int32(fdt0 >> 32, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    wt2 = float32_to_int32(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
+    wth2 = float32_to_int32(fdt0 >> 32, &env->active_fpu.fp_status);
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID)) {
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID)) {
         wt2 = FLOAT_SNAN32;
         wth2 = FLOAT_SNAN32;
     }
@@ -2133,8 +2133,8 @@ uint32_t do_float_cvts_d(uint64_t fdt0)
 {
     uint32_t fst2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fst2 = float64_to_float32(fdt0, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status);
     update_fcr31();
     return fst2;
 }
@@ -2143,8 +2143,8 @@ uint32_t do_float_cvts_w(uint32_t wt0)
 {
     uint32_t fst2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fst2 = int32_to_float32(wt0, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status);
     update_fcr31();
     return fst2;
 }
@@ -2153,8 +2153,8 @@ uint32_t do_float_cvts_l(uint64_t dt0)
 {
     uint32_t fst2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fst2 = int64_to_float32(dt0, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status);
     update_fcr31();
     return fst2;
 }
@@ -2163,7 +2163,7 @@ uint32_t do_float_cvts_pl(uint32_t wt0)
 {
     uint32_t wt2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
     wt2 = wt0;
     update_fcr31();
     return wt2;
@@ -2173,7 +2173,7 @@ uint32_t do_float_cvts_pu(uint32_t wth0)
 {
     uint32_t wt2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
     wt2 = wth0;
     update_fcr31();
     return wt2;
@@ -2183,10 +2183,10 @@ uint32_t do_float_cvtw_s(uint32_t fst0)
 {
     uint32_t wt2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    wt2 = float32_to_int32(fst0, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         wt2 = FLOAT_SNAN32;
     return wt2;
 }
@@ -2195,10 +2195,10 @@ uint32_t do_float_cvtw_d(uint64_t fdt0)
 {
     uint32_t wt2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    wt2 = float64_to_int32(fdt0, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         wt2 = FLOAT_SNAN32;
     return wt2;
 }
@@ -2207,11 +2207,11 @@ uint64_t do_float_roundl_d(uint64_t fdt0)
 {
     uint64_t dt2;
 
-    set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status);
-    dt2 = float64_to_int64(fdt0, &env->fpu->fp_status);
+    set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
+    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         dt2 = FLOAT_SNAN64;
     return dt2;
 }
@@ -2220,11 +2220,11 @@ uint64_t do_float_roundl_s(uint32_t fst0)
 {
     uint64_t dt2;
 
-    set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status);
-    dt2 = float32_to_int64(fst0, &env->fpu->fp_status);
+    set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
+    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         dt2 = FLOAT_SNAN64;
     return dt2;
 }
@@ -2233,11 +2233,11 @@ uint32_t do_float_roundw_d(uint64_t fdt0)
 {
     uint32_t wt2;
 
-    set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status);
-    wt2 = float64_to_int32(fdt0, &env->fpu->fp_status);
+    set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
+    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         wt2 = FLOAT_SNAN32;
     return wt2;
 }
@@ -2246,11 +2246,11 @@ uint32_t do_float_roundw_s(uint32_t fst0)
 {
     uint32_t wt2;
 
-    set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status);
-    wt2 = float32_to_int32(fst0, &env->fpu->fp_status);
+    set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
+    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         wt2 = FLOAT_SNAN32;
     return wt2;
 }
@@ -2259,9 +2259,9 @@ uint64_t do_float_truncl_d(uint64_t fdt0)
 {
     uint64_t dt2;
 
-    dt2 = float64_to_int64_round_to_zero(fdt0, &env->fpu->fp_status);
+    dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status);
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         dt2 = FLOAT_SNAN64;
     return dt2;
 }
@@ -2270,9 +2270,9 @@ uint64_t do_float_truncl_s(uint32_t fst0)
 {
     uint64_t dt2;
 
-    dt2 = float32_to_int64_round_to_zero(fst0, &env->fpu->fp_status);
+    dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         dt2 = FLOAT_SNAN64;
     return dt2;
 }
@@ -2281,9 +2281,9 @@ uint32_t do_float_truncw_d(uint64_t fdt0)
 {
     uint32_t wt2;
 
-    wt2 = float64_to_int32_round_to_zero(fdt0, &env->fpu->fp_status);
+    wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         wt2 = FLOAT_SNAN32;
     return wt2;
 }
@@ -2292,9 +2292,9 @@ uint32_t do_float_truncw_s(uint32_t fst0)
 {
     uint32_t wt2;
 
-    wt2 = float32_to_int32_round_to_zero(fst0, &env->fpu->fp_status);
+    wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         wt2 = FLOAT_SNAN32;
     return wt2;
 }
@@ -2303,11 +2303,11 @@ uint64_t do_float_ceill_d(uint64_t fdt0)
 {
     uint64_t dt2;
 
-    set_float_rounding_mode(float_round_up, &env->fpu->fp_status);
-    dt2 = float64_to_int64(fdt0, &env->fpu->fp_status);
+    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
+    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         dt2 = FLOAT_SNAN64;
     return dt2;
 }
@@ -2316,11 +2316,11 @@ uint64_t do_float_ceill_s(uint32_t fst0)
 {
     uint64_t dt2;
 
-    set_float_rounding_mode(float_round_up, &env->fpu->fp_status);
-    dt2 = float32_to_int64(fst0, &env->fpu->fp_status);
+    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
+    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         dt2 = FLOAT_SNAN64;
     return dt2;
 }
@@ -2329,11 +2329,11 @@ uint32_t do_float_ceilw_d(uint64_t fdt0)
 {
     uint32_t wt2;
 
-    set_float_rounding_mode(float_round_up, &env->fpu->fp_status);
-    wt2 = float64_to_int32(fdt0, &env->fpu->fp_status);
+    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
+    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         wt2 = FLOAT_SNAN32;
     return wt2;
 }
@@ -2342,11 +2342,11 @@ uint32_t do_float_ceilw_s(uint32_t fst0)
 {
     uint32_t wt2;
 
-    set_float_rounding_mode(float_round_up, &env->fpu->fp_status);
-    wt2 = float32_to_int32(fst0, &env->fpu->fp_status);
+    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
+    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         wt2 = FLOAT_SNAN32;
     return wt2;
 }
@@ -2355,11 +2355,11 @@ uint64_t do_float_floorl_d(uint64_t fdt0)
 {
     uint64_t dt2;
 
-    set_float_rounding_mode(float_round_down, &env->fpu->fp_status);
-    dt2 = float64_to_int64(fdt0, &env->fpu->fp_status);
+    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
+    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         dt2 = FLOAT_SNAN64;
     return dt2;
 }
@@ -2368,11 +2368,11 @@ uint64_t do_float_floorl_s(uint32_t fst0)
 {
     uint64_t dt2;
 
-    set_float_rounding_mode(float_round_down, &env->fpu->fp_status);
-    dt2 = float32_to_int64(fst0, &env->fpu->fp_status);
+    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
+    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         dt2 = FLOAT_SNAN64;
     return dt2;
 }
@@ -2381,11 +2381,11 @@ uint32_t do_float_floorw_d(uint64_t fdt0)
 {
     uint32_t wt2;
 
-    set_float_rounding_mode(float_round_down, &env->fpu->fp_status);
-    wt2 = float64_to_int32(fdt0, &env->fpu->fp_status);
+    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
+    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         wt2 = FLOAT_SNAN32;
     return wt2;
 }
@@ -2394,11 +2394,11 @@ uint32_t do_float_floorw_s(uint32_t fst0)
 {
     uint32_t wt2;
 
-    set_float_rounding_mode(float_round_down, &env->fpu->fp_status);
-    wt2 = float32_to_int32(fst0, &env->fpu->fp_status);
+    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
+    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
     RESTORE_ROUNDING_MODE;
     update_fcr31();
-    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
         wt2 = FLOAT_SNAN32;
     return wt2;
 }
@@ -2431,8 +2431,8 @@ uint64_t do_float_recip_d(uint64_t fdt0)
 {
     uint64_t fdt2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fdt2 = float64_div(FLOAT_ONE64, fdt0, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fdt2 = float64_div(FLOAT_ONE64, fdt0, &env->active_fpu.fp_status);
     update_fcr31();
     return fdt2;
 }
@@ -2441,8 +2441,8 @@ uint32_t do_float_recip_s(uint32_t fst0)
 {
     uint32_t fst2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fst2 = float32_div(FLOAT_ONE32, fst0, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fst2 = float32_div(FLOAT_ONE32, fst0, &env->active_fpu.fp_status);
     update_fcr31();
     return fst2;
 }
@@ -2451,9 +2451,9 @@ uint64_t do_float_rsqrt_d(uint64_t fdt0)
 {
     uint64_t fdt2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fdt2 = float64_sqrt(fdt0, &env->fpu->fp_status);
-    fdt2 = float64_div(FLOAT_ONE64, fdt2, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
+    fdt2 = float64_div(FLOAT_ONE64, fdt2, &env->active_fpu.fp_status);
     update_fcr31();
     return fdt2;
 }
@@ -2462,9 +2462,9 @@ uint32_t do_float_rsqrt_s(uint32_t fst0)
 {
     uint32_t fst2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fst2 = float32_sqrt(fst0, &env->fpu->fp_status);
-    fst2 = float32_div(FLOAT_ONE32, fst2, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
+    fst2 = float32_div(FLOAT_ONE32, fst2, &env->active_fpu.fp_status);
     update_fcr31();
     return fst2;
 }
@@ -2473,8 +2473,8 @@ uint64_t do_float_recip1_d(uint64_t fdt0)
 {
     uint64_t fdt2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fdt2 = float64_div(FLOAT_ONE64, fdt0, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fdt2 = float64_div(FLOAT_ONE64, fdt0, &env->active_fpu.fp_status);
     update_fcr31();
     return fdt2;
 }
@@ -2483,8 +2483,8 @@ uint32_t do_float_recip1_s(uint32_t fst0)
 {
     uint32_t fst2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fst2 = float32_div(FLOAT_ONE32, fst0, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fst2 = float32_div(FLOAT_ONE32, fst0, &env->active_fpu.fp_status);
     update_fcr31();
     return fst2;
 }
@@ -2494,9 +2494,9 @@ uint64_t do_float_recip1_ps(uint64_t fdt0)
     uint32_t fst2;
     uint32_t fsth2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fst2 = float32_div(FLOAT_ONE32, fdt0 & 0XFFFFFFFF, &env->fpu->fp_status);
-    fsth2 = float32_div(FLOAT_ONE32, fdt0 >> 32, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fst2 = float32_div(FLOAT_ONE32, fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
+    fsth2 = float32_div(FLOAT_ONE32, fdt0 >> 32, &env->active_fpu.fp_status);
     update_fcr31();
     return ((uint64_t)fsth2 << 32) | fst2;
 }
@@ -2505,9 +2505,9 @@ uint64_t do_float_rsqrt1_d(uint64_t fdt0)
 {
     uint64_t fdt2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fdt2 = float64_sqrt(fdt0, &env->fpu->fp_status);
-    fdt2 = float64_div(FLOAT_ONE64, fdt2, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
+    fdt2 = float64_div(FLOAT_ONE64, fdt2, &env->active_fpu.fp_status);
     update_fcr31();
     return fdt2;
 }
@@ -2516,9 +2516,9 @@ uint32_t do_float_rsqrt1_s(uint32_t fst0)
 {
     uint32_t fst2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fst2 = float32_sqrt(fst0, &env->fpu->fp_status);
-    fst2 = float32_div(FLOAT_ONE32, fst2, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
+    fst2 = float32_div(FLOAT_ONE32, fst2, &env->active_fpu.fp_status);
     update_fcr31();
     return fst2;
 }
@@ -2528,11 +2528,11 @@ uint64_t do_float_rsqrt1_ps(uint64_t fdt0)
     uint32_t fst2;
     uint32_t fsth2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fst2 = float32_sqrt(fdt0 & 0XFFFFFFFF, &env->fpu->fp_status);
-    fsth2 = float32_sqrt(fdt0 >> 32, &env->fpu->fp_status);
-    fst2 = float32_div(FLOAT_ONE32, fst2, &env->fpu->fp_status);
-    fsth2 = float32_div(FLOAT_ONE32, fsth2, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fst2 = float32_sqrt(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
+    fsth2 = float32_sqrt(fdt0 >> 32, &env->active_fpu.fp_status);
+    fst2 = float32_div(FLOAT_ONE32, fst2, &env->active_fpu.fp_status);
+    fsth2 = float32_div(FLOAT_ONE32, fsth2, &env->active_fpu.fp_status);
     update_fcr31();
     return ((uint64_t)fsth2 << 32) | fst2;
 }
@@ -2545,10 +2545,10 @@ uint64_t do_float_ ## name ## _d(uint64_t fdt0, uint64_t fdt1)     \
 {                                                                  \
     uint64_t dt2;                                                  \
                                                                    \
-    set_float_exception_flags(0, &env->fpu->fp_status);            \
-    dt2 = float64_ ## name (fdt0, fdt1, &env->fpu->fp_status);     \
+    set_float_exception_flags(0, &env->active_fpu.fp_status);            \
+    dt2 = float64_ ## name (fdt0, fdt1, &env->active_fpu.fp_status);     \
     update_fcr31();                                                \
-    if (GET_FP_CAUSE(env->fpu->fcr31) & FP_INVALID)                \
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_INVALID)                \
         dt2 = FLOAT_QNAN64;                                        \
     return dt2;                                                    \
 }                                                                  \
@@ -2557,10 +2557,10 @@ uint32_t do_float_ ## name ## _s(uint32_t fst0, uint32_t fst1)     \
 {                                                                  \
     uint32_t wt2;                                                  \
                                                                    \
-    set_float_exception_flags(0, &env->fpu->fp_status);            \
-    wt2 = float32_ ## name (fst0, fst1, &env->fpu->fp_status);     \
+    set_float_exception_flags(0, &env->active_fpu.fp_status);            \
+    wt2 = float32_ ## name (fst0, fst1, &env->active_fpu.fp_status);     \
     update_fcr31();                                                \
-    if (GET_FP_CAUSE(env->fpu->fcr31) & FP_INVALID)                \
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_INVALID)                \
         wt2 = FLOAT_QNAN32;                                        \
     return wt2;                                                    \
 }                                                                  \
@@ -2574,11 +2574,11 @@ uint64_t do_float_ ## name ## _ps(uint64_t fdt0, uint64_t fdt1)    \
     uint32_t wt2;                                                  \
     uint32_t wth2;                                                 \
                                                                    \
-    set_float_exception_flags(0, &env->fpu->fp_status);            \
-    wt2 = float32_ ## name (fst0, fst1, &env->fpu->fp_status);     \
-    wth2 = float32_ ## name (fsth0, fsth1, &env->fpu->fp_status);  \
+    set_float_exception_flags(0, &env->active_fpu.fp_status);            \
+    wt2 = float32_ ## name (fst0, fst1, &env->active_fpu.fp_status);     \
+    wth2 = float32_ ## name (fsth0, fsth1, &env->active_fpu.fp_status);  \
     update_fcr31();                                                \
-    if (GET_FP_CAUSE(env->fpu->fcr31) & FP_INVALID) {              \
+    if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_INVALID) {              \
         wt2 = FLOAT_QNAN32;                                        \
         wth2 = FLOAT_QNAN32;                                       \
     }                                                              \
@@ -2596,15 +2596,15 @@ FLOAT_BINOP(div)
 uint64_t do_float_ ## name1 ## name2 ## _d(uint64_t fdt0, uint64_t fdt1,  \
                                            uint64_t fdt2)                 \
 {                                                                         \
-    fdt0 = float64_ ## name1 (fdt0, fdt1, &env->fpu->fp_status);          \
-    return float64_ ## name2 (fdt0, fdt2, &env->fpu->fp_status);          \
+    fdt0 = float64_ ## name1 (fdt0, fdt1, &env->active_fpu.fp_status);          \
+    return float64_ ## name2 (fdt0, fdt2, &env->active_fpu.fp_status);          \
 }                                                                         \
                                                                           \
 uint32_t do_float_ ## name1 ## name2 ## _s(uint32_t fst0, uint32_t fst1,  \
                                            uint32_t fst2)                 \
 {                                                                         \
-    fst0 = float32_ ## name1 (fst0, fst1, &env->fpu->fp_status);          \
-    return float32_ ## name2 (fst0, fst2, &env->fpu->fp_status);          \
+    fst0 = float32_ ## name1 (fst0, fst1, &env->active_fpu.fp_status);          \
+    return float32_ ## name2 (fst0, fst2, &env->active_fpu.fp_status);          \
 }                                                                         \
                                                                           \
 uint64_t do_float_ ## name1 ## name2 ## _ps(uint64_t fdt0, uint64_t fdt1, \
@@ -2617,10 +2617,10 @@ uint64_t do_float_ ## name1 ## name2 ## _ps(uint64_t fdt0, uint64_t fdt1, \
     uint32_t fst2 = fdt2 & 0XFFFFFFFF;                                    \
     uint32_t fsth2 = fdt2 >> 32;                                          \
                                                                           \
-    fst0 = float32_ ## name1 (fst0, fst1, &env->fpu->fp_status);          \
-    fsth0 = float32_ ## name1 (fsth0, fsth1, &env->fpu->fp_status);       \
-    fst2 = float32_ ## name2 (fst0, fst2, &env->fpu->fp_status);          \
-    fsth2 = float32_ ## name2 (fsth0, fsth2, &env->fpu->fp_status);       \
+    fst0 = float32_ ## name1 (fst0, fst1, &env->active_fpu.fp_status);          \
+    fsth0 = float32_ ## name1 (fsth0, fsth1, &env->active_fpu.fp_status);       \
+    fst2 = float32_ ## name2 (fst0, fst2, &env->active_fpu.fp_status);          \
+    fsth2 = float32_ ## name2 (fsth0, fsth2, &env->active_fpu.fp_status);       \
     return ((uint64_t)fsth2 << 32) | fst2;                                \
 }
 
@@ -2633,16 +2633,16 @@ FLOAT_TERNOP(mul, sub)
 uint64_t do_float_n ## name1 ## name2 ## _d(uint64_t fdt0, uint64_t fdt1, \
                                            uint64_t fdt2)                 \
 {                                                                         \
-    fdt0 = float64_ ## name1 (fdt0, fdt1, &env->fpu->fp_status);          \
-    fdt2 = float64_ ## name2 (fdt0, fdt2, &env->fpu->fp_status);          \
+    fdt0 = float64_ ## name1 (fdt0, fdt1, &env->active_fpu.fp_status);          \
+    fdt2 = float64_ ## name2 (fdt0, fdt2, &env->active_fpu.fp_status);          \
     return float64_chs(fdt2);                                             \
 }                                                                         \
                                                                           \
 uint32_t do_float_n ## name1 ## name2 ## _s(uint32_t fst0, uint32_t fst1, \
                                            uint32_t fst2)                 \
 {                                                                         \
-    fst0 = float32_ ## name1 (fst0, fst1, &env->fpu->fp_status);          \
-    fst2 = float32_ ## name2 (fst0, fst2, &env->fpu->fp_status);          \
+    fst0 = float32_ ## name1 (fst0, fst1, &env->active_fpu.fp_status);          \
+    fst2 = float32_ ## name2 (fst0, fst2, &env->active_fpu.fp_status);          \
     return float32_chs(fst2);                                             \
 }                                                                         \
                                                                           \
@@ -2656,10 +2656,10 @@ uint64_t do_float_n ## name1 ## name2 ## _ps(uint64_t fdt0, uint64_t fdt1,\
     uint32_t fst2 = fdt2 & 0XFFFFFFFF;                                    \
     uint32_t fsth2 = fdt2 >> 32;                                          \
                                                                           \
-    fst0 = float32_ ## name1 (fst0, fst1, &env->fpu->fp_status);          \
-    fsth0 = float32_ ## name1 (fsth0, fsth1, &env->fpu->fp_status);       \
-    fst2 = float32_ ## name2 (fst0, fst2, &env->fpu->fp_status);          \
-    fsth2 = float32_ ## name2 (fsth0, fsth2, &env->fpu->fp_status);       \
+    fst0 = float32_ ## name1 (fst0, fst1, &env->active_fpu.fp_status);          \
+    fsth0 = float32_ ## name1 (fsth0, fsth1, &env->active_fpu.fp_status);       \
+    fst2 = float32_ ## name2 (fst0, fst2, &env->active_fpu.fp_status);          \
+    fsth2 = float32_ ## name2 (fsth0, fsth2, &env->active_fpu.fp_status);       \
     fst2 = float32_chs(fst2);                                             \
     fsth2 = float32_chs(fsth2);                                           \
     return ((uint64_t)fsth2 << 32) | fst2;                                \
@@ -2672,18 +2672,18 @@ FLOAT_NTERNOP(mul, sub)
 /* MIPS specific binary operations */
 uint64_t do_float_recip2_d(uint64_t fdt0, uint64_t fdt2)
 {
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fdt2 = float64_mul(fdt0, fdt2, &env->fpu->fp_status);
-    fdt2 = float64_chs(float64_sub(fdt2, FLOAT_ONE64, &env->fpu->fp_status));
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
+    fdt2 = float64_chs(float64_sub(fdt2, FLOAT_ONE64, &env->active_fpu.fp_status));
     update_fcr31();
     return fdt2;
 }
 
 uint32_t do_float_recip2_s(uint32_t fst0, uint32_t fst2)
 {
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fst2 = float32_mul(fst0, fst2, &env->fpu->fp_status);
-    fst2 = float32_chs(float32_sub(fst2, FLOAT_ONE32, &env->fpu->fp_status));
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
+    fst2 = float32_chs(float32_sub(fst2, FLOAT_ONE32, &env->active_fpu.fp_status));
     update_fcr31();
     return fst2;
 }
@@ -2695,31 +2695,31 @@ uint64_t do_float_recip2_ps(uint64_t fdt0, uint64_t fdt2)
     uint32_t fst2 = fdt2 & 0XFFFFFFFF;
     uint32_t fsth2 = fdt2 >> 32;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fst2 = float32_mul(fst0, fst2, &env->fpu->fp_status);
-    fsth2 = float32_mul(fsth0, fsth2, &env->fpu->fp_status);
-    fst2 = float32_chs(float32_sub(fst2, FLOAT_ONE32, &env->fpu->fp_status));
-    fsth2 = float32_chs(float32_sub(fsth2, FLOAT_ONE32, &env->fpu->fp_status));
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
+    fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
+    fst2 = float32_chs(float32_sub(fst2, FLOAT_ONE32, &env->active_fpu.fp_status));
+    fsth2 = float32_chs(float32_sub(fsth2, FLOAT_ONE32, &env->active_fpu.fp_status));
     update_fcr31();
     return ((uint64_t)fsth2 << 32) | fst2;
 }
 
 uint64_t do_float_rsqrt2_d(uint64_t fdt0, uint64_t fdt2)
 {
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fdt2 = float64_mul(fdt0, fdt2, &env->fpu->fp_status);
-    fdt2 = float64_sub(fdt2, FLOAT_ONE64, &env->fpu->fp_status);
-    fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64, &env->fpu->fp_status));
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
+    fdt2 = float64_sub(fdt2, FLOAT_ONE64, &env->active_fpu.fp_status);
+    fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64, &env->active_fpu.fp_status));
     update_fcr31();
     return fdt2;
 }
 
 uint32_t do_float_rsqrt2_s(uint32_t fst0, uint32_t fst2)
 {
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fst2 = float32_mul(fst0, fst2, &env->fpu->fp_status);
-    fst2 = float32_sub(fst2, FLOAT_ONE32, &env->fpu->fp_status);
-    fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32, &env->fpu->fp_status));
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
+    fst2 = float32_sub(fst2, FLOAT_ONE32, &env->active_fpu.fp_status);
+    fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32, &env->active_fpu.fp_status));
     update_fcr31();
     return fst2;
 }
@@ -2731,13 +2731,13 @@ uint64_t do_float_rsqrt2_ps(uint64_t fdt0, uint64_t fdt2)
     uint32_t fst2 = fdt2 & 0XFFFFFFFF;
     uint32_t fsth2 = fdt2 >> 32;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fst2 = float32_mul(fst0, fst2, &env->fpu->fp_status);
-    fsth2 = float32_mul(fsth0, fsth2, &env->fpu->fp_status);
-    fst2 = float32_sub(fst2, FLOAT_ONE32, &env->fpu->fp_status);
-    fsth2 = float32_sub(fsth2, FLOAT_ONE32, &env->fpu->fp_status);
-    fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32, &env->fpu->fp_status));
-    fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32, &env->fpu->fp_status));
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
+    fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
+    fst2 = float32_sub(fst2, FLOAT_ONE32, &env->active_fpu.fp_status);
+    fsth2 = float32_sub(fsth2, FLOAT_ONE32, &env->active_fpu.fp_status);
+    fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32, &env->active_fpu.fp_status));
+    fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32, &env->active_fpu.fp_status));
     update_fcr31();
     return ((uint64_t)fsth2 << 32) | fst2;
 }
@@ -2751,9 +2751,9 @@ uint64_t do_float_addr_ps(uint64_t fdt0, uint64_t fdt1)
     uint32_t fst2;
     uint32_t fsth2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fst2 = float32_add (fst0, fsth0, &env->fpu->fp_status);
-    fsth2 = float32_add (fst1, fsth1, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fst2 = float32_add (fst0, fsth0, &env->active_fpu.fp_status);
+    fsth2 = float32_add (fst1, fsth1, &env->active_fpu.fp_status);
     update_fcr31();
     return ((uint64_t)fsth2 << 32) | fst2;
 }
@@ -2767,9 +2767,9 @@ uint64_t do_float_mulr_ps(uint64_t fdt0, uint64_t fdt1)
     uint32_t fst2;
     uint32_t fsth2;
 
-    set_float_exception_flags(0, &env->fpu->fp_status);
-    fst2 = float32_mul (fst0, fsth0, &env->fpu->fp_status);
-    fsth2 = float32_mul (fst1, fsth1, &env->fpu->fp_status);
+    set_float_exception_flags(0, &env->active_fpu.fp_status);
+    fst2 = float32_mul (fst0, fsth0, &env->active_fpu.fp_status);
+    fsth2 = float32_mul (fst1, fsth1, &env->active_fpu.fp_status);
     update_fcr31();
     return ((uint64_t)fsth2 << 32) | fst2;
 }
@@ -2781,9 +2781,9 @@ void do_cmp_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc)    \
     int c = cond;                                              \
     update_fcr31();                                            \
     if (c)                                                     \
-        SET_FP_COND(cc, env->fpu);                             \
+        SET_FP_COND(cc, env->active_fpu);                      \
     else                                                       \
-        CLEAR_FP_COND(cc, env->fpu);                           \
+        CLEAR_FP_COND(cc, env->active_fpu);                    \
 }                                                              \
 void do_cmpabs_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
 {                                                              \
@@ -2793,9 +2793,9 @@ void do_cmpabs_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
     c = cond;                                                  \
     update_fcr31();                                            \
     if (c)                                                     \
-        SET_FP_COND(cc, env->fpu);                             \
+        SET_FP_COND(cc, env->active_fpu);                      \
     else                                                       \
-        CLEAR_FP_COND(cc, env->fpu);                           \
+        CLEAR_FP_COND(cc, env->active_fpu);                    \
 }
 
 int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
@@ -2814,24 +2814,24 @@ int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
 
 /* NOTE: the comma operator will make "cond" to eval to false,
  * but float*_is_unordered() is still called. */
-FOP_COND_D(f,   (float64_is_unordered(0, fdt1, fdt0, &env->fpu->fp_status), 0))
-FOP_COND_D(un,  float64_is_unordered(0, fdt1, fdt0, &env->fpu->fp_status))
-FOP_COND_D(eq,  !float64_is_unordered(0, fdt1, fdt0, &env->fpu->fp_status) && float64_eq(fdt0, fdt1, &env->fpu->fp_status))
-FOP_COND_D(ueq, float64_is_unordered(0, fdt1, fdt0, &env->fpu->fp_status)  || float64_eq(fdt0, fdt1, &env->fpu->fp_status))
-FOP_COND_D(olt, !float64_is_unordered(0, fdt1, fdt0, &env->fpu->fp_status) && float64_lt(fdt0, fdt1, &env->fpu->fp_status))
-FOP_COND_D(ult, float64_is_unordered(0, fdt1, fdt0, &env->fpu->fp_status)  || float64_lt(fdt0, fdt1, &env->fpu->fp_status))
-FOP_COND_D(ole, !float64_is_unordered(0, fdt1, fdt0, &env->fpu->fp_status) && float64_le(fdt0, fdt1, &env->fpu->fp_status))
-FOP_COND_D(ule, float64_is_unordered(0, fdt1, fdt0, &env->fpu->fp_status)  || float64_le(fdt0, fdt1, &env->fpu->fp_status))
+FOP_COND_D(f,   (float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status), 0))
+FOP_COND_D(un,  float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status))
+FOP_COND_D(eq,  !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ueq, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(olt, !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ult, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ole, !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ule, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
 /* NOTE: the comma operator will make "cond" to eval to false,
  * but float*_is_unordered() is still called. */
-FOP_COND_D(sf,  (float64_is_unordered(1, fdt1, fdt0, &env->fpu->fp_status), 0))
-FOP_COND_D(ngle,float64_is_unordered(1, fdt1, fdt0, &env->fpu->fp_status))
-FOP_COND_D(seq, !float64_is_unordered(1, fdt1, fdt0, &env->fpu->fp_status) && float64_eq(fdt0, fdt1, &env->fpu->fp_status))
-FOP_COND_D(ngl, float64_is_unordered(1, fdt1, fdt0, &env->fpu->fp_status)  || float64_eq(fdt0, fdt1, &env->fpu->fp_status))
-FOP_COND_D(lt,  !float64_is_unordered(1, fdt1, fdt0, &env->fpu->fp_status) && float64_lt(fdt0, fdt1, &env->fpu->fp_status))
-FOP_COND_D(nge, float64_is_unordered(1, fdt1, fdt0, &env->fpu->fp_status)  || float64_lt(fdt0, fdt1, &env->fpu->fp_status))
-FOP_COND_D(le,  !float64_is_unordered(1, fdt1, fdt0, &env->fpu->fp_status) && float64_le(fdt0, fdt1, &env->fpu->fp_status))
-FOP_COND_D(ngt, float64_is_unordered(1, fdt1, fdt0, &env->fpu->fp_status)  || float64_le(fdt0, fdt1, &env->fpu->fp_status))
+FOP_COND_D(sf,  (float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status), 0))
+FOP_COND_D(ngle,float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status))
+FOP_COND_D(seq, !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ngl, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(lt,  !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(nge, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(le,  !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+FOP_COND_D(ngt, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
 
 #define FOP_COND_S(op, cond)                                   \
 void do_cmp_s_ ## op (uint32_t fst0, uint32_t fst1, int cc)    \
@@ -2839,9 +2839,9 @@ void do_cmp_s_ ## op (uint32_t fst0, uint32_t fst1, int cc)    \
     int c = cond;                                              \
     update_fcr31();                                            \
     if (c)                                                     \
-        SET_FP_COND(cc, env->fpu);                             \
+        SET_FP_COND(cc, env->active_fpu);                      \
     else                                                       \
-        CLEAR_FP_COND(cc, env->fpu);                           \
+        CLEAR_FP_COND(cc, env->active_fpu);                    \
 }                                                              \
 void do_cmpabs_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \
 {                                                              \
@@ -2851,9 +2851,9 @@ void do_cmpabs_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \
     c = cond;                                                  \
     update_fcr31();                                            \
     if (c)                                                     \
-        SET_FP_COND(cc, env->fpu);                             \
+        SET_FP_COND(cc, env->active_fpu);                      \
     else                                                       \
-        CLEAR_FP_COND(cc, env->fpu);                           \
+        CLEAR_FP_COND(cc, env->active_fpu);                    \
 }
 
 flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
@@ -2872,24 +2872,24 @@ flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
 
 /* NOTE: the comma operator will make "cond" to eval to false,
  * but float*_is_unordered() is still called. */
-FOP_COND_S(f,   (float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status), 0))
-FOP_COND_S(un,  float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status))
-FOP_COND_S(eq,  !float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status) && float32_eq(fst0, fst1, &env->fpu->fp_status))
-FOP_COND_S(ueq, float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status)  || float32_eq(fst0, fst1, &env->fpu->fp_status))
-FOP_COND_S(olt, !float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status) && float32_lt(fst0, fst1, &env->fpu->fp_status))
-FOP_COND_S(ult, float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status)  || float32_lt(fst0, fst1, &env->fpu->fp_status))
-FOP_COND_S(ole, !float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status) && float32_le(fst0, fst1, &env->fpu->fp_status))
-FOP_COND_S(ule, float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status)  || float32_le(fst0, fst1, &env->fpu->fp_status))
+FOP_COND_S(f,   (float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status), 0))
+FOP_COND_S(un,  float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status))
+FOP_COND_S(eq,  !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ueq, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(olt, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ult, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ole, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ule, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
 /* NOTE: the comma operator will make "cond" to eval to false,
  * but float*_is_unordered() is still called. */
-FOP_COND_S(sf,  (float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status), 0))
-FOP_COND_S(ngle,float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status))
-FOP_COND_S(seq, !float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status) && float32_eq(fst0, fst1, &env->fpu->fp_status))
-FOP_COND_S(ngl, float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status)  || float32_eq(fst0, fst1, &env->fpu->fp_status))
-FOP_COND_S(lt,  !float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status) && float32_lt(fst0, fst1, &env->fpu->fp_status))
-FOP_COND_S(nge, float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status)  || float32_lt(fst0, fst1, &env->fpu->fp_status))
-FOP_COND_S(le,  !float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status) && float32_le(fst0, fst1, &env->fpu->fp_status))
-FOP_COND_S(ngt, float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status)  || float32_le(fst0, fst1, &env->fpu->fp_status))
+FOP_COND_S(sf,  (float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status), 0))
+FOP_COND_S(ngle,float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status))
+FOP_COND_S(seq, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ngl, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(lt,  !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(nge, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(le,  !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
+FOP_COND_S(ngt, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
 
 #define FOP_COND_PS(op, condl, condh)                           \
 void do_cmp_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc)    \
@@ -2903,13 +2903,13 @@ void do_cmp_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc)    \
                                                                 \
     update_fcr31();                                             \
     if (cl)                                                     \
-        SET_FP_COND(cc, env->fpu);                              \
+        SET_FP_COND(cc, env->active_fpu);                       \
     else                                                        \
-        CLEAR_FP_COND(cc, env->fpu);                            \
+        CLEAR_FP_COND(cc, env->active_fpu);                     \
     if (ch)                                                     \
-        SET_FP_COND(cc + 1, env->fpu);                          \
+        SET_FP_COND(cc + 1, env->active_fpu);                   \
     else                                                        \
-        CLEAR_FP_COND(cc + 1, env->fpu);                        \
+        CLEAR_FP_COND(cc + 1, env->active_fpu);                 \
 }                                                               \
 void do_cmpabs_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
 {                                                               \
@@ -2922,48 +2922,48 @@ void do_cmpabs_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
                                                                 \
     update_fcr31();                                             \
     if (cl)                                                     \
-        SET_FP_COND(cc, env->fpu);                              \
+        SET_FP_COND(cc, env->active_fpu);                       \
     else                                                        \
-        CLEAR_FP_COND(cc, env->fpu);                            \
+        CLEAR_FP_COND(cc, env->active_fpu);                     \
     if (ch)                                                     \
-        SET_FP_COND(cc + 1, env->fpu);                          \
+        SET_FP_COND(cc + 1, env->active_fpu);                   \
     else                                                        \
-        CLEAR_FP_COND(cc + 1, env->fpu);                        \
+        CLEAR_FP_COND(cc + 1, env->active_fpu);                 \
 }
 
 /* NOTE: the comma operator will make "cond" to eval to false,
  * but float*_is_unordered() is still called. */
-FOP_COND_PS(f,   (float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status), 0),
-                 (float32_is_unordered(0, fsth1, fsth0, &env->fpu->fp_status), 0))
-FOP_COND_PS(un,  float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status),
-                 float32_is_unordered(0, fsth1, fsth0, &env->fpu->fp_status))
-FOP_COND_PS(eq,  !float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status)   && float32_eq(fst0, fst1, &env->fpu->fp_status),
-                 !float32_is_unordered(0, fsth1, fsth0, &env->fpu->fp_status) && float32_eq(fsth0, fsth1, &env->fpu->fp_status))
-FOP_COND_PS(ueq, float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status)    || float32_eq(fst0, fst1, &env->fpu->fp_status),
-                 float32_is_unordered(0, fsth1, fsth0, &env->fpu->fp_status)  || float32_eq(fsth0, fsth1, &env->fpu->fp_status))
-FOP_COND_PS(olt, !float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status)   && float32_lt(fst0, fst1, &env->fpu->fp_status),
-                 !float32_is_unordered(0, fsth1, fsth0, &env->fpu->fp_status) && float32_lt(fsth0, fsth1, &env->fpu->fp_status))
-FOP_COND_PS(ult, float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status)    || float32_lt(fst0, fst1, &env->fpu->fp_status),
-                 float32_is_unordered(0, fsth1, fsth0, &env->fpu->fp_status)  || float32_lt(fsth0, fsth1, &env->fpu->fp_status))
-FOP_COND_PS(ole, !float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status)   && float32_le(fst0, fst1, &env->fpu->fp_status),
-                 !float32_is_unordered(0, fsth1, fsth0, &env->fpu->fp_status) && float32_le(fsth0, fsth1, &env->fpu->fp_status))
-FOP_COND_PS(ule, float32_is_unordered(0, fst1, fst0, &env->fpu->fp_status)    || float32_le(fst0, fst1, &env->fpu->fp_status),
-                 float32_is_unordered(0, fsth1, fsth0, &env->fpu->fp_status)  || float32_le(fsth0, fsth1, &env->fpu->fp_status))
+FOP_COND_PS(f,   (float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status), 0),
+                 (float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status), 0))
+FOP_COND_PS(un,  float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status),
+                 float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status))
+FOP_COND_PS(eq,  !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)   && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ueq, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(olt, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ult, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ole, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)   && float32_le(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ule, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
 /* NOTE: the comma operator will make "cond" to eval to false,
  * but float*_is_unordered() is still called. */
-FOP_COND_PS(sf,  (float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status), 0),
-                 (float32_is_unordered(1, fsth1, fsth0, &env->fpu->fp_status), 0))
-FOP_COND_PS(ngle,float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status),
-                 float32_is_unordered(1, fsth1, fsth0, &env->fpu->fp_status))
-FOP_COND_PS(seq, !float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status)   && float32_eq(fst0, fst1, &env->fpu->fp_status),
-                 !float32_is_unordered(1, fsth1, fsth0, &env->fpu->fp_status) && float32_eq(fsth0, fsth1, &env->fpu->fp_status))
-FOP_COND_PS(ngl, float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status)    || float32_eq(fst0, fst1, &env->fpu->fp_status),
-                 float32_is_unordered(1, fsth1, fsth0, &env->fpu->fp_status)  || float32_eq(fsth0, fsth1, &env->fpu->fp_status))
-FOP_COND_PS(lt,  !float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status)   && float32_lt(fst0, fst1, &env->fpu->fp_status),
-                 !float32_is_unordered(1, fsth1, fsth0, &env->fpu->fp_status) && float32_lt(fsth0, fsth1, &env->fpu->fp_status))
-FOP_COND_PS(nge, float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status)    || float32_lt(fst0, fst1, &env->fpu->fp_status),
-                 float32_is_unordered(1, fsth1, fsth0, &env->fpu->fp_status)  || float32_lt(fsth0, fsth1, &env->fpu->fp_status))
-FOP_COND_PS(le,  !float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status)   && float32_le(fst0, fst1, &env->fpu->fp_status),
-                 !float32_is_unordered(1, fsth1, fsth0, &env->fpu->fp_status) && float32_le(fsth0, fsth1, &env->fpu->fp_status))
-FOP_COND_PS(ngt, float32_is_unordered(1, fst1, fst0, &env->fpu->fp_status)    || float32_le(fst0, fst1, &env->fpu->fp_status),
-                 float32_is_unordered(1, fsth1, fsth0, &env->fpu->fp_status)  || float32_le(fsth0, fsth1, &env->fpu->fp_status))
+FOP_COND_PS(sf,  (float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status), 0),
+                 (float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status), 0))
+FOP_COND_PS(ngle,float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status),
+                 float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status))
+FOP_COND_PS(seq, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)   && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ngl, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(lt,  !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(nge, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(le,  !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)   && float32_le(fst0, fst1, &env->active_fpu.fp_status),
+                 !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
+FOP_COND_PS(ngt, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
+                 float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
index 3dded6c5808c04817306a1db35ed75c1c76d2b5d..bd358c875ed2c345fcaf6801ca97ab8daa4e8a16 100644 (file)
@@ -423,7 +423,8 @@ enum {
 };
 
 /* global register indices */
-static TCGv cpu_env, bcond, btarget, current_fpu;
+static TCGv cpu_env, bcond, btarget;
+static TCGv fpu_fpr32[32], fpu_fpr32h[32], fpu_fpr64[32], fpu_fcr0, fpu_fcr31;
 
 #include "gen-icount.h"
 
@@ -547,6 +548,18 @@ static const char *fregnames[] =
       "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
 
+static const char *fregnames_64[] =
+    { "F0",  "F1",  "F2",  "F3",  "F4",  "F5",  "F6",  "F7",
+      "F8",  "F9",  "F10", "F11", "F12", "F13", "F14", "F15",
+      "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23",
+      "F24", "F25", "F26", "F27", "F28", "F29", "F30", "F31", };
+
+static const char *fregnames_h[] =
+    { "h0",  "h1",  "h2",  "h3",  "h4",  "h5",  "h6",  "h7",
+      "h8",  "h9",  "h10", "h11", "h12", "h13", "h14", "h15",
+      "h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23",
+      "h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31", };
+
 #ifdef MIPS_DEBUG_DISAS
 #define MIPS_DEBUG(fmt, args...)                                              \
 do {                                                                          \
@@ -652,57 +665,48 @@ static inline void gen_store_srsgpr (int from, int to)
 /* Floating point register moves. */
 static inline void gen_load_fpr32 (TCGv t, int reg)
 {
-    tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX);
+    tcg_gen_mov_i32(t, fpu_fpr32[reg]);
 }
 
 static inline void gen_store_fpr32 (TCGv t, int reg)
 {
-    tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX);
+    tcg_gen_mov_i32(fpu_fpr32[reg], t);
 }
 
 static inline void gen_load_fpr64 (DisasContext *ctx, TCGv t, int reg)
 {
-    if (ctx->hflags & MIPS_HFLAG_F64) {
-        tcg_gen_ld_i64(t, current_fpu, 8 * reg);
-    } else {
-        TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
+    if (ctx->hflags & MIPS_HFLAG_F64)
+        tcg_gen_mov_i64(t, fpu_fpr64[reg]);
+    else {
         TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
 
-        tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX);
-        tcg_gen_extu_i32_i64(t, r_tmp1);
+        tcg_gen_extu_i32_i64(t, fpu_fpr32[reg | 1]);
         tcg_gen_shli_i64(t, t, 32);
-        tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX);
-        tcg_gen_extu_i32_i64(r_tmp2, r_tmp1);
+        tcg_gen_extu_i32_i64(r_tmp2, fpu_fpr32[reg & ~1]);
         tcg_gen_or_i64(t, t, r_tmp2);
-        tcg_temp_free(r_tmp1);
         tcg_temp_free(r_tmp2);
     }
 }
 
 static inline void gen_store_fpr64 (DisasContext *ctx, TCGv t, int reg)
 {
-    if (ctx->hflags & MIPS_HFLAG_F64) {
-        tcg_gen_st_i64(t, current_fpu, 8 * reg);
-    } else {
-        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
-
-        tcg_gen_trunc_i64_i32(r_tmp, t);
-        tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX);
+    if (ctx->hflags & MIPS_HFLAG_F64)
+        tcg_gen_mov_i64(fpu_fpr64[reg], t);
+    else {
+        tcg_gen_trunc_i64_i32(fpu_fpr32[reg & ~1], t);
         tcg_gen_shri_i64(t, t, 32);
-        tcg_gen_trunc_i64_i32(r_tmp, t);
-        tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX);
-        tcg_temp_free(r_tmp);
+        tcg_gen_trunc_i64_i32(fpu_fpr32[reg | 1], t);
     }
 }
 
 static inline void gen_load_fpr32h (TCGv t, int reg)
 {
-    tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX);
+    tcg_gen_mov_i32(t, fpu_fpr32h[reg]);
 }
 
 static inline void gen_store_fpr32h (TCGv t, int reg)
 {
-    tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX);
+    tcg_gen_mov_i32(fpu_fpr32h[reg], t);
 }
 
 static inline void get_fp_cond (TCGv t)
@@ -710,10 +714,9 @@ static inline void get_fp_cond (TCGv t)
     TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
     TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
 
-    tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
-    tcg_gen_shri_i32(r_tmp2, r_tmp1, 24);
+    tcg_gen_shri_i32(r_tmp2, fpu_fcr31, 24);
     tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe);
-    tcg_gen_shri_i32(r_tmp1, r_tmp1, 23);
+    tcg_gen_shri_i32(r_tmp1, fpu_fcr31, 23);
     tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1);
     tcg_gen_or_i32(t, r_tmp1, r_tmp2);
     tcg_temp_free(r_tmp1);
@@ -6009,8 +6012,7 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
 
     gen_load_gpr(t0, rd);
     gen_load_gpr(t1, rs);
-    tcg_gen_ld_i32(r_tmp, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
-    tcg_gen_andi_i32(r_tmp, r_tmp, ccbit);
+    tcg_gen_andi_i32(r_tmp, fpu_fcr31, ccbit);
     tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
     tcg_temp_free(r_tmp);
 
@@ -6043,8 +6045,7 @@ static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
 
     gen_load_fpr32(fp0, fs);
     gen_load_fpr32(fp1, fd);
-    tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
-    tcg_gen_andi_i32(r_tmp1, r_tmp1, ccbit);
+    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
     tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
     tcg_gen_mov_i32(fp1, fp0);
     tcg_temp_free(fp0);
@@ -6075,8 +6076,7 @@ static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int t
 
     gen_load_fpr64(ctx, fp0, fs);
     gen_load_fpr64(ctx, fp1, fd);
-    tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
-    tcg_gen_andi_i32(r_tmp1, r_tmp1, ccbit);
+    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
     tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
     tcg_gen_mov_i64(fp1, fp0);
     tcg_temp_free(fp0);
@@ -8632,11 +8632,11 @@ static void fpu_dump_state(CPUState *env, FILE *f,
 
 
     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
-                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
-                get_float_exception_flags(&env->fpu->fp_status));
+                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
+                get_float_exception_flags(&env->active_fpu.fp_status));
     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
         fpu_fprintf(f, "%3s: ", fregnames[i]);
-        printfpr(&env->fpu->fpr[i]);
+        printfpr(&env->active_fpu.fpr[i]);
     }
 
 #undef printfpr
@@ -8706,6 +8706,7 @@ void cpu_dump_state (CPUState *env, FILE *f,
 
 static void mips_tcg_init(void)
 {
+    int i;
     static int inited;
 
     /* Initialize various static tables. */
@@ -8717,10 +8718,24 @@ static void mips_tcg_init(void)
                                offsetof(CPUState, bcond), "bcond");
     btarget = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
                                  offsetof(CPUState, btarget), "btarget");
-    current_fpu = tcg_global_mem_new(TCG_TYPE_PTR,
-                                     TCG_AREG0,
-                                     offsetof(CPUState, fpu),
-                                     "current_fpu");
+    for (i = 0; i < 32; i++)
+        fpu_fpr32[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
+                                          offsetof(CPUState, active_fpu.fpr[i].w[FP_ENDIAN_IDX]),
+                                          fregnames[i]);
+    for (i = 0; i < 32; i++)
+        fpu_fpr64[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+                                          offsetof(CPUState, active_fpu.fpr[i]),
+                                          fregnames_64[i]);
+    for (i = 0; i < 32; i++)
+        fpu_fpr32h[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
+                                           offsetof(CPUState, active_fpu.fpr[i].w[!FP_ENDIAN_IDX]),
+                                           fregnames_h[i]);
+    fpu_fcr0 = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
+                                   offsetof(CPUState, active_fpu.fcr0),
+                                   "fcr0");
+    fpu_fcr31 = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
+                                   offsetof(CPUState, active_fpu.fcr31),
+                                   "fcr31");
 
     /* register helpers */
 #undef DEF_HELPER
index 8270c59901c6093d5eb1b3a7dfa2fe0a22175c0d..0026cd06ff760c83c3259d871ed6d945accb4bc0 100644 (file)
@@ -489,14 +489,17 @@ static void mmu_init (CPUMIPSState *env, const mips_def_t *def)
 
 static void fpu_init (CPUMIPSState *env, const mips_def_t *def)
 {
-    env->fpu = qemu_mallocz(sizeof(CPUMIPSFPUContext));
+    int i;
+
+    for (i = 0; i < MIPS_FPU_MAX; i++)
+        env->fpus[i].fcr0 = def->CP1_fcr0;
 
-    env->fpu->fcr0 = def->CP1_fcr0;
+    memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu));
     if (env->user_mode_only) {
         if (env->CP0_Config1 & (1 << CP0C1_FP))
             env->hflags |= MIPS_HFLAG_FPU;
 #ifdef TARGET_MIPS64
-        if (env->fpu->fcr0 & (1 << FCR0_F64))
+        if (env->active_fpu.fcr0 & (1 << FCR0_F64))
             env->hflags |= MIPS_HFLAG_F64;
 #endif
     }