qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [patch] ppc float entianness


From: Paul Brook
Subject: [Qemu-devel] [patch] ppc float entianness
Date: Sun, 20 Mar 2005 21:18:44 +0000
User-agent: KMail/1.7.2

The PPC FPU emulation is broken on hosts with with weird floating point word 
ordering (ie. arm).

The attached patch fixes this by using CPU_DoubleU as appropriate.

Paul

Index: target-ppc/op_helper.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-ppc/op_helper.c,v
retrieving revision 1.12
diff -u -p -r1.12 op_helper.c
--- target-ppc/op_helper.c      13 Mar 2005 17:01:22 -0000      1.12
+++ target-ppc/op_helper.c      20 Mar 2005 21:09:33 -0000
@@ -180,25 +180,13 @@ void do_load_fpscr (void)
     /* The 32 MSB of the target fpr are undefined.
      * They'll be zero...
      */
-    union {
-        double d;
-        struct {
-            uint32_t u[2];
-        } s;
-    } u;
+    CPU_DoubleU u;
     int i;
 
-#ifdef WORDS_BIGENDIAN
-#define WORD0 0
-#define WORD1 1
-#else
-#define WORD0 1
-#define WORD1 0
-#endif
-    u.s.u[WORD0] = 0;
-    u.s.u[WORD1] = 0;
+    u.l.upper = 0;
+    u.l.lower = 0;
     for (i = 0; i < 8; i++)
-        u.s.u[WORD1] |= env->fpscr[i] << (4 * i);
+        u.l.lower |= env->fpscr[i] << (4 * i);
     FT0 = u.d;
 }
 
@@ -207,20 +195,15 @@ 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;
     int i, rnd_type;
 
     u.d = FT0;
     if (mask & 0x80)
-        env->fpscr[0] = (env->fpscr[0] & 0x9) | ((u.s.u[WORD1] >> 28) & ~0x9);
+        env->fpscr[0] = (env->fpscr[0] & 0x9) | ((u.l.lower >> 28) & ~0x9);
     for (i = 1; i < 7; i++) {
         if (mask & (1 << (7 - i)))
-            env->fpscr[i] = (u.s.u[WORD1] >> (4 * (7 - i))) & 0xF;
+            env->fpscr[i] = (u.l.lower >> (4 * (7 - i))) & 0xF;
     }
     /* TODO: update FEX & VX */
     /* Set rounding mode */
@@ -248,32 +231,30 @@ void do_store_fpscr (uint32_t mask)
 
 void do_fctiw (void)
 {
-    union {
-        double d;
-        uint64_t i;
-    } p;
+    CPU_DoubleU u;
+    uint64_t i;
 
     /* XXX: higher bits are not supposed to be significant.
      *      to make tests easier, return the same as a real PPC 750 (aka G3)
      */
-    p.i = float64_to_int32(FT0, &env->fp_status);
-    p.i |= 0xFFF80000ULL << 32;
-    FT0 = p.d;
+    i = float64_to_int32(FT0, &env->fp_status);
+    u.l.upper = i >> 32;
+    u.l.lower = i;
+    FT0 = u.d;
 }
 
 void do_fctiwz (void)
 {
-    union {
-        double d;
-        uint64_t i;
-    } p;
+    CPU_DoubleU u;
+    uint64_t i;
 
     /* XXX: higher bits are not supposed to be significant.
      *      to make tests easier, return the same as a real PPC 750 (aka G3)
      */
-    p.i = float64_to_int32_round_to_zero(FT0, &env->fp_status);
-    p.i |= 0xFFF80000ULL << 32;
-    FT0 = p.d;
+    i = float64_to_int32_round_to_zero(FT0, &env->fp_status);
+    u.l.upper = (i >> 32) | 0xFFF80000;
+    u.l.lower = i;
+    FT0 = u.d;
 }
 
 void do_fnmadd (void)
@@ -305,54 +286,55 @@ void do_fsqrt (void)
 
 void do_fres (void)
 {
-    union {
-        double d;
-        uint64_t i;
-    } p;
+    CPU_DoubleU u;
 
     if (isnormal(FT0)) {
         FT0 = (float)(1.0 / FT0);
     } else {
-        p.d = FT0;
-        if (p.i == 0x8000000000000000ULL) {
-            p.i = 0xFFF0000000000000ULL;
-        } else if (p.i == 0x0000000000000000ULL) {
-            p.i = 0x7FF0000000000000ULL;
+        u.d = FT0;
+        if (u.l.upper == 0x80000000u && u.l.lower == 0) {
+            u.l.upper = 0xFFF00000u;
+        } else if (u.l.upper == 0 && u.l.lower == 0) {
+            u.l.upper = 0x7FF00000u;
         } else if (isnan(FT0)) {
-            p.i = 0x7FF8000000000000ULL;
+            u.l.upper = 0x7FF80000u;
+            u.l.lower = 0;
         } else if (FT0 < 0.0) {
-            p.i = 0x8000000000000000ULL;
+            u.l.upper = 0x80000000u;
+            u.l.lower = 0;
         } else {
-            p.i = 0x0000000000000000ULL;
+            u.l.upper = 0;
+            u.l.lower = 0;
         }
-        FT0 = p.d;
+        FT0 = u.d;
     }
 }
 
 void do_frsqrte (void)
 {
-    union {
-        double d;
-        uint64_t i;
-    } p;
+    CPU_DoubleU u;
 
     if (isnormal(FT0) && FT0 > 0.0) {
         FT0 = (float)(1.0 / sqrt(FT0));
     } else {
-        p.d = FT0;
-        if (p.i == 0x8000000000000000ULL) {
-            p.i = 0xFFF0000000000000ULL;
-        } else if (p.i == 0x0000000000000000ULL) {
-            p.i = 0x7FF0000000000000ULL;
+        u.d = FT0;
+        if (u.l.upper == 0x80000000u && u.l.lower == 0) {
+            u.l.upper = 0xFFF00000u;
+        } else if (u.l.upper == 0 && u.l.lower == 0) {
+            u.l.upper = 0x7FF00000u;
         } else if (isnan(FT0)) {
-            if (!(p.i & 0x0008000000000000ULL))
-                p.i |= 0x000FFFFFFFFFFFFFULL;
-        } else if (FT0 < 0) {
-            p.i = 0x7FF8000000000000ULL;
+            if (!(u.l.upper & 0x00080000u)){
+                u.l.upper |= 0x000fffffu;
+                u.l.lower |= 0xffffffffu;
+            }
+        } else if (FT0 < 0.0) {
+            u.l.upper = 0x7ff80000u;
+            u.l.lower = 0;
         } else {
-            p.i = 0x0000000000000000ULL;
+            u.l.upper = 0;
+            u.l.lower = 0;
         }
-        FT0 = p.d;
+        FT0 = u.d;
     }
 }
 
@@ -406,26 +388,20 @@ void do_fcmpo (void)
 
 void do_fabs (void)
 {
-    union {
-        double d;
-        uint64_t i;
-    } p;
-
-    p.d = FT0;
-    p.i &= ~0x8000000000000000ULL;
-    FT0 = p.d;
+    CPU_DoubleU u;
+
+    u.d = FT0;
+    u.l.upper &= ~0x80000000u;
+    FT0 = u.d;
 }
 
 void do_fnabs (void)
 {
-    union {
-        double d;
-        uint64_t i;
-    } p;
-
-    p.d = FT0;
-    p.i |= 0x8000000000000000ULL;
-    FT0 = p.d;
+    CPU_DoubleU u;
+
+    u.d = FT0;
+    u.l.upper &= ~0x80000000u;
+    FT0 = u.d;
 }
 
 /* Instruction cache invalidation helper */

reply via email to

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