diff options
-rw-r--r-- | cpu-all.h | 5 | ||||
-rw-r--r-- | target-ppc/op.c | 85 | ||||
-rw-r--r-- | target-ppc/op_helper.c | 418 | ||||
-rw-r--r-- | target-ppc/op_helper.h | 104 | ||||
-rw-r--r-- | target-ppc/op_helper_mem.h | 18 | ||||
-rw-r--r-- | target-ppc/op_mem.h | 69 |
6 files changed, 241 insertions, 458 deletions
@@ -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 { diff --git a/target-ppc/op.c b/target-ppc/op.c index 6cda0f0f64..972b8bc29d 100644 --- a/target-ppc/op.c +++ b/target-ppc/op.c @@ -580,47 +580,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; - - u.s.u[WORD0] = 0; - u.s.u[WORD1] = env->fpscr; + CPU_DoubleU u; + + 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) { @@ -3226,27 +3207,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(); } @@ -3282,27 +3257,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(); } diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 38467c44e6..7136e51f7d 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -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_op_excp (int op) 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_divide_excp (void) } } 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++) { @@ -992,10 +972,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 */ @@ -1004,12 +981,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; } @@ -1017,10 +994,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 */ @@ -1029,12 +1003,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; } @@ -1043,21 +1017,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 */ @@ -1066,17 +1034,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 */ @@ -1085,7 +1050,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; } } @@ -1271,10 +1236,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 */ @@ -1286,16 +1248,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; } @@ -1303,10 +1265,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 */ @@ -1323,16 +1282,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; } @@ -1340,10 +1299,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 */ @@ -1356,16 +1312,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; } @@ -2056,36 +2012,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; @@ -2095,12 +2042,9 @@ static always_inline int32_t _do_efsctsi (uint32_t val) 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; @@ -2110,12 +2054,9 @@ static always_inline uint32_t _do_efsctui (uint32_t val) 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; @@ -2125,12 +2066,9 @@ static always_inline int32_t _do_efsctsiz (uint32_t val) 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; @@ -2171,43 +2109,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; @@ -2219,13 +2148,10 @@ static always_inline int32_t _do_efsctsf (uint32_t val) 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; @@ -2237,13 +2163,10 @@ static always_inline uint32_t _do_efsctuf (uint32_t val) 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; @@ -2255,13 +2178,10 @@ static always_inline int32_t _do_efsctsfz (uint32_t val) 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; @@ -2338,86 +2258,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) @@ -2453,104 +2355,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) @@ -2586,36 +2470,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) diff --git a/target-ppc/op_helper.h b/target-ppc/op_helper.h index 5ec13a420d..1d5fc0a252 100644 --- a/target-ppc/op_helper.h +++ b/target-ppc/op_helper.h @@ -296,108 +296,78 @@ static always_inline uint32_t _do_efsneg (uint32_t val) } 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 diff --git a/target-ppc/op_helper_mem.h b/target-ppc/op_helper_mem.h index 1d7b991cac..c8ef7ce242 100644 --- a/target-ppc/op_helper_mem.h +++ b/target-ppc/op_helper_mem.h @@ -316,15 +316,12 @@ void glue(do_POWER2_lfq, MEMSUFFIX) (void) 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) (void) 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); } diff --git a/target-ppc/op_mem.h b/target-ppc/op_mem.h index 16dd4ceebf..eae9f4ea5c 100644 --- a/target-ppc/op_mem.h +++ b/target-ppc/op_mem.h @@ -267,31 +267,19 @@ void OPPROTO glue(glue(glue(op_st, name), _64), MEMSUFFIX) (void) \ } #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), _64), MEMSUFFIX) (void) \ } #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); } |