qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [5252] Move the active FPU registers into env again, and us


From: Thiemo Seufer
Subject: [Qemu-devel] [5252] Move the active FPU registers into env again, and use more TCG registers
Date: Thu, 18 Sep 2008 11:57:27 +0000

Revision: 5252
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5252
Author:   ths
Date:     2008-09-18 11:57:27 +0000 (Thu, 18 Sep 2008)

Log Message:
-----------
Move the active FPU registers into env again, and use more TCG registers
to access them.

Signed-off-by: Thiemo Seufer <address@hidden>

Modified Paths:
--------------
    trunk/gdbstub.c
    trunk/target-mips/TODO
    trunk/target-mips/cpu.h
    trunk/target-mips/exec.h
    trunk/target-mips/op_helper.c
    trunk/target-mips/translate.c
    trunk/target-mips/translate_init.c

Modified: trunk/gdbstub.c
===================================================================
--- trunk/gdbstub.c     2008-09-18 10:13:19 UTC (rev 5251)
+++ trunk/gdbstub.c     2008-09-18 11:57:27 UTC (rev 5252)
@@ -731,16 +731,16 @@
         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 @@
     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 @@
         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. */

Modified: trunk/target-mips/TODO
===================================================================
--- trunk/target-mips/TODO      2008-09-18 10:13:19 UTC (rev 5251)
+++ trunk/target-mips/TODO      2008-09-18 11:57:27 UTC (rev 5252)
@@ -30,11 +30,6 @@
   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
 ------

Modified: trunk/target-mips/cpu.h
===================================================================
--- trunk/target-mips/cpu.h     2008-09-18 10:13:19 UTC (rev 5251)
+++ trunk/target-mips/cpu.h     2008-09-18 11:57:27 UTC (rev 5252)
@@ -84,9 +84,9 @@
 #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 @@
 
 #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 @@
 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 @@
     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 */

Modified: trunk/target-mips/exec.h
===================================================================
--- trunk/target-mips/exec.h    2008-09-18 10:13:19 UTC (rev 5251)
+++ trunk/target-mips/exec.h    2008-09-18 11:57:27 UTC (rev 5252)
@@ -86,7 +86,7 @@
     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)

Modified: trunk/target-mips/op_helper.c
===================================================================
--- trunk/target-mips/op_helper.c       2008-09-18 10:13:19 UTC (rev 5251)
+++ trunk/target-mips/op_helper.c       2008-09-18 11:57:27 UTC (rev 5252)
@@ -1940,7 +1940,7 @@
 };
 
 #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 @@
 
     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 @@
     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 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 @@
 /* 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 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 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 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 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 @@
     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 @@
     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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 @@
     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 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 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 @@
     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 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 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 @@
     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 @@
 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 @@
     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 @@
 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 @@
     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 @@
 /* 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 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
 
 /* 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 @@
     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 @@
     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 @@
 
 /* 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 @@
                                                                 \
     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 @@
                                                                 \
     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))

Modified: trunk/target-mips/translate.c
===================================================================
--- trunk/target-mips/translate.c       2008-09-18 10:13:19 UTC (rev 5251)
+++ trunk/target-mips/translate.c       2008-09-18 11:57:27 UTC (rev 5252)
@@ -423,7 +423,8 @@
 };
 
 /* 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 @@
       "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 @@
 /* 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 @@
     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 @@
 
     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 @@
 
     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 @@
 
     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 @@
 
 
     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 @@
 
 static void mips_tcg_init(void)
 {
+    int i;
     static int inited;
 
     /* Initialize various static tables. */
@@ -8717,10 +8718,24 @@
                                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

Modified: trunk/target-mips/translate_init.c
===================================================================
--- trunk/target-mips/translate_init.c  2008-09-18 10:13:19 UTC (rev 5251)
+++ trunk/target-mips/translate_init.c  2008-09-18 11:57:27 UTC (rev 5252)
@@ -489,14 +489,17 @@
 
 static void fpu_init (CPUMIPSState *env, const mips_def_t *def)
 {
-    env->fpu = qemu_mallocz(sizeof(CPUMIPSFPUContext));
+    int i;
 
-    env->fpu->fcr0 = def->CP1_fcr0;
+    for (i = 0; i < MIPS_FPU_MAX; i++)
+        env->fpus[i].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
     }






reply via email to

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