[Top][All Lists]
[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 */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [patch] ppc float entianness,
Paul Brook <=