[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
xscale (bigendian) floating point problem
From: |
Pauli |
Subject: |
xscale (bigendian) floating point problem |
Date: |
Thu, 14 Aug 2003 09:22:51 +1000 |
>Submitter-Id: net
>Originator: Pauli
>Organization:
SnapGear
>Confidential: no
>Synopsis: floating point doesn't work for big endian arm targets
>Severity: serious
>Priority: medium
>Category: libc
>Class: sw-bug
>Release: libc-2.2.5
>Environment:
Host type: --linux-gnu
System: Linux skaro 2.4.20-3-k7 #1 Sun Jun 8 01:35:14 EST 2003 i686 GNU/Linux
Architecture: i686
Addons: linuxthreads ncurses
Build CFLAGS: -DEMBED -O2
Compiler version: arm-linux-gcc version 3.2.1
Symbol versioning: yes
Build static: yes
Build shared: yes
Build pic-default: no
Build profile: no
Build omitfp: no
Build bounded: no
Build static-nss: no
Stdio: libio
>Description:
Floating point operations in glibc are broken when built for
an Intel IXP425 target. This processor demands to run in big
endian mode.
We pass in explicit -mbig-endian in CFLAGS and -EB in LDFLAGS to
cater for this.
I've checked the sources for libc-2.3.2 and it appears to have
the same problem.
>How-To-Repeat:
int main() {
printf("%g\n", 3.0);
return 0;
}
>Fix:
The sysdeps/arm/ieee754.h which defines the internal structure
of the floating point types doesn't appear to support
endian issues properly. Grabbing the appropriate bits from
sysdeps/ieee754/ieee754.h seems to fix the problem.
Unified diff of changes that seemed to fix the problem for me:
@@ -32,18 +32,33 @@
/* This is the IEEE 754 single-precision format. */
struct
{
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:8;
+ unsigned int mantissa:23;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int mantissa:23;
unsigned int exponent:8;
unsigned int negative:1;
+#endif /* Little endian. */
} ieee;
/* This format makes it easier to see if a NaN is a signalling NaN. */
struct
{
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:8;
+ unsigned int quiet_nan:1;
+ unsigned int mantissa:22;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int mantissa:22;
unsigned int quiet_nan:1;
unsigned int exponent:8;
unsigned int negative:1;
+#endif /* Little endian. */
} ieee_nan;
};
@@ -57,20 +72,55 @@
/* This is the IEEE 754 double-precision format. */
struct
{
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:20;
+ unsigned int mantissa1:32;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# if __FLOAT_WORD_ORDER == BIG_ENDIAN
unsigned int mantissa0:20;
unsigned int exponent:11;
unsigned int negative:1;
unsigned int mantissa1:32;
+# else
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:20;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+# endif
+#endif /* Little endian. */
} ieee;
/* This format makes it easier to see if a NaN is a signalling NaN. */
struct
{
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ unsigned int quiet_nan:1;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:19;
+ unsigned int mantissa1:32;
+#else
+# if __FLOAT_WORD_ORDER == BIG_ENDIAN
unsigned int mantissa0:19;
unsigned int quiet_nan:1;
unsigned int exponent:11;
unsigned int negative:1;
unsigned int mantissa1:32;
+# else
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:19;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+# endif
+#endif
} ieee_nan;
};
@@ -88,23 +138,61 @@
/* This is the IEEE 854 double-extended-precision format. */
struct
{
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
unsigned int exponent:15;
unsigned int empty:16;
+ unsigned int mantissa0:32;
+ unsigned int mantissa1:32;
+#endif
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# if __FLOAT_WORD_ORDER == BIG_ENDIAN
+ unsigned int exponent:15;
unsigned int negative:1;
+ unsigned int empty:16;
+ unsigned int mantissa0:32;
+ unsigned int mantissa1:32;
+# else
unsigned int mantissa1:32;
unsigned int mantissa0:32;
+ unsigned int exponent:15;
+ unsigned int negative:1;
+ unsigned int empty:16;
+# endif
+#endif
} ieee;
/* This is for NaNs in the IEEE 854 double-extended-precision format. */
struct
{
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
unsigned int exponent:15;
unsigned int empty:16;
+ unsigned int one:1;
+ unsigned int quiet_nan:1;
+ unsigned int mantissa0:30;
+ unsigned int mantissa1:32;
+#endif
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# if __FLOAT_WORD_ORDER == BIG_ENDIAN
+ unsigned int exponent:15;
unsigned int negative:1;
+ unsigned int empty:16;
+ unsigned int mantissa0:30;
+ unsigned int quiet_nan:1;
+ unsigned int one:1;
+ unsigned int mantissa1:32;
+# else
unsigned int mantissa1:32;
unsigned int mantissa0:30;
unsigned int quiet_nan:1;
unsigned int one:1;
+ unsigned int exponent:15;
+ unsigned int negative:1;
+ unsigned int empty:16;
+# endif
+#endif
} ieee_nan;
};
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- xscale (bigendian) floating point problem,
Pauli <=