This is the mail archive of the newlib@sourceware.org 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]
Other format: [Raw text]

[RFC/PATCH] Enable IEEE_Arith when double is 32 bits for strtod


Hi,

Attached is a 2 part patch I have constructed against 1.15.0 of newlib
in which part 1 fixes some compilation errors detected as a result of
defining "IEEE_Arith" in part 2 of the patch.

The second part of the patch fixes an error detected by Plumhall C test
suite (2007A) when running an application where doubles are 32 bits (in
this instance with the GCC SH4 ABI -m4-single-only). The test suite is
expecting that +/- HUGE_VAL is returned on overflow, which is the case
when a double is 64 bits but not when 32 bits. Part 2 of the patch
enables this behaviour. I also have attached a reduced form of the test
which illustrates the failure.

The ChangeLog entry:

        * libc/stdlib/mprec.h [_DOUBLE_IS_32BITS}: Define IEEE_Arith
	bits and redefine associated dword0 macro (rvalue issue).
	* libc/stdio/vfieeefp.h: Ditto.
        * libc/stdlib/strtod.c: Add checks for _DOUBLE_IS_32BITS
        to prevent setting dword1 which is an rvalue only.

Cheers,

Antony.

--- newlib/libc/stdio/vfieeefp.h@@/NEWLIB-1.15.0	2004-05-26 01:19:14.000000000 +0100
+++ newlib/libc/stdio/vfieeefp.h	2007-08-17 18:13:46.259368000 +0100
@@ -170,9 +170,7 @@
 #define Exp_mask    ((__uint32_t)0x7f800000L)
 #define P    	    24
 #define Bias 	    127
-#if 0
-#define IEEE_Arith  /* it is, but the code doesn't handle IEEE singles yet */
-#endif
+#define IEEE_Arith
 #define Emin        (-126)
 #define Exp_1       ((__uint32_t)0x3f800000L)
 #define Exp_11      ((__uint32_t)0x3f800000L)
--- newlib/libc/stdlib/mprec.h.orig	2007-08-28 11:41:24.994483000 +0100
+++ newlib/libc/stdlib/mprec.h	2007-08-17 18:56:06.969216000 +0100
@@ -139,15 +139,7 @@
 #define P    	    24
 #define Bias 	    127
 #define NO_HEX_FP   /* not supported in this case */
-#if 0
-#define IEEE_Arith  /* it is, but the code doesn't handle IEEE singles yet */
-#endif
-/* Following is needed due to IEEE_Arith not being set on above.  */
-#if defined(__v800)
-#define n_bigtens 2
-#else
-#define n_bigtens 5
-#endif
+#define IEEE_Arith
 #define Emin        (-126)
 #define Exp_1       ((__uint32_t)0x3f800000L)
 #define Exp_11      ((__uint32_t)0x3f800000L)
--- newlib/libc/stdlib/mprec.h@@/NEWLIB-1.15.0	2006-07-05 17:18:30.000000000 +0100
+++ newlib/libc/stdlib/mprec.h	2007-08-28 11:41:24.994483000 +0100
@@ -175,7 +175,11 @@
 
 #define word0(x) (x.i[0])
 #define word1(x) 0
+#ifdef YES_ALIAS
 #define dword0(x) ((__ULong *)&x)[0]
+#else
+#define dword0(x) ((U*)&x)->L[0]
+#endif
 #define dword1(x) 0
 #else
 
--- newlib/libc/stdlib/strtod.c@@/NEWLIB-1.15.0	2006-07-05 17:18:30.000000000 +0100
+++ newlib/libc/stdlib/strtod.c	2007-08-17 19:11:58.711787000 +0100
@@ -386,7 +386,9 @@
 					if (!match(&s,"inity"))
 						++s;
 					dword0(rv) = 0x7ff00000;
+#ifndef _DOUBLE_IS_32BITS
 					dword1(rv) = 0;
+#endif /*!_DOUBLE_IS_32BITS*/
 					goto ret;
 					}
 				break;
@@ -398,12 +400,16 @@
 					 && hexnan(&s, &fpinan, bits)
 							== STRTOG_NaNbits) {
 						dword0(rv) = 0x7ff00000 | bits[1];
+#ifndef _DOUBLE_IS_32BITS
 						dword1(rv) = bits[0];
+#endif /*!_DOUBLE_IS_32BITS*/
 						}
 					else {
 #endif
 						dword0(rv) = NAN_WORD0;
+#ifndef _DOUBLE_IS_32BITS
 						dword1(rv) = NAN_WORD1;
+#endif /*!_DOUBLE_IS_32BITS*/
 #ifndef No_Hex_NaN
 						}
 #endif
@@ -627,8 +633,8 @@
 #ifndef _DOUBLE_IS_32BITS
 				else
 					dword1(rv) &= 0xffffffff << j;
-				}
 #endif /*!_DOUBLE_IS_32BITS*/
+				}
 #else
 			for(j = 0; e1 > 1; j++, e1 >>= 1)
 				if (e1 & 1)
@@ -1109,7 +1115,9 @@
 	if (inexact) {
 		if (!oldinexact) {
 			dword0(rv0) = Exp_1 + (70 << Exp_shift);
+#ifndef _DOUBLE_IS_32BITS
 			dword1(rv0) = 0;
+#endif /*!_DOUBLE_IS_32BITS*/
 			dval(rv0) += 1.;
 			}
 		}
@@ -1119,7 +1127,9 @@
 #ifdef Avoid_Underflow
 	if (scale) {
 		dword0(rv0) = Exp_1 - 2*P*Exp_msk1;
+#ifndef _DOUBLE_IS_32BITS
 		dword1(rv0) = 0;
+#endif /*!_DOUBLE_IS_32BITS*/
 		dval(rv) *= dval(rv0);
 #ifndef NO_ERRNO
 		/* try to avoid the bug of testing an 8087 register value */
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

static int deq(double val1, double val2)
{
  if (val1 != val2) {
    printf("got %f, expected %f\n", val1, val2);
  }
}  

static int ieq(int val1, int val2)
{
  if (val1 != val2) {
    printf("got %d, expected %d\n", val1, val2);
  }
}  

int main(void)
{
  /* overflow returns +/- HUGE_VAL */
  errno = 0;
  deq(strtod("2.3e99999999999999999999", NULL), HUGE_VAL);
  ieq(errno, ERANGE);
  errno = 0;
  deq(strtod("-1e99999999999999999999", NULL), -HUGE_VAL);
  ieq(errno, ERANGE); 

  return 0;
}

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