qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH][PPC] Use float32/64 instead of float/double


From: Aurelien Jarno
Subject: Re: [Qemu-devel] [PATCH][PPC] Use float32/64 instead of float/double
Date: Thu, 3 Jan 2008 00:26:46 +0100
User-agent: Mutt/1.5.13 (2006-08-11)

On Sun, Dec 30, 2007 at 06:32:45PM +0200, Blue Swirl wrote:
> On 12/30/07, Aurelien Jarno <address@hidden> wrote:
> > The patch below changes the float and double types into float32 and
> > and float64 types in the PPC code. This doesn't change anything when
> > using softfloat-native as the types are the same, but that helps
> > compiling the PPC target with softfloat.
> 
> You could also consider replacing the unions with the common
> definition CPU_DoubleU in cpu-all.h and also add CPU_FloatU.

Good idea. Please find and updated patch below.


The patch below uses the float32 and float64 types instead of the float
and double types in the PPC code. This doesn't change anything when
using softfloat-native as the types are the same, but that helps 
compiling the PPC target with softfloat.

It also defines a new union CPU_FloatU in addition to CPU_DoubleU, and
use them instead of identical unions that are defined in numerous 
places.

 cpu-all.h                  |    5 
 target-ppc/op.c            |   83 ++------
 target-ppc/op_helper.c     |  418 +++++++++++++++------------------------------
 target-ppc/op_helper.h     |  104 +++--------
 target-ppc/op_helper_mem.h |   18 -
 target-ppc/op_mem.h        |   69 ++-----
 6 files changed, 240 insertions(+), 457 deletions(-)

Index: cpu-all.h
===================================================================
RCS file: /sources/qemu/qemu/cpu-all.h,v
retrieving revision 1.81
diff -u -d -p -r1.81 cpu-all.h
--- cpu-all.h   1 Jan 2008 16:57:19 -0000       1.81
+++ cpu-all.h   2 Jan 2008 23:21:06 -0000
@@ -116,6 +116,11 @@ static inline void tswap64s(uint64_t *s)
 #define bswaptls(s) bswap64s(s)
 #endif
 
+typedef union {
+    float32 f;
+    uint32_t l;
+} CPU_FloatU;
+
 /* NOTE: arm FPA is horrible as double 32 bit words are stored in big
    endian ! */
 typedef union {
Index: target-ppc/op.c
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/op.c,v
retrieving revision 1.68
diff -u -d -p -r1.68 op.c
--- target-ppc/op.c     16 Nov 2007 14:11:28 -0000      1.68
+++ target-ppc/op.c     2 Jan 2008 23:21:06 -0000
@@ -585,47 +585,28 @@ void OPPROTO op_float_check_status (void
 }
 #endif
 
-#if defined(WORDS_BIGENDIAN)
-#define WORD0 0
-#define WORD1 1
-#else
-#define WORD0 1
-#define WORD1 0
-#endif
 void OPPROTO op_load_fpscr_FT0 (void)
 {
     /* The 32 MSB of the target fpr are undefined.
      * They'll be zero...
      */
-    union {
-        float64 d;
-        struct {
-            uint32_t u[2];
-        } s;
-    } u;
+    CPU_DoubleU u;
 
-    u.s.u[WORD0] = 0;
-    u.s.u[WORD1] = env->fpscr;
+    u.l.upper = 0;
+    u.l.lower = env->fpscr;
     FT0 = u.d;
     RETURN();
 }
 
 void OPPROTO op_set_FT0 (void)
 {
-    union {
-        float64 d;
-        struct {
-            uint32_t u[2];
-        } s;
-    } u;
+    CPU_DoubleU u;
 
-    u.s.u[WORD0] = 0;
-    u.s.u[WORD1] = PARAM1;
+    u.l.upper = 0;
+    u.l.lower = PARAM1;
     FT0 = u.d;
     RETURN();
 }
-#undef WORD0
-#undef WORD1
 
 void OPPROTO op_load_fpscr_T0 (void)
 {
@@ -3241,27 +3222,21 @@ void OPPROTO op_efststeq (void)
 
 void OPPROTO op_efdsub (void)
 {
-    union {
-        uint64_t u;
-        float64 f;
-    } u1, u2;
-    u1.u = T0_64;
-    u2.u = T1_64;
-    u1.f = float64_sub(u1.f, u2.f, &env->spe_status);
-    T0_64 = u1.u;
+    CPU_DoubleU u1, u2;
+    u1.ll = T0_64;
+    u2.ll = T1_64;
+    u1.d = float64_sub(u1.d, u2.d, &env->spe_status);
+    T0_64 = u1.ll;
     RETURN();
 }
 
 void OPPROTO op_efdadd (void)
 {
-    union {
-        uint64_t u;
-        float64 f;
-    } u1, u2;
-    u1.u = T0_64;
-    u2.u = T1_64;
-    u1.f = float64_add(u1.f, u2.f, &env->spe_status);
-    T0_64 = u1.u;
+    CPU_DoubleU u1, u2;
+    u1.ll = T0_64;
+    u2.ll = T1_64;
+    u1.d = float64_add(u1.d, u2.d, &env->spe_status);
+    T0_64 = u1.ll;
     RETURN();
 }
 
@@ -3297,27 +3272,21 @@ void OPPROTO op_efdneg (void)
 
 void OPPROTO op_efddiv (void)
 {
-    union {
-        uint64_t u;
-        float64 f;
-    } u1, u2;
-    u1.u = T0_64;
-    u2.u = T1_64;
-    u1.f = float64_div(u1.f, u2.f, &env->spe_status);
-    T0_64 = u1.u;
+    CPU_DoubleU u1, u2;
+    u1.ll = T0_64;
+    u2.ll = T1_64;
+    u1.d = float64_div(u1.d, u2.d, &env->spe_status);
+    T0_64 = u1.ll;
     RETURN();
 }
 
 void OPPROTO op_efdmul (void)
 {
-    union {
-        uint64_t u;
-        float64 f;
-    } u1, u2;
-    u1.u = T0_64;
-    u2.u = T1_64;
-    u1.f = float64_mul(u1.f, u2.f, &env->spe_status);
-    T0_64 = u1.u;
+    CPU_DoubleU u1, u2;
+    u1.ll = T0_64;
+    u2.ll = T1_64;
+    u1.d = float64_mul(u1.d, u2.d, &env->spe_status);
+    T0_64 = u1.ll;
     RETURN();
 }
 
Index: target-ppc/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/op_helper.c,v
retrieving revision 1.73
diff -u -d -p -r1.73 op_helper.c
--- target-ppc/op_helper.c      24 Nov 2007 02:03:55 -0000      1.73
+++ target-ppc/op_helper.c      2 Jan 2008 23:21:06 -0000
@@ -455,53 +455,41 @@ void do_popcntb_64 (void)
 
 /*****************************************************************************/
 /* Floating point operations helpers */
-static always_inline int fpisneg (float64 f)
+static always_inline int fpisneg (float64 d)
 {
-    union {
-        float64 f;
-        uint64_t u;
-    } u;
+    CPU_DoubleU u;
 
-    u.f = f;
+    u.d = d;
 
-    return u.u >> 63 != 0;
+    return u.ll >> 63 != 0;
 }
 
-static always_inline int isden (float f)
+static always_inline int isden (float64 d)
 {
-    union {
-        float64 f;
-        uint64_t u;
-    } u;
+    CPU_DoubleU u;
 
-    u.f = f;
+    u.d = d;
 
-    return ((u.u >> 52) & 0x7FF) == 0;
+    return ((u.ll >> 52) & 0x7FF) == 0;
 }
 
-static always_inline int iszero (float64 f)
+static always_inline int iszero (float64 d)
 {
-    union {
-        float64 f;
-        uint64_t u;
-    } u;
+    CPU_DoubleU u;
 
-    u.f = f;
+    u.d = d;
 
-    return (u.u & ~0x8000000000000000ULL) == 0;
+    return (u.ll & ~0x8000000000000000ULL) == 0;
 }
 
-static always_inline int isinfinity (float64 f)
+static always_inline int isinfinity (float64 d)
 {
-    union {
-        float64 f;
-        uint64_t u;
-    } u;
+    CPU_DoubleU u;
 
-    u.f = f;
+    u.d = d;
 
-    return ((u.u >> 52) & 0x7FF) == 0x7FF &&
-        (u.u & 0x000FFFFFFFFFFFFFULL) == 0;
+    return ((u.ll >> 52) & 0x7FF) == 0x7FF &&
+        (u.ll & 0x000FFFFFFFFFFFFFULL) == 0;
 }
 
 void do_compute_fprf (int set_fprf)
@@ -638,10 +626,7 @@ static always_inline void fload_invalid_
 
 static always_inline void float_zero_divide_excp (void)
 {
-    union {
-        float64 f;
-        uint64_t u;
-    } u0, u1;
+    CPU_DoubleU u0, u1;
 
     env->fpscr |= 1 << FPSCR_ZX;
     env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
@@ -656,11 +641,11 @@ static always_inline void float_zero_div
         }
     } else {
         /* Set the result to infinity */
-        u0.f = FT0;
-        u1.f = FT1;
-        u0.u = ((u0.u ^ u1.u) & 0x8000000000000000ULL);
-        u0.u |= 0x7FFULL << 52;
-        FT0 = u0.f;
+        u0.d = FT0;
+        u1.d = FT1;
+        u0.ll = ((u0.ll ^ u1.ll) & 0x8000000000000000ULL);
+        u0.ll |= 0x7FFULL << 52;
+        FT0 = u0.d;
     }
 }
 
@@ -865,18 +850,13 @@ void do_store_fpscr (uint32_t mask)
     /*
      * We use only the 32 LSB of the incoming fpr
      */
-    union {
-        double d;
-        struct {
-            uint32_t u[2];
-        } s;
-    } u;
+    CPU_DoubleU u;
     uint32_t prev, new;
     int i;
 
     u.d = FT0;
     prev = env->fpscr;
-    new = u.s.u[WORD1];
+    new = u.l.lower;
     new &= ~0x90000000;
     new |= prev & 0x90000000;
     for (i = 0; i < 7; i++) {
@@ -988,10 +968,7 @@ void do_fdiv (void)
 
 void do_fctiw (void)
 {
-    union {
-        double d;
-        uint64_t i;
-    } p;
+    CPU_DoubleU p;
 
     if (unlikely(float64_is_signaling_nan(FT0))) {
         /* sNaN conversion */
@@ -1000,12 +977,12 @@ void do_fctiw (void)
         /* qNan / infinity conversion */
         fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);
     } else {
-        p.i = float64_to_int32(FT0, &env->fp_status);
+        p.ll = float64_to_int32(FT0, &env->fp_status);
 #if USE_PRECISE_EMULATION
         /* XXX: higher bits are not supposed to be significant.
          *     to make tests easier, return the same as a real PowerPC 750
          */
-        p.i |= 0xFFF80000ULL << 32;
+        p.ll |= 0xFFF80000ULL << 32;
 #endif
         FT0 = p.d;
     }
@@ -1013,10 +990,7 @@ void do_fctiw (void)
 
 void do_fctiwz (void)
 {
-    union {
-        double d;
-        uint64_t i;
-    } p;
+    CPU_DoubleU p;
 
     if (unlikely(float64_is_signaling_nan(FT0))) {
         /* sNaN conversion */
@@ -1025,12 +999,12 @@ void do_fctiwz (void)
         /* qNan / infinity conversion */
         fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);
     } else {
-        p.i = float64_to_int32_round_to_zero(FT0, &env->fp_status);
+        p.ll = float64_to_int32_round_to_zero(FT0, &env->fp_status);
 #if USE_PRECISE_EMULATION
         /* XXX: higher bits are not supposed to be significant.
          *     to make tests easier, return the same as a real PowerPC 750
          */
-        p.i |= 0xFFF80000ULL << 32;
+        p.ll |= 0xFFF80000ULL << 32;
 #endif
         FT0 = p.d;
     }
@@ -1039,21 +1013,15 @@ void do_fctiwz (void)
 #if defined(TARGET_PPC64)
 void do_fcfid (void)
 {
-    union {
-        double d;
-        uint64_t i;
-    } p;
+    CPU_DoubleU p;
 
     p.d = FT0;
-    FT0 = int64_to_float64(p.i, &env->fp_status);
+    FT0 = int64_to_float64(p.ll, &env->fp_status);
 }
 
 void do_fctid (void)
 {
-    union {
-        double d;
-        uint64_t i;
-    } p;
+    CPU_DoubleU p;
 
     if (unlikely(float64_is_signaling_nan(FT0))) {
         /* sNaN conversion */
@@ -1062,17 +1030,14 @@ void do_fctid (void)
         /* qNan / infinity conversion */
         fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);
     } else {
-        p.i = float64_to_int64(FT0, &env->fp_status);
+        p.ll = float64_to_int64(FT0, &env->fp_status);
         FT0 = p.d;
     }
 }
 
 void do_fctidz (void)
 {
-    union {
-        double d;
-        uint64_t i;
-    } p;
+    CPU_DoubleU p;
 
     if (unlikely(float64_is_signaling_nan(FT0))) {
         /* sNaN conversion */
@@ -1081,7 +1046,7 @@ void do_fctidz (void)
         /* qNan / infinity conversion */
         fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);
     } else {
-        p.i = float64_to_int64_round_to_zero(FT0, &env->fp_status);
+        p.ll = float64_to_int64_round_to_zero(FT0, &env->fp_status);
         FT0 = p.d;
     }
 }
@@ -1267,10 +1232,7 @@ void do_fsqrt (void)
 
 void do_fre (void)
 {
-    union {
-        double d;
-        uint64_t i;
-    } p;
+    CPU_DoubleU p;
 
     if (unlikely(float64_is_signaling_nan(FT0))) {
         /* sNaN reciprocal */
@@ -1282,16 +1244,16 @@ void do_fre (void)
         FT0 = float64_div(1.0, FT0, &env->fp_status);
     } else {
         p.d = FT0;
-        if (p.i == 0x8000000000000000ULL) {
-            p.i = 0xFFF0000000000000ULL;
-        } else if (p.i == 0x0000000000000000ULL) {
-            p.i = 0x7FF0000000000000ULL;
+        if (p.ll == 0x8000000000000000ULL) {
+            p.ll = 0xFFF0000000000000ULL;
+        } else if (p.ll == 0x0000000000000000ULL) {
+            p.ll = 0x7FF0000000000000ULL;
         } else if (isnan(FT0)) {
-            p.i = 0x7FF8000000000000ULL;
+            p.ll = 0x7FF8000000000000ULL;
         } else if (fpisneg(FT0)) {
-            p.i = 0x8000000000000000ULL;
+            p.ll = 0x8000000000000000ULL;
         } else {
-            p.i = 0x0000000000000000ULL;
+            p.ll = 0x0000000000000000ULL;
         }
         FT0 = p.d;
     }
@@ -1299,10 +1261,7 @@ void do_fre (void)
 
 void do_fres (void)
 {
-    union {
-        double d;
-        uint64_t i;
-    } p;
+    CPU_DoubleU p;
 
     if (unlikely(float64_is_signaling_nan(FT0))) {
         /* sNaN reciprocal */
@@ -1319,16 +1278,16 @@ void do_fres (void)
 #endif
     } else {
         p.d = FT0;
-        if (p.i == 0x8000000000000000ULL) {
-            p.i = 0xFFF0000000000000ULL;
-        } else if (p.i == 0x0000000000000000ULL) {
-            p.i = 0x7FF0000000000000ULL;
+        if (p.ll == 0x8000000000000000ULL) {
+            p.ll = 0xFFF0000000000000ULL;
+        } else if (p.ll == 0x0000000000000000ULL) {
+            p.ll = 0x7FF0000000000000ULL;
         } else if (isnan(FT0)) {
-            p.i = 0x7FF8000000000000ULL;
+            p.ll = 0x7FF8000000000000ULL;
         } else if (fpisneg(FT0)) {
-            p.i = 0x8000000000000000ULL;
+            p.ll = 0x8000000000000000ULL;
         } else {
-            p.i = 0x0000000000000000ULL;
+            p.ll = 0x0000000000000000ULL;
         }
         FT0 = p.d;
     }
@@ -1336,10 +1295,7 @@ void do_fres (void)
 
 void do_frsqrte (void)
 {
-    union {
-        double d;
-        uint64_t i;
-    } p;
+    CPU_DoubleU p;
 
     if (unlikely(float64_is_signaling_nan(FT0))) {
         /* sNaN reciprocal square root */
@@ -1352,16 +1308,16 @@ void do_frsqrte (void)
         FT0 = float32_div(1.0, FT0, &env->fp_status);
     } else {
         p.d = FT0;
-        if (p.i == 0x8000000000000000ULL) {
-            p.i = 0xFFF0000000000000ULL;
-        } else if (p.i == 0x0000000000000000ULL) {
-            p.i = 0x7FF0000000000000ULL;
+        if (p.ll == 0x8000000000000000ULL) {
+            p.ll = 0xFFF0000000000000ULL;
+        } else if (p.ll == 0x0000000000000000ULL) {
+            p.ll = 0x7FF0000000000000ULL;
         } else if (isnan(FT0)) {
-            p.i |= 0x000FFFFFFFFFFFFFULL;
+            p.ll |= 0x000FFFFFFFFFFFFFULL;
         } else if (fpisneg(FT0)) {
-            p.i = 0x7FF8000000000000ULL;
+            p.ll = 0x7FF8000000000000ULL;
         } else {
-            p.i = 0x0000000000000000ULL;
+            p.ll = 0x0000000000000000ULL;
         }
         FT0 = p.d;
     }
@@ -2052,36 +2008,27 @@ DO_SPE_CMP(cmpltu);
 /* Single precision floating-point conversions from/to integer */
 static always_inline uint32_t _do_efscfsi (int32_t val)
 {
-    union {
-        uint32_t u;
-        float32 f;
-    } u;
+    CPU_FloatU u;
 
     u.f = int32_to_float32(val, &env->spe_status);
 
-    return u.u;
+    return u.l;
 }
 
 static always_inline uint32_t _do_efscfui (uint32_t val)
 {
-    union {
-        uint32_t u;
-        float32 f;
-    } u;
+    CPU_FloatU u;
 
     u.f = uint32_to_float32(val, &env->spe_status);
 
-    return u.u;
+    return u.l;
 }
 
 static always_inline int32_t _do_efsctsi (uint32_t val)
 {
-    union {
-        int32_t u;
-        float32 f;
-    } u;
+    CPU_FloatU u;
 
-    u.u = val;
+    u.l = val;
     /* NaN are not treated the same way IEEE 754 does */
     if (unlikely(isnan(u.f)))
         return 0;
@@ -2091,12 +2038,9 @@ static always_inline int32_t _do_efsctsi
 
 static always_inline uint32_t _do_efsctui (uint32_t val)
 {
-    union {
-        int32_t u;
-        float32 f;
-    } u;
+    CPU_FloatU u;
 
-    u.u = val;
+    u.l = val;
     /* NaN are not treated the same way IEEE 754 does */
     if (unlikely(isnan(u.f)))
         return 0;
@@ -2106,12 +2050,9 @@ static always_inline uint32_t _do_efsctu
 
 static always_inline int32_t _do_efsctsiz (uint32_t val)
 {
-    union {
-        int32_t u;
-        float32 f;
-    } u;
+    CPU_FloatU u;
 
-    u.u = val;
+    u.l = val;
     /* NaN are not treated the same way IEEE 754 does */
     if (unlikely(isnan(u.f)))
         return 0;
@@ -2121,12 +2062,9 @@ static always_inline int32_t _do_efsctsi
 
 static always_inline uint32_t _do_efsctuiz (uint32_t val)
 {
-    union {
-        int32_t u;
-        float32 f;
-    } u;
+    CPU_FloatU u;
 
-    u.u = val;
+    u.l = val;
     /* NaN are not treated the same way IEEE 754 does */
     if (unlikely(isnan(u.f)))
         return 0;
@@ -2167,43 +2105,34 @@ void do_efsctuiz (void)
 /* Single precision floating-point conversion to/from fractional */
 static always_inline uint32_t _do_efscfsf (uint32_t val)
 {
-    union {
-        uint32_t u;
-        float32 f;
-    } u;
+    CPU_FloatU u;
     float32 tmp;
 
     u.f = int32_to_float32(val, &env->spe_status);
     tmp = int64_to_float32(1ULL << 32, &env->spe_status);
     u.f = float32_div(u.f, tmp, &env->spe_status);
 
-    return u.u;
+    return u.l;
 }
 
 static always_inline uint32_t _do_efscfuf (uint32_t val)
 {
-    union {
-        uint32_t u;
-        float32 f;
-    } u;
+    CPU_FloatU u;
     float32 tmp;
 
     u.f = uint32_to_float32(val, &env->spe_status);
     tmp = uint64_to_float32(1ULL << 32, &env->spe_status);
     u.f = float32_div(u.f, tmp, &env->spe_status);
 
-    return u.u;
+    return u.l;
 }
 
 static always_inline int32_t _do_efsctsf (uint32_t val)
 {
-    union {
-        int32_t u;
-        float32 f;
-    } u;
+    CPU_FloatU u;
     float32 tmp;
 
-    u.u = val;
+    u.l = val;
     /* NaN are not treated the same way IEEE 754 does */
     if (unlikely(isnan(u.f)))
         return 0;
@@ -2215,13 +2144,10 @@ static always_inline int32_t _do_efsctsf
 
 static always_inline uint32_t _do_efsctuf (uint32_t val)
 {
-    union {
-        int32_t u;
-        float32 f;
-    } u;
+    CPU_FloatU u;
     float32 tmp;
 
-    u.u = val;
+    u.l = val;
     /* NaN are not treated the same way IEEE 754 does */
     if (unlikely(isnan(u.f)))
         return 0;
@@ -2233,13 +2159,10 @@ static always_inline uint32_t _do_efsctu
 
 static always_inline int32_t _do_efsctsfz (uint32_t val)
 {
-    union {
-        int32_t u;
-        float32 f;
-    } u;
+    CPU_FloatU u;
     float32 tmp;
 
-    u.u = val;
+    u.l = val;
     /* NaN are not treated the same way IEEE 754 does */
     if (unlikely(isnan(u.f)))
         return 0;
@@ -2251,13 +2174,10 @@ static always_inline int32_t _do_efsctsf
 
 static always_inline uint32_t _do_efsctufz (uint32_t val)
 {
-    union {
-        int32_t u;
-        float32 f;
-    } u;
+    CPU_FloatU u;
     float32 tmp;
 
-    u.u = val;
+    u.l = val;
     /* NaN are not treated the same way IEEE 754 does */
     if (unlikely(isnan(u.f)))
         return 0;
@@ -2334,86 +2254,68 @@ void do_efdcmpeq (void)
 /* Double precision floating-point conversion to/from integer */
 static always_inline uint64_t _do_efdcfsi (int64_t val)
 {
-    union {
-        uint64_t u;
-        float64 f;
-    } u;
+    CPU_DoubleU u;
 
-    u.f = int64_to_float64(val, &env->spe_status);
+    u.d = int64_to_float64(val, &env->spe_status);
 
-    return u.u;
+    return u.ll;
 }
 
 static always_inline uint64_t _do_efdcfui (uint64_t val)
 {
-    union {
-        uint64_t u;
-        float64 f;
-    } u;
+    CPU_DoubleU u;
 
-    u.f = uint64_to_float64(val, &env->spe_status);
+    u.d = uint64_to_float64(val, &env->spe_status);
 
-    return u.u;
+    return u.ll;
 }
 
 static always_inline int64_t _do_efdctsi (uint64_t val)
 {
-    union {
-        int64_t u;
-        float64 f;
-    } u;
+    CPU_DoubleU u;
 
-    u.u = val;
+    u.ll = val;
     /* NaN are not treated the same way IEEE 754 does */
-    if (unlikely(isnan(u.f)))
+    if (unlikely(isnan(u.d)))
         return 0;
 
-    return float64_to_int64(u.f, &env->spe_status);
+    return float64_to_int64(u.d, &env->spe_status);
 }
 
 static always_inline uint64_t _do_efdctui (uint64_t val)
 {
-    union {
-        int64_t u;
-        float64 f;
-    } u;
+    CPU_DoubleU u;
 
-    u.u = val;
+    u.ll = val;
     /* NaN are not treated the same way IEEE 754 does */
-    if (unlikely(isnan(u.f)))
+    if (unlikely(isnan(u.d)))
         return 0;
 
-    return float64_to_uint64(u.f, &env->spe_status);
+    return float64_to_uint64(u.d, &env->spe_status);
 }
 
 static always_inline int64_t _do_efdctsiz (uint64_t val)
 {
-    union {
-        int64_t u;
-        float64 f;
-    } u;
+    CPU_DoubleU u;
 
-    u.u = val;
+    u.ll = val;
     /* NaN are not treated the same way IEEE 754 does */
-    if (unlikely(isnan(u.f)))
+    if (unlikely(isnan(u.d)))
         return 0;
 
-    return float64_to_int64_round_to_zero(u.f, &env->spe_status);
+    return float64_to_int64_round_to_zero(u.d, &env->spe_status);
 }
 
 static always_inline uint64_t _do_efdctuiz (uint64_t val)
 {
-    union {
-        int64_t u;
-        float64 f;
-    } u;
+    CPU_DoubleU u;
 
-    u.u = val;
+    u.ll = val;
     /* NaN are not treated the same way IEEE 754 does */
-    if (unlikely(isnan(u.f)))
+    if (unlikely(isnan(u.d)))
         return 0;
 
-    return float64_to_uint64_round_to_zero(u.f, &env->spe_status);
+    return float64_to_uint64_round_to_zero(u.d, &env->spe_status);
 }
 
 void do_efdcfsi (void)
@@ -2449,104 +2351,86 @@ void do_efdctuiz (void)
 /* Double precision floating-point conversion to/from fractional */
 static always_inline uint64_t _do_efdcfsf (int64_t val)
 {
-    union {
-        uint64_t u;
-        float64 f;
-    } u;
+    CPU_DoubleU u;
     float64 tmp;
 
-    u.f = int32_to_float64(val, &env->spe_status);
+    u.d = int32_to_float64(val, &env->spe_status);
     tmp = int64_to_float64(1ULL << 32, &env->spe_status);
-    u.f = float64_div(u.f, tmp, &env->spe_status);
+    u.d = float64_div(u.d, tmp, &env->spe_status);
 
-    return u.u;
+    return u.ll;
 }
 
 static always_inline uint64_t _do_efdcfuf (uint64_t val)
 {
-    union {
-        uint64_t u;
-        float64 f;
-    } u;
+    CPU_DoubleU u;
     float64 tmp;
 
-    u.f = uint32_to_float64(val, &env->spe_status);
+    u.d = uint32_to_float64(val, &env->spe_status);
     tmp = int64_to_float64(1ULL << 32, &env->spe_status);
-    u.f = float64_div(u.f, tmp, &env->spe_status);
+    u.d = float64_div(u.d, tmp, &env->spe_status);
 
-    return u.u;
+    return u.ll;
 }
 
 static always_inline int64_t _do_efdctsf (uint64_t val)
 {
-    union {
-        int64_t u;
-        float64 f;
-    } u;
+    CPU_DoubleU u;
     float64 tmp;
 
-    u.u = val;
+    u.ll = val;
     /* NaN are not treated the same way IEEE 754 does */
-    if (unlikely(isnan(u.f)))
+    if (unlikely(isnan(u.d)))
         return 0;
     tmp = uint64_to_float64(1ULL << 32, &env->spe_status);
-    u.f = float64_mul(u.f, tmp, &env->spe_status);
+    u.d = float64_mul(u.d, tmp, &env->spe_status);
 
-    return float64_to_int32(u.f, &env->spe_status);
+    return float64_to_int32(u.d, &env->spe_status);
 }
 
 static always_inline uint64_t _do_efdctuf (uint64_t val)
 {
-    union {
-        int64_t u;
-        float64 f;
-    } u;
+    CPU_DoubleU u;
     float64 tmp;
 
-    u.u = val;
+    u.ll = val;
     /* NaN are not treated the same way IEEE 754 does */
-    if (unlikely(isnan(u.f)))
+    if (unlikely(isnan(u.d)))
         return 0;
     tmp = uint64_to_float64(1ULL << 32, &env->spe_status);
-    u.f = float64_mul(u.f, tmp, &env->spe_status);
+    u.d = float64_mul(u.d, tmp, &env->spe_status);
 
-    return float64_to_uint32(u.f, &env->spe_status);
+    return float64_to_uint32(u.d, &env->spe_status);
 }
 
 static always_inline int64_t _do_efdctsfz (uint64_t val)
 {
-    union {
-        int64_t u;
-        float64 f;
-    } u;
+    CPU_DoubleU u;
     float64 tmp;
 
-    u.u = val;
+    u.ll = val;
     /* NaN are not treated the same way IEEE 754 does */
-    if (unlikely(isnan(u.f)))
+    if (unlikely(isnan(u.d)))
         return 0;
     tmp = uint64_to_float64(1ULL << 32, &env->spe_status);
-    u.f = float64_mul(u.f, tmp, &env->spe_status);
+    u.d = float64_mul(u.d, tmp, &env->spe_status);
 
-    return float64_to_int32_round_to_zero(u.f, &env->spe_status);
+    return float64_to_int32_round_to_zero(u.d, &env->spe_status);
 }
 
 static always_inline uint64_t _do_efdctufz (uint64_t val)
 {
-    union {
-        int64_t u;
-        float64 f;
-    } u;
+    CPU_DoubleU u;
     float64 tmp;
 
-    u.u = val;
+    u.ll = val;
     /* NaN are not treated the same way IEEE 754 does */
-    if (unlikely(isnan(u.f)))
+    if (unlikely(isnan(u.d)))
         return 0;
     tmp = uint64_to_float64(1ULL << 32, &env->spe_status);
-    u.f = float64_mul(u.f, tmp, &env->spe_status);
+    u.d = float64_mul(u.d, tmp, &env->spe_status);
 
-    return float64_to_uint32_round_to_zero(u.f, &env->spe_status);
+    return float64_to_uint32_round_to_zero(u.d, &env->spe_status);
 }
 
 void do_efdcfsf (void)
@@ -2582,36 +2466,24 @@ void do_efdctufz (void)
 /* Floating point conversion between single and double precision */
 static always_inline uint32_t _do_efscfd (uint64_t val)
 {
-    union {
-        uint64_t u;
-        float64 f;
-    } u1;
-    union {
-        uint32_t u;
-        float32 f;
-    } u2;
+    CPU_DoubleU u1;
+    CPU_FloatU u2;
 
-    u1.u = val;
-    u2.f = float64_to_float32(u1.f, &env->spe_status);
+    u1.ll = val;
+    u2.f = float64_to_float32(u1.d, &env->spe_status);
 
-    return u2.u;
+    return u2.l;
 }
 
 static always_inline uint64_t _do_efdcfs (uint32_t val)
 {
-    union {
-        uint64_t u;
-        float64 f;
-    } u2;
-    union {
-        uint32_t u;
-        float32 f;
-    } u1;
+    CPU_DoubleU u2;
+    CPU_FloatU u1;
 
-    u1.u = val;
-    u2.f = float32_to_float64(u1.f, &env->spe_status);
+    u1.l = val;
+    u2.d = float32_to_float64(u1.f, &env->spe_status);
 
-    return u2.u;
+    return u2.ll;
 }
 
 void do_efscfd (void)
Index: target-ppc/op_helper.h
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/op_helper.h,v
retrieving revision 1.30
diff -u -d -p -r1.30 op_helper.h
--- target-ppc/op_helper.h      22 Nov 2007 11:00:46 -0000      1.30
+++ target-ppc/op_helper.h      2 Jan 2008 23:21:06 -0000
@@ -296,108 +296,78 @@ static always_inline uint32_t _do_efsneg
 }
 static always_inline uint32_t _do_efsadd (uint32_t op1, uint32_t op2)
 {
-    union {
-        uint32_t u;
-        float32 f;
-    } u1, u2;
-    u1.u = op1;
-    u2.u = op2;
+    CPU_FloatU u1, u2;
+    u1.l = op1;
+    u2.l = op2;
     u1.f = float32_add(u1.f, u2.f, &env->spe_status);
-    return u1.u;
+    return u1.l;
 }
 static always_inline uint32_t _do_efssub (uint32_t op1, uint32_t op2)
 {
-    union {
-        uint32_t u;
-        float32 f;
-    } u1, u2;
-    u1.u = op1;
-    u2.u = op2;
+    CPU_FloatU u1, u2;
+    u1.l = op1;
+    u2.l = op2;
     u1.f = float32_sub(u1.f, u2.f, &env->spe_status);
-    return u1.u;
+    return u1.l;
 }
 static always_inline uint32_t _do_efsmul (uint32_t op1, uint32_t op2)
 {
-    union {
-        uint32_t u;
-        float32 f;
-    } u1, u2;
-    u1.u = op1;
-    u2.u = op2;
+    CPU_FloatU u1, u2;
+    u1.l = op1;
+    u2.l = op2;
     u1.f = float32_mul(u1.f, u2.f, &env->spe_status);
-    return u1.u;
+    return u1.l;
 }
 static always_inline uint32_t _do_efsdiv (uint32_t op1, uint32_t op2)
 {
-    union {
-        uint32_t u;
-        float32 f;
-    } u1, u2;
-    u1.u = op1;
-    u2.u = op2;
+    CPU_FloatU u1, u2;
+    u1.l = op1;
+    u2.l = op2;
     u1.f = float32_div(u1.f, u2.f, &env->spe_status);
-    return u1.u;
+    return u1.l;
 }
 
 static always_inline int _do_efststlt (uint32_t op1, uint32_t op2)
 {
-    union {
-        uint32_t u;
-        float32 f;
-    } u1, u2;
-    u1.u = op1;
-    u2.u = op2;
+    CPU_FloatU u1, u2;
+    u1.l = op1;
+    u2.l = op2;
     return float32_lt(u1.f, u2.f, &env->spe_status) ? 1 : 0;
 }
 static always_inline int _do_efststgt (uint32_t op1, uint32_t op2)
 {
-    union {
-        uint32_t u;
-        float32 f;
-    } u1, u2;
-    u1.u = op1;
-    u2.u = op2;
+    CPU_FloatU u1, u2;
+    u1.l = op1;
+    u2.l = op2;
     return float32_le(u1.f, u2.f, &env->spe_status) ? 0 : 1;
 }
 static always_inline int _do_efststeq (uint32_t op1, uint32_t op2)
 {
-    union {
-        uint32_t u;
-        float32 f;
-    } u1, u2;
-    u1.u = op1;
-    u2.u = op2;
+    CPU_FloatU u1, u2;
+    u1.l = op1;
+    u2.l = op2;
     return float32_eq(u1.f, u2.f, &env->spe_status) ? 1 : 0;
 }
 /* Double precision floating-point helpers */
 static always_inline int _do_efdtstlt (uint64_t op1, uint64_t op2)
 {
-    union {
-        uint64_t u;
-        float64 f;
-    } u1, u2;
-    u1.u = op1;
-    u2.u = op2;
-    return float64_lt(u1.f, u2.f, &env->spe_status) ? 1 : 0;
+    CPU_DoubleU u1, u2;
+    u1.ll = op1;
+    u2.ll = op2;
+    return float64_lt(u1.d, u2.d, &env->spe_status) ? 1 : 0;
 }
 static always_inline int _do_efdtstgt (uint64_t op1, uint64_t op2)
 {
-    union {
-        uint64_t u;
-        float64 f;
-    } u1, u2;
-    u1.u = op1;
-    u2.u = op2;
-    return float64_le(u1.f, u2.f, &env->spe_status) ? 0 : 1;
+    CPU_DoubleU u1, u2;
+    u1.ll = op1;
+    u2.ll = op2;
+    return float64_le(u1.d, u2.d, &env->spe_status) ? 0 : 1;
 }
 static always_inline int _do_efdtsteq (uint64_t op1, uint64_t op2)
 {
-    union {
-        uint64_t u;
-        float64 f;
-    } u1, u2;
-    u1.u = op1;
-    u2.u = op2;
-    return float64_eq(u1.f, u2.f, &env->spe_status) ? 1 : 0;
+    CPU_DoubleU u1, u2;
+    u1.ll = op1;
+    u2.ll = op2;
+    return float64_eq(u1.d, u2.d, &env->spe_status) ? 1 : 0;
 }
 #endif
Index: target-ppc/op_helper_mem.h
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/op_helper_mem.h,v
retrieving revision 1.16
diff -u -d -p -r1.16 op_helper_mem.h
--- target-ppc/op_helper_mem.h  22 Nov 2007 11:00:46 -0000      1.16
+++ target-ppc/op_helper_mem.h  2 Jan 2008 23:21:06 -0000
@@ -316,15 +316,12 @@ void glue(do_POWER2_lfq, MEMSUFFIX) (voi
     FT1 = glue(ldfq, MEMSUFFIX)((uint32_t)(T0 + 4));
 }
 
-static always_inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA)
+static always_inline float64 glue(ldfqr, MEMSUFFIX) (target_ulong EA)
 {
-    union {
-        double d;
-        uint64_t u;
-    } u;
+    CPU_DoubleU u;
 
     u.d = glue(ldfq, MEMSUFFIX)(EA);
-    u.u = bswap64(u.u);
+    u.ll = bswap64(u.ll);
 
     return u.d;
 }
@@ -341,15 +338,12 @@ void glue(do_POWER2_stfq, MEMSUFFIX) (vo
     glue(stfq, MEMSUFFIX)((uint32_t)(T0 + 4), FT1);
 }
 
-static always_inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d)
+static always_inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, float64 d)
 {
-    union {
-        double d;
-        uint64_t u;
-    } u;
+    CPU_DoubleU u;
 
     u.d = d;
-    u.u = bswap64(u.u);
+    u.ll = bswap64(u.ll);
     glue(stfq, MEMSUFFIX)(EA, u.d);
 }
 
Index: target-ppc/op_mem.h
===================================================================
RCS file: /sources/qemu/qemu/target-ppc/op_mem.h,v
retrieving revision 1.27
diff -u -d -p -r1.27 op_mem.h
--- target-ppc/op_mem.h 22 Nov 2007 11:00:46 -0000      1.27
+++ target-ppc/op_mem.h 2 Jan 2008 23:21:06 -0000
@@ -267,31 +267,19 @@ void OPPROTO glue(glue(glue(op_st, name)
 }
 #endif
 
-static always_inline void glue(stfs, MEMSUFFIX) (target_ulong EA, double d)
+static always_inline void glue(stfs, MEMSUFFIX) (target_ulong EA, float64 d)
 {
     glue(stfl, MEMSUFFIX)(EA, float64_to_float32(d, &env->fp_status));
 }
 
-#if defined(WORDS_BIGENDIAN)
-#define WORD0 0
-#define WORD1 1
-#else
-#define WORD0 1
-#define WORD1 0
-#endif
-static always_inline void glue(stfiw, MEMSUFFIX) (target_ulong EA, double d)
+static always_inline void glue(stfiw, MEMSUFFIX) (target_ulong EA, float64 d)
 {
-    union {
-        double d;
-        uint32_t u[2];
-    } u;
+    CPU_DoubleU u;
 
     /* Store the low order 32 bits without any conversion */
     u.d = d;
-    glue(st32, MEMSUFFIX)(EA, u.u[WORD0]);
+    glue(st32, MEMSUFFIX)(EA, u.l.lower);
 }
-#undef WORD0
-#undef WORD1
 
 PPC_STF_OP(fd, stfq);
 PPC_STF_OP(fs, stfs);
@@ -302,41 +290,32 @@ PPC_STF_OP_64(fs, stfs);
 PPC_STF_OP_64(fiw, stfiw);
 #endif
 
-static always_inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d)
+static always_inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, float64 d)
 {
-    union {
-        double d;
-        uint64_t u;
-    } u;
+    CPU_DoubleU u;
 
     u.d = d;
-    u.u = bswap64(u.u);
+    u.ll = bswap64(u.ll);
     glue(stfq, MEMSUFFIX)(EA, u.d);
 }
 
-static always_inline void glue(stfsr, MEMSUFFIX) (target_ulong EA, double d)
+static always_inline void glue(stfsr, MEMSUFFIX) (target_ulong EA, float64 d)
 {
-    union {
-        float f;
-        uint32_t u;
-    } u;
+    CPU_FloatU u;
 
     u.f = float64_to_float32(d, &env->fp_status);
-    u.u = bswap32(u.u);
+    u.l = bswap32(u.l);
     glue(stfl, MEMSUFFIX)(EA, u.f);
 }
 
-static always_inline void glue(stfiwr, MEMSUFFIX) (target_ulong EA, double d)
+static always_inline void glue(stfiwr, MEMSUFFIX) (target_ulong EA, float64 d)
 {
-    union {
-        double d;
-        uint64_t u;
-    } u;
+    CPU_DoubleU u;
 
     /* Store the low order 32 bits without any conversion */
     u.d = d;
-    u.u = bswap32(u.u);
-    glue(st32, MEMSUFFIX)(EA, u.u);
+    u.l.lower = bswap32(u.l.lower);
+    glue(st32, MEMSUFFIX)(EA, u.l.lower);
 }
 
 PPC_STF_OP(fd_le, stfqr);
@@ -365,7 +344,7 @@ void OPPROTO glue(glue(glue(op_l, name),
 }
 #endif
 
-static always_inline double glue(ldfs, MEMSUFFIX) (target_ulong EA)
+static always_inline float64 glue(ldfs, MEMSUFFIX) (target_ulong EA)
 {
     return float32_to_float64(glue(ldfl, MEMSUFFIX)(EA), &env->fp_status);
 }
@@ -377,28 +356,22 @@ PPC_LDF_OP_64(fd, ldfq);
 PPC_LDF_OP_64(fs, ldfs);
 #endif
 
-static always_inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA)
+static always_inline float64 glue(ldfqr, MEMSUFFIX) (target_ulong EA)
 {
-    union {
-        double d;
-        uint64_t u;
-    } u;
+    CPU_DoubleU u;
 
     u.d = glue(ldfq, MEMSUFFIX)(EA);
-    u.u = bswap64(u.u);
+    u.ll = bswap64(u.ll);
 
     return u.d;
 }
 
-static always_inline double glue(ldfsr, MEMSUFFIX) (target_ulong EA)
+static always_inline float64 glue(ldfsr, MEMSUFFIX) (target_ulong EA)
 {
-    union {
-        float f;
-        uint32_t u;
-    } u;
+    CPU_FloatU u;
 
     u.f = glue(ldfl, MEMSUFFIX)(EA);
-    u.u = bswap32(u.u);
+    u.l = bswap32(u.l);
 
     return float32_to_float64(u.f, &env->fp_status);
 }


-- 
  .''`.  Aurelien Jarno             | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   address@hidden         | address@hidden
   `-    people.debian.org/~aurel32 | www.aurel32.net




reply via email to

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