]> git.proxmox.com Git - mirror_qemu.git/blobdiff - target-ppc/op_helper.c
Suppress gcc 4.x -Wpointer-sign (included in -Wall) warnings
[mirror_qemu.git] / target-ppc / op_helper.c
index 68e90ceb57e239106c2782fa99b9520808c34011..46e9b7ab6c06db9b95fd586905c83ec886eb616e 100644 (file)
 #define MEMSUFFIX _kernel
 #include "op_helper.h"
 #include "op_helper_mem.h"
-#if defined(TARGET_PPC64H)
 #define MEMSUFFIX _hypv
 #include "op_helper.h"
 #include "op_helper_mem.h"
 #endif
-#endif
 
 //#define DEBUG_OP
 //#define DEBUG_EXCEPTIONS
@@ -246,7 +244,7 @@ void do_mulldo (void)
     int64_t th;
     uint64_t tl;
 
-    muls64(&tl, &th, T0, T1);
+    muls64(&tl, (uint64_t *)&th, T0, T1);
     T0 = (int64_t)tl;
     /* If th != 0 && th != -1, then we had an overflow */
     if (likely((uint64_t)(th + 1) <= 1)) {
@@ -457,54 +455,63 @@ void do_popcntb_64 (void)
 
 /*****************************************************************************/
 /* Floating point operations helpers */
-static always_inline int fpisneg (float64 f)
+static always_inline int fpisneg (float64 d)
+{
+    CPU_DoubleU u;
+
+    u.d = d;
+
+    return u.ll >> 63 != 0;
+}
+
+static always_inline int isden (float64 d)
+{
+    CPU_DoubleU u;
+
+    u.d = d;
+
+    return ((u.ll >> 52) & 0x7FF) == 0;
+}
+
+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 >> 63 != 0;
+    return (u.ll & ~0x8000000000000000ULL) == 0;
 }
 
-static always_inline int isden (float 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) == 0;
+    return ((u.ll >> 52) & 0x7FF) == 0x7FF &&
+        (u.ll & 0x000FFFFFFFFFFFFFULL) == 0;
 }
 
-static always_inline int iszero (float64 f)
+#ifdef CONFIG_SOFTFLOAT
+static always_inline int isfinite (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 >> 52) & 0x7FF) != 0x7FF);
 }
 
-static always_inline int isinfinity (float64 f)
+static always_inline int isnormal (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;
+    uint32_t exp = (u.ll >> 52) & 0x7FF;
+    return ((0 < exp) && (exp < 0x7FF));
 }
+#endif
 
 void do_compute_fprf (int set_fprf)
 {
@@ -640,10 +647,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));
@@ -658,11 +662,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;
     }
 }
 
@@ -867,18 +871,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++) {
@@ -890,12 +889,16 @@ void do_store_fpscr (uint32_t mask)
     /* Update VX and FEX */
     if (fpscr_ix != 0)
         env->fpscr |= 1 << FPSCR_VX;
+    else
+        env->fpscr &= ~(1 << FPSCR_VX);
     if ((fpscr_ex & fpscr_eex) != 0) {
         env->fpscr |= 1 << FPSCR_FEX;
         env->exception_index = POWERPC_EXCP_PROGRAM;
         /* XXX: we should compute it properly */
         env->error_code = POWERPC_EXCP_FP;
     }
+    else
+        env->fpscr &= ~(1 << FPSCR_FEX);
     fpscr_set_rounding_mode();
 }
 #undef WORD0
@@ -990,10 +993,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 */
@@ -1002,12 +1002,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;
     }
@@ -1015,10 +1015,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 */
@@ -1027,12 +1024,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;
     }
@@ -1041,21 +1038,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 */
@@ -1064,17 +1055,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 */
@@ -1083,7 +1071,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;
     }
 }
@@ -1269,10 +1257,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 */
@@ -1284,16 +1269,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;
     }
@@ -1301,10 +1286,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 */
@@ -1321,16 +1303,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;
     }
@@ -1338,10 +1320,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 */
@@ -1354,16 +1333,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;
     }
@@ -1427,7 +1406,7 @@ void cpu_dump_rfi (target_ulong RA, target_ulong msr);
 
 void do_store_msr (void)
 {
-    T0 = hreg_store_msr(env, T0);
+    T0 = hreg_store_msr(env, T0, 0);
     if (T0 != 0) {
         env->interrupt_request |= CPU_INTERRUPT_EXITTB;
         do_raise_exception(T0);
@@ -1453,7 +1432,7 @@ static always_inline void __do_rfi (target_ulong nip, target_ulong msr,
 #endif
     /* XXX: beware: this is false if VLE is supported */
     env->nip = nip & ~((target_ulong)0x00000003);
-    hreg_store_msr(env, msr);
+    hreg_store_msr(env, msr, 1);
 #if defined (DEBUG_OP)
     cpu_dump_rfi(env->nip, env->msr);
 #endif
@@ -1475,8 +1454,7 @@ void do_rfid (void)
     __do_rfi(env->spr[SPR_SRR0], env->spr[SPR_SRR1],
              ~((target_ulong)0xFFFF0000), 0);
 }
-#endif
-#if defined(TARGET_PPC64H)
+
 void do_hrfid (void)
 {
     __do_rfi(env->spr[SPR_HSRR0], env->spr[SPR_HSRR1],
@@ -1853,7 +1831,6 @@ void do_440_dlmzb (void)
     T0 = i;
 }
 
-#if defined(TARGET_PPCEMB)
 /* SPE extension helpers */
 /* Use a table to make this quicker */
 static uint8_t hbrev[16] = {
@@ -1872,16 +1849,16 @@ static always_inline uint32_t word_reverse (uint32_t val)
         (byte_reverse(val >> 8) << 16) | (byte_reverse(val) << 24);
 }
 
-#define MASKBITS 16 // Random value - to be fixed
+#define MASKBITS 16 // Random value - to be fixed (implementation dependant)
 void do_brinc (void)
 {
     uint32_t a, b, d, mask;
 
-    mask = UINT32_MAX >> MASKBITS;
-    b = T1_64 & mask;
-    a = T0_64 & mask;
-    d = word_reverse(1 + word_reverse(a | ~mask));
-    T0_64 = (T0_64 & ~mask) | (d & mask);
+    mask = UINT32_MAX >> (32 - MASKBITS);
+    a = T0 & mask;
+    b = T1 & mask;
+    d = word_reverse(1 + word_reverse(a | ~b));
+    T0 = (T0 & ~mask) | (d & b);
 }
 
 #define DO_SPE_OP2(name)                                                      \
@@ -2056,36 +2033,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 +2063,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 +2075,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 +2087,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 +2130,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 +2169,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 +2184,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 +2199,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 +2279,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 +2376,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 +2491,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)
@@ -2713,18 +2606,12 @@ DO_SPE_OP1(fsctuiz);
 DO_SPE_OP1(fsctsf);
 /* evfsctuf */
 DO_SPE_OP1(fsctuf);
-#endif /* defined(TARGET_PPCEMB) */
 
 /*****************************************************************************/
 /* Softmmu support */
 #if !defined (CONFIG_USER_ONLY)
 
 #define MMUSUFFIX _mmu
-#ifdef __s390__
-# define GETPC() ((void*)((unsigned long)__builtin_return_address(0) & 0x7fffffffUL))
-#else
-# define GETPC() (__builtin_return_address(0))
-#endif
 
 #define SHIFT 0
 #include "softmmu_template.h"
@@ -2788,9 +2675,9 @@ void do_load_6xx_tlb (int is_code)
     way = (env->spr[SPR_SRR1] >> 17) & 1;
 #if defined (DEBUG_SOFTWARE_TLB)
     if (loglevel != 0) {
-        fprintf(logfile, "%s: EPN %08lx %08lx PTE0 %08lx PTE1 %08lx way %d\n",
-                __func__, (unsigned long)T0, (unsigned long)EPN,
-                (unsigned long)CMP, (unsigned long)RPN, way);
+        fprintf(logfile, "%s: EPN " TDX " " ADDRX " PTE0 " ADDRX
+                " PTE1 " ADDRX " way %d\n",
+                __func__, T0, EPN, CMP, RPN, way);
     }
 #endif
     /* Store this TLB */
@@ -2809,9 +2696,9 @@ void do_load_74xx_tlb (int is_code)
     way = env->spr[SPR_TLBMISS] & 0x3;
 #if defined (DEBUG_SOFTWARE_TLB)
     if (loglevel != 0) {
-        fprintf(logfile, "%s: EPN %08lx %08lx PTE0 %08lx PTE1 %08lx way %d\n",
-                __func__, (unsigned long)T0, (unsigned long)EPN,
-                (unsigned long)CMP, (unsigned long)RPN, way);
+        fprintf(logfile, "%s: EPN " TDX " " ADDRX " PTE0 " ADDRX
+                " PTE1 " ADDRX " way %d\n",
+                __func__, T0, EPN, CMP, RPN, way);
     }
 #endif
     /* Store this TLB */
@@ -2925,7 +2812,7 @@ void do_4xx_tlbwe_hi (void)
 
 #if defined (DEBUG_SOFTWARE_TLB)
     if (loglevel != 0) {
-        fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1);
+        fprintf(logfile, "%s T0 " TDX " T1 " TDX "\n", __func__, T0, T1);
     }
 #endif
     T0 &= 0x3F;
@@ -2994,7 +2881,7 @@ void do_4xx_tlbwe_lo (void)
 
 #if defined (DEBUG_SOFTWARE_TLB)
     if (loglevel != 0) {
-        fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1);
+        fprintf(logfile, "%s T0 " TDX " T1 " TDX "\n", __func__, T0, T1);
     }
 #endif
     T0 &= 0x3F;
@@ -3027,7 +2914,7 @@ void do_440_tlbwe (int word)
 
 #if defined (DEBUG_SOFTWARE_TLB)
     if (loglevel != 0) {
-        fprintf(logfile, "%s word %d T0 " REGX " T1 " REGX "\n",
+        fprintf(logfile, "%s word %d T0 " TDX " T1 " TDX "\n",
                 __func__, word, T0, T1);
     }
 #endif