From de8a5b78105f9c7f60213a4d15a31a03f7485b6d Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Fri, 15 May 2009 16:15:57 +0000 Subject: 2009-05-15 Craig Howland * configure.in: Add configuration test for long double type existing and set flag _HAVE_LONG_DOUBLE if true. Fix INIT_ARRAY (.init_array) and _LDBL_EQ_DBL tests to not link so that will work with cross-compilers. * configure: Regenerated. * Makefile.in: Ditto. * newlib.hin: Add _HAVE_LONG_DOUBLE flag. * libc/include/math.h: Change non-builtin defines for HUGE_VAL, HUGE_VALF, and HUGE_VALL to be constant expressions. Add definitions for the non-builtin case for INFINITY and NAN. Gate HUGE_VALL and union __ldmath definitions with (new) _HAVE_LONG_DOUBLE. *libm/common/s_infconst.c: Change definitions to use values from float.h instead of non-so-portable integer forms. Mark as being deprecated (because now removed from math.h, are not used anywhere in Newlib, itself). --- newlib/libc/include/math.h | 54 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 14 deletions(-) (limited to 'newlib/libc/include/math.h') diff --git a/newlib/libc/include/math.h b/newlib/libc/include/math.h index 3efdb3675..f25539a2f 100644 --- a/newlib/libc/include/math.h +++ b/newlib/libc/include/math.h @@ -8,23 +8,28 @@ _BEGIN_STD_C +/* __dmath, __fmath, and __ldmath are only here for backwards compatibility + * in case any code used them. They are no longer used by Newlib, itself, + * other than legacy. */ union __dmath { - __ULong i[2]; double d; + __ULong i[2]; }; union __fmath { - __ULong i[1]; float f; + __ULong i[1]; }; +#if defined(_HAVE_LONG_DOUBLE) union __ldmath { + long double ld; __ULong i[4]; - _LONG_DOUBLE ld; }; +#endif /* Natural log of 2 */ #define _M_LOG2_E 0.693147180559945309417 @@ -57,24 +62,45 @@ union __ldmath #else /* !gcc >= 3.3 */ - /* No builtins. Use floating-point unions instead. Declare as an array - without bounds so no matter what small data support a port and/or - library has, the reference will be via the general method for accessing - globals. */ + /* No builtins. Use fixed defines instead. (All 3 HUGE plus the INFINITY + * and NAN macros are required to be constant expressions. Using a variable-- + * even a static const--does not meet this requirement, as it cannot be + * evaluated at translation time.) + * The infinities are done using numbers that are far in excess of + * something that would be expected to be encountered in a floating-point + * implementation. (A more certain way uses values from float.h, but that is + * avoided because system includes are not supposed to include each other.) + * This method might produce warnings from some compilers. (It does in + * newer GCCs, but not for ones that would hit this #else.) If this happens, + * please report details to the Newlib mailing list. */ #ifndef HUGE_VAL - extern __IMPORT const union __dmath __infinity[]; - #define HUGE_VAL (__infinity[0].d) + #define HUGE_VAL (1.0e999999999) #endif #ifndef HUGE_VALF - extern __IMPORT const union __fmath __infinityf[]; - #define HUGE_VALF (__infinityf[0].f) + #define HUGE_VALF (1.0e999999999F) + #endif + + #if !defined(HUGE_VALL) && defined(_HAVE_LONG_DOUBLE) + #define HUGE_VALL (1.0e999999999L) + #endif + + #if !defined(INFINITY) + #define INFINITY (HUGE_VALF) #endif - #ifndef HUGE_VALL - extern __IMPORT const union __ldmath __infinityld[]; - #define HUGE_VALL (__infinityld[0].ld) + #if !defined(NAN) + #if defined(__GNUC__) && defined(__cplusplus) + /* Exception: older g++ versions warn about the divide by 0 used in the + * normal case (even though older gccs do not). This trick suppresses the + * warning, but causes errors for plain gcc, so is only used in the one + * special case. */ + static const union { __ULong __i[1]; float __d; } __Nanf = {0x7FC00000}; + #define NAN (__Nanf.__d) + #else + #define NAN (0.0F/0.0F) + #endif #endif #endif /* !gcc >= 3.3 */ -- cgit v1.2.3