[RFC/PATCH] Enable IEEE_Arith when double is 32 bits for strtod
Jeff Johnston
jjohnstn@redhat.com
Fri Aug 31 22:36:00 GMT 2007
Patch applied. Thanks.
-- Jeff J.
Antony KING wrote:
> 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;
> }
More information about the Newlib
mailing list