From de8a5b78105f9c7f60213a4d15a31a03f7485b6d Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Fri, 15 May 2009 16:15:57 +0000 Subject: [PATCH] 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/ChangeLog | 18 ++++++++ newlib/Makefile.in | 2 + newlib/configure | 74 +++++++++++++++++++++++++++++---- newlib/configure.in | 44 +++++++++++++++++--- newlib/libc/include/math.h | 54 +++++++++++++++++------- newlib/libm/common/s_infconst.c | 39 +++++------------ newlib/newlib.hin | 3 ++ 7 files changed, 179 insertions(+), 55 deletions(-) diff --git a/newlib/ChangeLog b/newlib/ChangeLog index df9847083..bc4405758 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,21 @@ +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). + 2009-05-15 Corinna Vinschen * libc/string/local.h: New file. diff --git a/newlib/Makefile.in b/newlib/Makefile.in index f2a37cd01..7274398dd 100644 --- a/newlib/Makefile.in +++ b/newlib/Makefile.in @@ -171,6 +171,8 @@ FGREP = @FGREP@ GREP = @GREP@ HAVE_DOC_FALSE = @HAVE_DOC_FALSE@ HAVE_DOC_TRUE = @HAVE_DOC_TRUE@ +HAVE_LONG_DOUBLE_FALSE = @HAVE_LONG_DOUBLE_FALSE@ +HAVE_LONG_DOUBLE_TRUE = @HAVE_LONG_DOUBLE_TRUE@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ diff --git a/newlib/configure b/newlib/configure index 1d9108d88..baf10f668 100755 --- a/newlib/configure +++ b/newlib/configure @@ -462,7 +462,7 @@ ac_subdirs_all="$ac_subdirs_all libc" ac_subdirs_all="$ac_subdirs_all libm" ac_subdirs_all="$ac_subdirs_all doc" ac_subdirs_all="$ac_subdirs_all iconvdata" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS MAY_SUPPLY_SYSCALLS_TRUE MAY_SUPPLY_SYSCALLS_FALSE newlib_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB READELF ac_ct_READELF MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CCAS CCASFLAGS NEWLIB_CFLAGS LDFLAGS ELIX_LEVEL_0_TRUE ELIX_LEVEL_0_FALSE ELIX_LEVEL_1_TRUE ELIX_LEVEL_1_FALSE ELIX_LEVEL_2_TRUE ELIX_LEVEL_2_FALSE ELIX_LEVEL_3_TRUE ELIX_LEVEL_3_FALSE ELIX_LEVEL_4_TRUE ELIX_LEVEL_4_FALSE USE_LIBTOOL_TRUE USE_LIBTOOL_FALSE OBJEXT oext aext lpfx libm_machine_dir machine_dir sys_dir SED DLLTOOL ac_ct_DLLTOOL OBJDUMP ac_ct_OBJDUMP LIBTOOL CFLAGS CPPFLAGS ac_ct_CC EXEEXT EGREP FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 CPP NEWLIB_HW_FP_TRUE NEWLIB_HW_FP_FALSE CC_FOR_NEWLIB subdirs HAVE_DOC_TRUE HAVE_DOC_FALSE EXTRA_DIRS CRT0 CRT0_DIR CRT1 CRT1_DIR LIBM_MACHINE_OBJECTLIST MACHINE_OBJECTLIST SYS_OBJECTLIST SYS_MACH_OBJECTLIST POSIX_OBJECTLIST SIGNAL_OBJECTLIST SYSCALL_OBJECTLIST UNIX_OBJECTLIST STDIO64_OBJECTLIST CC_FOR_BUILD libc_cv_initfinit_array LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS MAY_SUPPLY_SYSCALLS_TRUE MAY_SUPPLY_SYSCALLS_FALSE newlib_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB READELF ac_ct_READELF MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CCAS CCASFLAGS NEWLIB_CFLAGS LDFLAGS ELIX_LEVEL_0_TRUE ELIX_LEVEL_0_FALSE ELIX_LEVEL_1_TRUE ELIX_LEVEL_1_FALSE ELIX_LEVEL_2_TRUE ELIX_LEVEL_2_FALSE ELIX_LEVEL_3_TRUE ELIX_LEVEL_3_FALSE ELIX_LEVEL_4_TRUE ELIX_LEVEL_4_FALSE USE_LIBTOOL_TRUE USE_LIBTOOL_FALSE OBJEXT oext aext lpfx libm_machine_dir machine_dir sys_dir SED DLLTOOL ac_ct_DLLTOOL OBJDUMP ac_ct_OBJDUMP LIBTOOL CFLAGS CPPFLAGS ac_ct_CC EXEEXT EGREP FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 CPP NEWLIB_HW_FP_TRUE NEWLIB_HW_FP_FALSE CC_FOR_NEWLIB subdirs HAVE_DOC_TRUE HAVE_DOC_FALSE EXTRA_DIRS CRT0 CRT0_DIR CRT1 CRT1_DIR LIBM_MACHINE_OBJECTLIST MACHINE_OBJECTLIST SYS_OBJECTLIST SYS_MACH_OBJECTLIST POSIX_OBJECTLIST SIGNAL_OBJECTLIST SYSCALL_OBJECTLIST UNIX_OBJECTLIST STDIO64_OBJECTLIST CC_FOR_BUILD libc_cv_initfinit_array HAVE_LONG_DOUBLE_TRUE HAVE_LONG_DOUBLE_FALSE LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -11874,8 +11874,8 @@ int __start (void) { return 0; } int foo (void) { return 1; } int (*fp) (void) __attribute__ ((section (".init_array"))) = foo; EOF -if { ac_try='${CC} $CFLAGS $CPPFLAGS $LDFLAGS -o conftest conftest.c - -static -nostartfiles -nostdlib 1>&5' +if { ac_try='${CC} $CFLAGS $CPPFLAGS -c -o conftest conftest.c + 1>&5' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -11902,8 +11902,59 @@ _ACEOF fi -echo "$as_me:$LINENO: checking long double equals double" >&5 -echo $ECHO_N "checking long double equals double... $ECHO_C" >&6 +echo "$as_me:$LINENO: checking whether long double type exists" >&5 +echo $ECHO_N "checking whether long double type exists... $ECHO_C" >&6 +if test "${acnewlib_cv_type_long_double+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.c < +#if defined(LDBL_MANT_DIG) + #define _HAVE_LONG_DOUBLE + #else + #error "LDBL != DBL" +#endif +long double test() { +long double ld = 0.0L; +return ld; +} +EOF +if { ac_try='${CC} $CFLAGS $CPPFLAGS -c -o conftest.o conftest.c + 1>&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } +then + acnewlib_cv_type_long_double=yes; +else + acnewlib_cv_type_long_double=no; +fi +rm -f conftest* +fi +echo "$as_me:$LINENO: result: $acnewlib_cv_type_long_double" >&5 +echo "${ECHO_T}$acnewlib_cv_type_long_double" >&6 +if test $acnewlib_cv_type_long_double = yes; then + cat >>confdefs.h <<_ACEOF +#define _HAVE_LONG_DOUBLE 1 +_ACEOF + +fi + + +if test x"$acnewlib_cv_type_long_double" = x"yes"; then + HAVE_LONG_DOUBLE_TRUE= + HAVE_LONG_DOUBLE_FALSE='#' +else + HAVE_LONG_DOUBLE_TRUE='#' + HAVE_LONG_DOUBLE_FALSE= +fi + + +echo "$as_me:$LINENO: checking whether long double equals double" >&5 +echo $ECHO_N "checking whether long double equals double... $ECHO_C" >&6 if test "${newlib_ldbl_eq_dbl+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -11916,8 +11967,8 @@ else #error "LDBL != DBL" #endif EOF -if { ac_try='${CC} $CFLAGS $CPPFLAGS $LDFLAGS -o conftest conftest.c - -static -nostartfiles -nostdlib 1>&5' +if { ac_try='${CC} $CFLAGS $CPPFLAGS -c -o conftest.o conftest.c + 1>&5' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -12123,6 +12174,13 @@ echo "$as_me: error: conditional \"HAVE_DOC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi +if test -z "${HAVE_LONG_DOUBLE_TRUE}" && test -z "${HAVE_LONG_DOUBLE_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"HAVE_LONG_DOUBLE\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"HAVE_LONG_DOUBLE\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files @@ -13050,6 +13108,8 @@ s,@UNIX_OBJECTLIST@,$UNIX_OBJECTLIST,;t t s,@STDIO64_OBJECTLIST@,$STDIO64_OBJECTLIST,;t t s,@CC_FOR_BUILD@,$CC_FOR_BUILD,;t t s,@libc_cv_initfinit_array@,$libc_cv_initfinit_array,;t t +s,@HAVE_LONG_DOUBLE_TRUE@,$HAVE_LONG_DOUBLE_TRUE,;t t +s,@HAVE_LONG_DOUBLE_FALSE@,$HAVE_LONG_DOUBLE_FALSE,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF diff --git a/newlib/configure.in b/newlib/configure.in index 9ff520100..86b5397c9 100644 --- a/newlib/configure.in +++ b/newlib/configure.in @@ -378,8 +378,8 @@ int __start (void) { return 0; } int foo (void) { return 1; } int (*fp) (void) __attribute__ ((section (".init_array"))) = foo; EOF -if AC_TRY_COMMAND([${CC} $CFLAGS $CPPFLAGS $LDFLAGS -o conftest conftest.c - -static -nostartfiles -nostdlib 1>&AS_MESSAGE_LOG_FD]) +if AC_TRY_COMMAND([${CC} $CFLAGS $CPPFLAGS -c -o conftest conftest.c + 1>&AS_MESSAGE_LOG_FD]) then if ${READELF} -S conftest | grep -e INIT_ARRAY > /dev/null; then libc_cv_initfinit_array=yes @@ -395,7 +395,41 @@ if test $libc_cv_initfinit_array = yes; then AC_DEFINE_UNQUOTED(HAVE_INITFINI_ARRAY) fi -AC_CACHE_CHECK(long double equals double, +dnl Autoconf 2.59 doesn't support the AC_TYPE_LONG_DOUBLE macro. Instead of: +dnl AC_TYPE_LONG_DOUBLE +dnl AM_CONDITIONAL(HAVE_LONG_DOUBLE, test x"$ac_cv_type_long_double" = x"yes") +dnl we specify our own long double test. +dnl Additionally, ac_cv_objext is broken so that AC_COMPILE_IFELSE cannot be +dnl used, so use AC_TRY_COMMAND instead. +AC_CACHE_CHECK(whether long double type exists, + acnewlib_cv_type_long_double, [dnl +cat > conftest.c < +#if defined(LDBL_MANT_DIG) + #define _HAVE_LONG_DOUBLE + #else + #error "LDBL != DBL" +#endif +long double test() { +long double ld = 0.0L; +return ld; +} +EOF +if AC_TRY_COMMAND([${CC} $CFLAGS $CPPFLAGS -c -o conftest.o conftest.c + 1>&AS_MESSAGE_LOG_FD]) +then + acnewlib_cv_type_long_double=yes; +else + acnewlib_cv_type_long_double=no; +fi +rm -f conftest*]) +if test $acnewlib_cv_type_long_double = yes; then + AC_DEFINE_UNQUOTED(_HAVE_LONG_DOUBLE) +fi +AM_CONDITIONAL(HAVE_LONG_DOUBLE, test x"$acnewlib_cv_type_long_double" = x"yes") + +AC_CACHE_CHECK(whether long double equals double, newlib_ldbl_eq_dbl, [dnl cat > conftest.c < @@ -406,8 +440,8 @@ cat > conftest.c <&AS_MESSAGE_LOG_FD]) +if AC_TRY_COMMAND([${CC} $CFLAGS $CPPFLAGS -c -o conftest.o conftest.c + 1>&AS_MESSAGE_LOG_FD]) then newlib_ldbl_eq_dbl=yes; else 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 - #ifndef HUGE_VALL - extern __IMPORT const union __ldmath __infinityld[]; - #define HUGE_VALL (__infinityld[0].ld) + #if !defined(HUGE_VALL) && defined(_HAVE_LONG_DOUBLE) + #define HUGE_VALL (1.0e999999999L) + #endif + + #if !defined(INFINITY) + #define INFINITY (HUGE_VALF) + #endif + + #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 */ diff --git a/newlib/libm/common/s_infconst.c b/newlib/libm/common/s_infconst.c index 9447b97cc..47a9dca19 100644 --- a/newlib/libm/common/s_infconst.c +++ b/newlib/libm/common/s_infconst.c @@ -3,38 +3,19 @@ */ #include -#include "fdlibm.h" +#include +/* These should never actually be used any longer, as their use in math.h was + * removed, but they are kept here in case a user was pointing to them. + * FIXME: deprecate these identifiers and then delete them. */ + /* Float version of infinity. */ -const union __fmath __infinityf[1] = {{{0x7f800000}}}; +const union __fmath __infinityf[1] = { { FLT_MAX+FLT_MAX } }; /* Double version of infinity. */ -#ifndef _DOUBLE_IS_32BITS - #ifdef __IEEE_BIG_ENDIAN - const union __dmath __infinity[1] = {{{0x7ff00000, 0}}}; - #else - const union __dmath __infinity[1] = {{{0, 0x7ff00000}}}; - #endif -#else /* defined (_DOUBLE_IS_32BITS) */ - const union __dmath __infinity[1] = {{{0x7f800000, 0}}}; -#endif /* defined (_DOUBLE_IS_32BITS) */ +const union __dmath __infinity[1] = { { DBL_MAX+DBL_MAX } }; /* Long double version of infinity. */ -#ifdef __IEEE_BIG_ENDIAN - #if LDBL_MANT_DIG == 24 - const union __ldmath __infinityld[1] = {{{0x7f800000, 0, 0, 0}}}; - #elif LDBL_MANT_DIG == 53 - const union __ldmath __infinityld[1] = {{{0x7ff00000, 0, 0, 0}}}; - #else - const union __ldmath __infinityld[1] = {{{0x7fff0000, 0, 0, 0}}}; - #endif /* LDBL_MANT_DIG size */ -#else /* __IEEE_LITTLE_ENDIAN */ - #if LDBL_MANT_DIG == 24 - const union __ldmath __infinityld[1] = {{{0x7f800000, 0, 0, 0}}}; - #elif LDBL_MANT_DIG == 53 - const union __ldmath __infinityld[1] = {{{0, 0x7ff00000, 0, 0}}}; - #else - const union __ldmath __infinityld[1] = {{{0, 0x80000000, 0x00007fff, 0}}}; - #endif /* LDBL_MANT_DIG size */ -#endif /* __IEEE_LITTLE_ENDIAN */ - +#if defined(_HAVE_LONG_DOUBLE) +const union __ldmath __infinityld[1] = { { LDBL_MAX+LDBL_MAX } }; +#endif diff --git a/newlib/newlib.hin b/newlib/newlib.hin index f7afdebb7..1db939a2c 100644 --- a/newlib/newlib.hin +++ b/newlib/newlib.hin @@ -46,6 +46,9 @@ functions. */ #undef _ATEXIT_DYNAMIC_ALLOC +/* True if long double supported. */ +#undef _HAVE_LONG_DOUBLE + /* True if long double supported and it is equal to double. */ #undef _LDBL_EQ_DBL