This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[RFA] ARM IEEE byte ordering patch


Hi Jeff,

  Intel recently turned up a bug in newlib with this simple test
  program:

      int 
      main (void)
      {
        return printf ("%f\n", 1000000000000000.0);
      }

  Which for little endian ARMs will print rubbish.  It turns out that
  this is because of ARMs weird IEEE format where the words are always
  stored in big endian order, even though the bytes inside the words
  are stored in the target's native format.  It was thought that this
  made no difference to newlib, but it turns out that there is one
  macro - Storeinc - which is affected.

  The patch below fixes this problem, by defining
  __IEEE_BYTES_LITTLE_ENDIAN for little endian ARMs and then selecting
  the correct definition of Storeinc based partially on this
  definition. 

  May I apply the patch ?

Cheers

Nick

2001-06-27  Nick Clifton  <nickc@cambridge.redhat.com>

	* libc/include/machine/ieeefp.h (__IEEE_BYTES_LITTLE_ENDIAN):
	Define for little endian ARMs.

	* libc/stdlib/mprec.h (Storeinc): Use little endian version if
	__IEEE_BYTES_LITTLE_ENDIAN is defined.

Index: include/machine/ieeefp.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/include/machine/ieeefp.h,v
retrieving revision 1.5
diff -p -r1.5 ieeefp.h
*** ieeefp.h	2001/04/04 13:30:58	1.5
--- ieeefp.h	2001/06/27 08:57:19
***************
*** 21,29 ****
  
  #if defined(__arm__) || defined(__thumb__)
  /* ARM always has big-endian words.  Within those words the byte ordering
!    appears to be big or little endian.  Newlib doesn't seem to care about
!    the byte ordering within words.  */
  #define __IEEE_BIG_ENDIAN
  #endif
  
  #ifdef __hppa__
--- 21,31 ----
  
  #if defined(__arm__) || defined(__thumb__)
  /* ARM always has big-endian words.  Within those words the byte ordering
!    will be big or little endian depending upon the target.  */
  #define __IEEE_BIG_ENDIAN
+ #ifdef __ARMEL__
+ #define __IEEE_BYTES_LITTLE_ENDIAN
+ #endif
  #endif
  
  #ifdef __hppa__
Index: stdlib/mprec.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdlib/mprec.h,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 mprec.h
*** mprec.h	2000/02/17 19:39:48	1.1.1.1
--- mprec.h	2001/06/27 08:57:20
*************** union double_union
*** 81,87 ****
   * An alternative that might be better on some machines is
   * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
   */
! #if defined(IEEE_8087) + defined(VAX)
  #define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
  ((unsigned short *)a)[0] = (unsigned short)c, a++)
  #else
--- 81,87 ----
   * An alternative that might be better on some machines is
   * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
   */
! #if defined (__IEEE_BYTES_LITTLE_ENDIAN) + defined (IEEE_8087) + defined (VAX)
  #define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
  ((unsigned short *)a)[0] = (unsigned short)c, a++)
  #else


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]