qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [patch] ppc float entianness
@ 2005-03-20 21:18 Paul Brook
  0 siblings, 0 replies; only message in thread
From: Paul Brook @ 2005-03-20 21:18 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 173 bytes --]

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


[-- Attachment #2: patch.qemu_ppc_double --]
[-- Type: text/x-diff, Size: 5714 bytes --]

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 */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2005-03-20 21:45 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-20 21:18 [Qemu-devel] [patch] ppc float entianness Paul Brook

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).