diff options
author | Mark H Weaver <mhw@netris.org> | 2013-08-06 17:37:34 -0400 |
---|---|---|
committer | Mark H Weaver <mhw@netris.org> | 2013-08-06 17:37:34 -0400 |
commit | d8d7c7bf5706ce7873257eb88f0a5cc01b541858 (patch) | |
tree | 406fa16e28f45c93b361d2f8ea80a62374dd180a /m4 | |
parent | e7f64971ed62a6b58f86b5d90a15b24733e36a8d (diff) | |
parent | 524140436fc03ee439d5c358c8c7a4c2c559684a (diff) |
Merge remote-tracking branch 'origin/stable-2.0'
Conflicts:
libguile/numbers.c
libguile/vm-i-scheme.c
Diffstat (limited to 'm4')
-rw-r--r-- | m4/copysign.m4 | 19 | ||||
-rw-r--r-- | m4/gnulib-cache.m4 | 4 | ||||
-rw-r--r-- | m4/gnulib-comp.m4 | 42 | ||||
-rw-r--r-- | m4/isfinite.m4 | 165 | ||||
-rw-r--r-- | m4/signbit.m4 | 365 |
5 files changed, 594 insertions, 1 deletions
diff --git a/m4/copysign.m4 b/m4/copysign.m4 new file mode 100644 index 000000000..382a6c6bb --- /dev/null +++ b/m4/copysign.m4 @@ -0,0 +1,19 @@ +# copysign.m4 serial 1 +dnl Copyright (C) 2011-2013 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_COPYSIGN], +[ + AC_REQUIRE([gl_MATH_H_DEFAULTS]) + + dnl Determine COPYSIGN_LIBM. + gl_MATHFUNC([copysign], [double], [(double, double)]) + if test $gl_cv_func_copysign_no_libm = no \ + && test $gl_cv_func_copysign_in_libm = no; then + HAVE_COPYSIGN=0 + COPYSIGN_LIBM= + fi + AC_SUBST([COPYSIGN_LIBM]) +]) diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4 index 81e464632..d41ec7b22 100644 --- a/m4/gnulib-cache.m4 +++ b/m4/gnulib-cache.m4 @@ -27,7 +27,7 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --local-dir=gnulib-local --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl=3 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files accept alignof alloca-opt announce-gen autobuild bind byteswap c-strcase canonicalize-lgpl ceil clock-time close connect dirfd duplocale environ extensions flock floor fpieee frexp fstat full-read full-write func gendocs getaddrinfo getlogin getpeername getsockname getsockopt git-version-gen gitlog-to-changelog gnu-web-doc-update gnupload havelib iconv_open-utf inet_ntop inet_pton isinf isnan ldexp lib-symbol-versions lib-symbol-visibility libunistring listen localcharset locale log1p maintainer-makefile malloc-gnu malloca nl_langinfo nproc open pipe-posix pipe2 poll putenv recv recvfrom regex rename select send sendto setenv setsockopt shutdown socket stat-time stdlib strftime striconveh string sys_stat time times trunc verify vsnprintf warnings wchar +# gnulib-tool --import --dir=. --local-dir=gnulib-local --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl=3 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files accept alignof alloca-opt announce-gen autobuild bind byteswap c-strcase canonicalize-lgpl ceil clock-time close connect copysign dirfd duplocale environ extensions flock floor fpieee frexp fstat full-read full-write func gendocs getaddrinfo getlogin getpeername getsockname getsockopt git-version-gen gitlog-to-changelog gnu-web-doc-update gnupload havelib iconv_open-utf inet_ntop inet_pton isfinite isinf isnan ldexp lib-symbol-versions lib-symbol-visibility libunistring listen localcharset locale log1p maintainer-makefile malloc-gnu malloca nl_langinfo nproc open pipe-posix pipe2 poll putenv recv recvfrom regex rename select send sendto setenv setsockopt shutdown socket stat-time stdlib strftime striconveh string sys_stat time times trunc verify vsnprintf warnings wchar # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([gnulib-local]) @@ -45,6 +45,7 @@ gl_MODULES([ clock-time close connect + copysign dirfd duplocale environ @@ -71,6 +72,7 @@ gl_MODULES([ iconv_open-utf inet_ntop inet_pton + isfinite isinf isnan largefile diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 55c003a58..8a1b80175 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -61,6 +61,7 @@ AC_DEFUN([gl_EARLY], # Code from module close: # Code from module configmake: # Code from module connect: + # Code from module copysign: # Code from module dirent: # Code from module dirfd: # Code from module dirname-lgpl: @@ -108,12 +109,15 @@ AC_DEFUN([gl_EARLY], # Code from module inet_ntop: # Code from module inet_pton: # Code from module inline: + # Code from module isfinite: # Code from module isinf: # Code from module isnan: # Code from module isnand: # Code from module isnand-nolibm: # Code from module isnanf: + # Code from module isnanf-nolibm: # Code from module isnanl: + # Code from module isnanl-nolibm: # Code from module langinfo: # Code from module largefile: AC_REQUIRE([AC_SYS_LARGEFILE]) @@ -172,6 +176,7 @@ AC_DEFUN([gl_EARLY], # Code from module setsockopt: # Code from module shutdown: # Code from module signal-h: + # Code from module signbit: # Code from module size_max: # Code from module snippet/_Noreturn: # Code from module snippet/arg-nonnull: @@ -292,6 +297,11 @@ AC_SUBST([LTALLOCA]) AC_LIBOBJ([connect]) fi gl_SYS_SOCKET_MODULE_INDICATOR([connect]) + gl_FUNC_COPYSIGN + if test $HAVE_COPYSIGN = 0; then + AC_LIBOBJ([copysign]) + fi + gl_MATH_MODULE_INDICATOR([copysign]) gl_DIRENT_H gl_FUNC_DIRFD if test $ac_cv_func_dirfd = no && test $gl_cv_func_dirfd_macro = no; then @@ -415,6 +425,11 @@ AC_SUBST([LTALLOCA]) fi gl_ARPA_INET_MODULE_INDICATOR([inet_pton]) gl_INLINE + gl_ISFINITE + if test $REPLACE_ISFINITE = 1; then + AC_LIBOBJ([isfinite]) + fi + gl_MATH_MODULE_INDICATOR([isfinite]) gl_ISINF if test $REPLACE_ISINF = 1; then AC_LIBOBJ([isinf]) @@ -445,6 +460,11 @@ AC_SUBST([LTALLOCA]) gl_PREREQ_ISNANF fi gl_MATH_MODULE_INDICATOR([isnanf]) + gl_FUNC_ISNANF_NO_LIBM + if test $gl_func_isnanf_no_libm != yes; then + AC_LIBOBJ([isnanf]) + gl_PREREQ_ISNANF + fi gl_FUNC_ISNANL m4_ifdef([gl_ISNAN], [ AC_REQUIRE([gl_ISNAN]) @@ -454,6 +474,11 @@ AC_SUBST([LTALLOCA]) gl_PREREQ_ISNANL fi gl_MATH_MODULE_INDICATOR([isnanl]) + gl_FUNC_ISNANL_NO_LIBM + if test $gl_func_isnanl_no_libm != yes; then + AC_LIBOBJ([isnanl]) + gl_PREREQ_ISNANL + fi gl_LANGINFO_H AC_REQUIRE([gl_LARGEFILE]) gl_FUNC_LDEXP @@ -656,6 +681,13 @@ AC_SUBST([LTALLOCA]) fi gl_SYS_SOCKET_MODULE_INDICATOR([shutdown]) gl_SIGNAL_H + gl_SIGNBIT + if test $REPLACE_SIGNBIT = 1; then + AC_LIBOBJ([signbitf]) + AC_LIBOBJ([signbitd]) + AC_LIBOBJ([signbitl]) + fi + gl_MATH_MODULE_INDICATOR([signbit]) gl_SIZE_MAX gl_FUNC_SNPRINTF gl_STDIO_MODULE_INDICATOR([snprintf]) @@ -935,6 +967,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/close.c lib/config.charset lib/connect.c + lib/copysign.c lib/dirent.in.h lib/dirfd.c lib/dirname-lgpl.c @@ -976,11 +1009,14 @@ AC_DEFUN([gl_FILE_LIST], [ lib/iconveh.h lib/inet_ntop.c lib/inet_pton.c + lib/isfinite.c lib/isinf.c lib/isnan.c lib/isnand-nolibm.h lib/isnand.c + lib/isnanf-nolibm.h lib/isnanf.c + lib/isnanl-nolibm.h lib/isnanl.c lib/itold.c lib/langinfo.in.h @@ -1053,6 +1089,9 @@ AC_DEFUN([gl_FILE_LIST], [ lib/setsockopt.c lib/shutdown.c lib/signal.in.h + lib/signbitd.c + lib/signbitf.c + lib/signbitl.c lib/size_max.h lib/snprintf.c lib/socket.c @@ -1125,6 +1164,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/close.m4 m4/codeset.m4 m4/configmake.m4 + m4/copysign.m4 m4/dirent_h.m4 m4/dirfd.m4 m4/dirname.m4 @@ -1163,6 +1203,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/inline.m4 m4/intmax_t.m4 m4/inttypes_h.m4 + m4/isfinite.m4 m4/isinf.m4 m4/isnan.m4 m4/isnand.m4 @@ -1228,6 +1269,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/servent.m4 m4/setenv.m4 m4/signal_h.m4 + m4/signbit.m4 m4/size_max.m4 m4/snprintf.m4 m4/socketlib.m4 diff --git a/m4/isfinite.m4 b/m4/isfinite.m4 new file mode 100644 index 000000000..b54b403b8 --- /dev/null +++ b/m4/isfinite.m4 @@ -0,0 +1,165 @@ +# isfinite.m4 serial 13 +dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_ISFINITE], +[ + AC_REQUIRE([gl_MATH_H_DEFAULTS]) + dnl Persuade glibc <math.h> to declare isfinite. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_CHECK_DECLS([isfinite], , , [[#include <math.h>]]) + if test "$ac_cv_have_decl_isfinite" = yes; then + gl_CHECK_MATH_LIB([ISFINITE_LIBM], + [x = isfinite (x) + isfinite ((float) x);]) + if test "$ISFINITE_LIBM" != missing; then + dnl Test whether isfinite() on 'long double' works. + gl_ISFINITEL_WORKS + case "$gl_cv_func_isfinitel_works" in + *yes) ;; + *) ISFINITE_LIBM=missing;; + esac + dnl Also, isfinite() on 'double' does not work on Linux/ia64 (because of + dnl signalling NaNs). But this does not have to be tested, since + dnl isfinite(long double) also does not work in this situation. + fi + fi + if test "$ac_cv_have_decl_isfinite" != yes || + test "$ISFINITE_LIBM" = missing; then + REPLACE_ISFINITE=1 + dnl No libraries are needed to link lib/isfinite.c. + ISFINITE_LIBM= + fi + AC_SUBST([ISFINITE_LIBM]) +]) + +dnl Test whether isfinite() on 'long double' recognizes all numbers which are +dnl neither finite nor infinite. This test fails e.g. on i686, x86_64, ia64, +dnl because of +dnl - pseudo-denormals on x86_64, +dnl - pseudo-zeroes, unnormalized numbers, and pseudo-denormals on i686, +dnl - pseudo-NaN, pseudo-Infinity, pseudo-zeroes, unnormalized numbers, and +dnl pseudo-denormals on ia64. +AC_DEFUN([gl_ISFINITEL_WORKS], +[ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gl_BIGENDIAN]) + AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether isfinite(long double) works], [gl_cv_func_isfinitel_works], + [ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include <float.h> +#include <limits.h> +#include <math.h> +#define NWORDS \ + ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) +typedef union { unsigned int word[NWORDS]; long double value; } + memory_long_double; +/* On Irix 6.5, gcc 3.4.3 can't compute compile-time NaN, and needs the + runtime type conversion. */ +#ifdef __sgi +static long double NaNl () +{ + double zero = 0.0; + return zero / zero; +} +#else +# define NaNl() (0.0L / 0.0L) +#endif +int main () +{ + int result = 0; + + { + memory_long_double m; + unsigned int i; + + /* The isfinite macro should be immune against changes in the sign bit and + in the mantissa bits. The xor operation twiddles a bit that can only be + a sign bit or a mantissa bit (since the exponent never extends to + bit 31). */ + m.value = NaNl (); + m.word[NWORDS / 2] ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1); + for (i = 0; i < NWORDS; i++) + m.word[i] |= 1; + if (isfinite (m.value)) + result |= 1; + } + +#if ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE +/* Representation of an 80-bit 'long double' as an initializer for a sequence + of 'unsigned int' words. */ +# ifdef WORDS_BIGENDIAN +# define LDBL80_WORDS(exponent,manthi,mantlo) \ + { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \ + ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \ + (unsigned int) (mantlo) << 16 \ + } +# else +# define LDBL80_WORDS(exponent,manthi,mantlo) \ + { mantlo, manthi, exponent } +# endif + { /* Quiet NaN. */ + static memory_long_double x = + { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) }; + if (isfinite (x.value)) + result |= 2; + } + { + /* Signalling NaN. */ + static memory_long_double x = + { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) }; + if (isfinite (x.value)) + result |= 2; + } + /* The isfinite macro should recognize Pseudo-NaNs, Pseudo-Infinities, + Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in + Intel IA-64 Architecture Software Developer's Manual, Volume 1: + Application Architecture. + Table 5-2 "Floating-Point Register Encodings" + Figure 5-6 "Memory to Floating-Point Register Data Translation" + */ + { /* Pseudo-NaN. */ + static memory_long_double x = + { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) }; + if (isfinite (x.value)) + result |= 4; + } + { /* Pseudo-Infinity. */ + static memory_long_double x = + { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) }; + if (isfinite (x.value)) + result |= 8; + } + { /* Pseudo-Zero. */ + static memory_long_double x = + { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) }; + if (isfinite (x.value)) + result |= 16; + } + { /* Unnormalized number. */ + static memory_long_double x = + { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) }; + if (isfinite (x.value)) + result |= 32; + } + { /* Pseudo-Denormal. */ + static memory_long_double x = + { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) }; + if (isfinite (x.value)) + result |= 64; + } +#endif + + return result; +}]])], [gl_cv_func_isfinitel_works=yes], [gl_cv_func_isfinitel_works=no], + [case "$host_cpu" in + # Guess no on ia64, x86_64, i386. + ia64 | x86_64 | i*86) gl_cv_func_isfinitel_works="guessing no";; + *) gl_cv_func_isfinitel_works="guessing yes";; + esac + ]) + ]) +]) diff --git a/m4/signbit.m4 b/m4/signbit.m4 new file mode 100644 index 000000000..d58caaf05 --- /dev/null +++ b/m4/signbit.m4 @@ -0,0 +1,365 @@ +# signbit.m4 serial 13 +dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_SIGNBIT], +[ + AC_REQUIRE([gl_MATH_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([for signbit macro], [gl_cv_func_signbit], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include <math.h> +/* If signbit is defined as a function, don't use it, since calling it for + 'float' or 'long double' arguments would involve conversions. + If signbit is not declared at all but exists as a library function, don't + use it, since the prototype may not match. + If signbit is not declared at all but exists as a compiler built-in, don't + use it, since it's preferable to use __builtin_signbit* (no warnings, + no conversions). */ +#ifndef signbit +# error "signbit should be a macro" +#endif +#include <string.h> +]gl_SIGNBIT_TEST_PROGRAM +])], + [gl_cv_func_signbit=yes], + [gl_cv_func_signbit=no], + [case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_signbit="guessing yes" ;; + # If we don't know, assume the worst. + *) gl_cv_func_signbit="guessing no" ;; + esac + ]) + ]) + dnl GCC 4.0 and newer provides three built-ins for signbit. + dnl They can be used without warnings, also in C++, regardless of <math.h>. + dnl But they may expand to calls to functions, which may or may not be in + dnl libc. + AC_CACHE_CHECK([for signbit compiler built-ins], [gl_cv_func_signbit_gcc], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#if __GNUC__ >= 4 +# define signbit(x) \ + (sizeof (x) == sizeof (long double) ? __builtin_signbitl (x) : \ + sizeof (x) == sizeof (double) ? __builtin_signbit (x) : \ + __builtin_signbitf (x)) +#else +# error "signbit should be three compiler built-ins" +#endif +#include <string.h> +]gl_SIGNBIT_TEST_PROGRAM +])], + [gl_cv_func_signbit_gcc=yes], + [gl_cv_func_signbit_gcc=no], + [case "$host_os" in + # Guess yes on glibc systems. + *-gnu*) gl_cv_func_signbit_gcc="guessing yes" ;; + # If we don't know, assume the worst. + *) gl_cv_func_signbit_gcc="guessing no" ;; + esac + ]) + ]) + dnl Use the compiler built-ins whenever possible, because they are more + dnl efficient than the system library functions (if they exist). + case "$gl_cv_func_signbit_gcc" in + *yes) + REPLACE_SIGNBIT_USING_GCC=1 + ;; + *) + case "$gl_cv_func_signbit" in + *yes) ;; + *) + dnl REPLACE_SIGNBIT=1 makes sure the signbit[fdl] functions get built. + REPLACE_SIGNBIT=1 + gl_FLOAT_SIGN_LOCATION + gl_DOUBLE_SIGN_LOCATION + gl_LONG_DOUBLE_SIGN_LOCATION + if test "$gl_cv_cc_float_signbit" = unknown; then + dnl Test whether copysignf() is declared. + AC_CHECK_DECLS([copysignf], , , [[#include <math.h>]]) + if test "$ac_cv_have_decl_copysignf" = yes; then + dnl Test whether copysignf() can be used without libm. + AC_CACHE_CHECK([whether copysignf can be used without linking with libm], + [gl_cv_func_copysignf_no_libm], + [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include <math.h> + float x, y;]], + [[return copysignf (x, y) < 0;]])], + [gl_cv_func_copysignf_no_libm=yes], + [gl_cv_func_copysignf_no_libm=no]) + ]) + if test $gl_cv_func_copysignf_no_libm = yes; then + AC_DEFINE([HAVE_COPYSIGNF_IN_LIBC], [1], + [Define if the copysignf function is declared in <math.h> and available in libc.]) + fi + fi + fi + if test "$gl_cv_cc_double_signbit" = unknown; then + dnl Test whether copysign() is declared. + AC_CHECK_DECLS([copysign], , , [[#include <math.h>]]) + if test "$ac_cv_have_decl_copysign" = yes; then + dnl Test whether copysign() can be used without libm. + AC_CACHE_CHECK([whether copysign can be used without linking with libm], + [gl_cv_func_copysign_no_libm], + [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include <math.h> + double x, y;]], + [[return copysign (x, y) < 0;]])], + [gl_cv_func_copysign_no_libm=yes], + [gl_cv_func_copysign_no_libm=no]) + ]) + if test $gl_cv_func_copysign_no_libm = yes; then + AC_DEFINE([HAVE_COPYSIGN_IN_LIBC], [1], + [Define if the copysign function is declared in <math.h> and available in libc.]) + fi + fi + fi + if test "$gl_cv_cc_long_double_signbit" = unknown; then + dnl Test whether copysignl() is declared. + AC_CHECK_DECLS([copysignl], , , [[#include <math.h>]]) + if test "$ac_cv_have_decl_copysignl" = yes; then + dnl Test whether copysignl() can be used without libm. + AC_CACHE_CHECK([whether copysignl can be used without linking with libm], + [gl_cv_func_copysignl_no_libm], + [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include <math.h> + long double x, y;]], + [[return copysignl (x, y) < 0;]])], + [gl_cv_func_copysignl_no_libm=yes], + [gl_cv_func_copysignl_no_libm=no]) + ]) + if test $gl_cv_func_copysignl_no_libm = yes; then + AC_DEFINE([HAVE_COPYSIGNL_IN_LIBC], [1], + [Define if the copysignl function is declared in <math.h> and available in libc.]) + fi + fi + fi + ;; + esac + ;; + esac +]) + +AC_DEFUN([gl_SIGNBIT_TEST_PROGRAM], [[ +/* Global variables. + Needed because GCC 4 constant-folds __builtin_signbitl (literal) + but cannot constant-fold __builtin_signbitl (variable). */ +float vf; +double vd; +long double vl; +int main () +{ +/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0. + So we use -p0f and -p0d instead. */ +float p0f = 0.0f; +float m0f = -p0f; +double p0d = 0.0; +double m0d = -p0d; +/* On HP-UX 10.20, negating 0.0L does not yield -0.0L. + So we use another constant expression instead. + But that expression does not work on other platforms, such as when + cross-compiling to PowerPC on Mac OS X 10.5. */ +long double p0l = 0.0L; +#if defined __hpux || defined __sgi +long double m0l = -LDBL_MIN * LDBL_MIN; +#else +long double m0l = -p0l; +#endif + int result = 0; + if (signbit (vf)) /* link check */ + vf++; + { + float plus_inf = 1.0f / p0f; + float minus_inf = -1.0f / p0f; + if (!(!signbit (255.0f) + && signbit (-255.0f) + && !signbit (p0f) + && (memcmp (&m0f, &p0f, sizeof (float)) == 0 || signbit (m0f)) + && !signbit (plus_inf) + && signbit (minus_inf))) + result |= 1; + } + if (signbit (vd)) /* link check */ + vd++; + { + double plus_inf = 1.0 / p0d; + double minus_inf = -1.0 / p0d; + if (!(!signbit (255.0) + && signbit (-255.0) + && !signbit (p0d) + && (memcmp (&m0d, &p0d, sizeof (double)) == 0 || signbit (m0d)) + && !signbit (plus_inf) + && signbit (minus_inf))) + result |= 2; + } + if (signbit (vl)) /* link check */ + vl++; + { + long double plus_inf = 1.0L / p0l; + long double minus_inf = -1.0L / p0l; + if (signbit (255.0L)) + result |= 4; + if (!signbit (-255.0L)) + result |= 4; + if (signbit (p0l)) + result |= 8; + if (!(memcmp (&m0l, &p0l, sizeof (long double)) == 0 || signbit (m0l))) + result |= 16; + if (signbit (plus_inf)) + result |= 32; + if (!signbit (minus_inf)) + result |= 64; + } + return result; +} +]]) + +AC_DEFUN([gl_FLOAT_SIGN_LOCATION], +[ + gl_FLOATTYPE_SIGN_LOCATION([float], [gl_cv_cc_float_signbit], [f], [FLT]) +]) + +AC_DEFUN([gl_DOUBLE_SIGN_LOCATION], +[ + gl_FLOATTYPE_SIGN_LOCATION([double], [gl_cv_cc_double_signbit], [], [DBL]) +]) + +AC_DEFUN([gl_LONG_DOUBLE_SIGN_LOCATION], +[ + gl_FLOATTYPE_SIGN_LOCATION([long double], [gl_cv_cc_long_double_signbit], [L], [LDBL]) +]) + +AC_DEFUN([gl_FLOATTYPE_SIGN_LOCATION], +[ + AC_CACHE_CHECK([where to find the sign bit in a '$1'], + [$2], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include <stddef.h> +#include <stdio.h> +#define NWORDS \ + ((sizeof ($1) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) +typedef union { $1 value; unsigned int word[NWORDS]; } + memory_float; +static memory_float plus = { 1.0$3 }; +static memory_float minus = { -1.0$3 }; +int main () +{ + size_t j, k, i; + unsigned int m; + FILE *fp = fopen ("conftest.out", "w"); + if (fp == NULL) + return 1; + /* Find the different bit. */ + k = 0; m = 0; + for (j = 0; j < NWORDS; j++) + { + unsigned int x = plus.word[j] ^ minus.word[j]; + if ((x & (x - 1)) || (x && m)) + { + /* More than one bit difference. */ + fprintf (fp, "unknown"); + return 2; + } + if (x) + { + k = j; + m = x; + } + } + if (m == 0) + { + /* No difference. */ + fprintf (fp, "unknown"); + return 3; + } + /* Now m = plus.word[k] ^ ~minus.word[k]. */ + if (plus.word[k] & ~minus.word[k]) + { + /* Oh? The sign bit is set in the positive and cleared in the negative + numbers? */ + fprintf (fp, "unknown"); + return 4; + } + for (i = 0; ; i++) + if ((m >> i) & 1) + break; + fprintf (fp, "word %d bit %d", (int) k, (int) i); + if (fclose (fp) != 0) + return 5; + return 0; +} + ]])], + [$2=`cat conftest.out`], + [$2="unknown"], + [ + dnl When cross-compiling, we don't know. It depends on the + dnl ABI and compiler version. There are too many cases. + $2="unknown" + ]) + rm -f conftest.out + ]) + case "$]$2[" in + word*bit*) + word=`echo "$]$2[" | sed -e 's/word //' -e 's/ bit.*//'` + bit=`echo "$]$2[" | sed -e 's/word.*bit //'` + AC_DEFINE_UNQUOTED([$4][_SIGNBIT_WORD], [$word], + [Define as the word index where to find the sign of '$1'.]) + AC_DEFINE_UNQUOTED([$4][_SIGNBIT_BIT], [$bit], + [Define as the bit index in the word where to find the sign of '$1'.]) + ;; + esac +]) + +# Expands to code that defines a function signbitf(float). +# It extracts the sign bit of a non-NaN value. +AC_DEFUN([gl_FLOAT_SIGNBIT_CODE], +[ + gl_FLOATTYPE_SIGNBIT_CODE([float], [f], [f]) +]) + +# Expands to code that defines a function signbitd(double). +# It extracts the sign bit of a non-NaN value. +AC_DEFUN([gl_DOUBLE_SIGNBIT_CODE], +[ + gl_FLOATTYPE_SIGNBIT_CODE([double], [d], []) +]) + +# Expands to code that defines a function signbitl(long double). +# It extracts the sign bit of a non-NaN value. +AC_DEFUN([gl_LONG_DOUBLE_SIGNBIT_CODE], +[ + gl_FLOATTYPE_SIGNBIT_CODE([long double], [l], [L]) +]) + +AC_DEFUN([gl_FLOATTYPE_SIGNBIT_CODE], +[[ +static int +signbit$2 ($1 value) +{ + typedef union { $1 f; unsigned char b[sizeof ($1)]; } float_union; + static float_union plus_one = { 1.0$3 }; /* unused bits are zero here */ + static float_union minus_one = { -1.0$3 }; /* unused bits are zero here */ + /* Compute the sign bit mask as the XOR of plus_one and minus_one. */ + float_union u; + unsigned int i; + u.f = value; + for (i = 0; i < sizeof ($1); i++) + if (u.b[i] & (plus_one.b[i] ^ minus_one.b[i])) + return 1; + return 0; +} +]]) |