bug-glibc
[Top][All Lists]
Advanced

[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;
   };
 






reply via email to

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