This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GNU Guile".
http://git.savannah.gnu.org/cgit/guile.git/commit/?id=524140436fc03ee439d5c358c8c7a4c2c559684a The branch, stable-2.0 has been updated via 524140436fc03ee439d5c358c8c7a4c2c559684a (commit) from ca7b6f6869072a79175c2d2db1b63f706bdf9b25 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 524140436fc03ee439d5c358c8c7a4c2c559684a Author: Mark H Weaver <[email protected]> Date: Tue Aug 6 17:16:04 2013 -0400 Add files from 'copysign' and 'isfinite' Gnulib modules. * lib/copysign.c: * lib/isfinite.c: * lib/isnanf-nolibm.h: * lib/isnanl-nolibm.h: * lib/signbitd.c: * lib/signbitf.c: * lib/signbitl.c: * m4/copysign.m4: * m4/isfinite.m4: * m4/signbit.m4: New files. ----------------------------------------------------------------------- Summary of changes: lib/{mbtowc.c => copysign.c} | 16 +- lib/isfinite.c | 51 ++++ lib/{isnand-nolibm.h => isnanf-nolibm.h} | 25 ++- lib/{isnand-nolibm.h => isnanl-nolibm.h} | 20 +- lib/signbitd.c | 64 ++++++ lib/signbitf.c | 64 ++++++ lib/signbitl.c | 64 ++++++ m4/copysign.m4 | 19 ++ m4/{isinf.m4 => isfinite.m4} | 104 ++++----- m4/signbit.m4 | 365 ++++++++++++++++++++++++++++++ 10 files changed, 708 insertions(+), 84 deletions(-) copy lib/{mbtowc.c => copysign.c} (78%) create mode 100644 lib/isfinite.c copy lib/{isnand-nolibm.h => isnanf-nolibm.h} (62%) copy lib/{isnand-nolibm.h => isnanl-nolibm.h} (74%) create mode 100644 lib/signbitd.c create mode 100644 lib/signbitf.c create mode 100644 lib/signbitl.c create mode 100644 m4/copysign.m4 copy m4/{isinf.m4 => isfinite.m4} (61%) create mode 100644 m4/signbit.m4 diff --git a/lib/mbtowc.c b/lib/copysign.c similarity index 78% copy from lib/mbtowc.c copy to lib/copysign.c index 7777f0a..61efeb8 100644 --- a/lib/mbtowc.c +++ b/lib/copysign.c @@ -1,6 +1,5 @@ -/* Convert multibyte character to wide character. +/* Copy sign into another 'double' number. Copyright (C) 2011-2013 Free Software Foundation, Inc. - Written by Bruno Haible <[email protected]>, 2011. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -17,10 +16,11 @@ #include <config.h> -#include <stdlib.h> +/* Specification. */ +#include <math.h> -#include <errno.h> -#include <string.h> -#include <wchar.h> - -#include "mbtowc-impl.h" +double +copysign (double x, double y) +{ + return (signbit (x) != signbit (y) ? - x : x); +} diff --git a/lib/isfinite.c b/lib/isfinite.c new file mode 100644 index 0000000..d9eddf5 --- /dev/null +++ b/lib/isfinite.c @@ -0,0 +1,51 @@ +/* Test for finite value (zero, subnormal, or normal, and not infinite or NaN). + Copyright (C) 2007-2013 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, see <http://www.gnu.org/licenses/>. */ + +/* Written by Ben Pfaff <[email protected]>, 2007. */ + +#include <config.h> + +#include "isnanf-nolibm.h" +#include "isnand-nolibm.h" +#include "isnanl-nolibm.h" + +/* The "cc" compiler on HP-UX 11.11, when optimizing, simplifies the test + x - y == 0.0 to x == y, a simplification which is invalid when x and y + are Infinity. Disable this optimization. */ +#if defined __hpux && !defined __GNUC__ +static float zerof; +static double zerod; +static long double zerol; +#else +# define zerof 0.f +# define zerod 0. +# define zerol 0.L +#endif + +int gl_isfinitef (float x) +{ + return !isnanf (x) && x - x == zerof; +} + +int gl_isfinited (double x) +{ + return !isnand (x) && x - x == zerod; +} + +int gl_isfinitel (long double x) +{ + return !isnanl (x) && x - x == zerol; +} diff --git a/lib/isnand-nolibm.h b/lib/isnanf-nolibm.h similarity index 62% copy from lib/isnand-nolibm.h copy to lib/isnanf-nolibm.h index 3510202..56f4fde 100644 --- a/lib/isnand-nolibm.h +++ b/lib/isnanf-nolibm.h @@ -14,20 +14,27 @@ You should have received a copy of the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#if HAVE_ISNAND_IN_LIBC -/* Get declaration of isnan macro. */ +#if HAVE_ISNANF_IN_LIBC +/* Get declaration of isnan macro or (older) isnanf function. */ # include <math.h> # if __GNUC__ >= 4 /* GCC 4.0 and newer provides three built-ins for isnan. */ -# undef isnand -# define isnand(x) __builtin_isnan ((double)(x)) +# undef isnanf +# define isnanf(x) __builtin_isnanf ((float)(x)) +# elif defined isnan +# undef isnanf +# define isnanf(x) isnan ((float)(x)) # else -# undef isnand -# define isnand(x) isnan ((double)(x)) + /* Get declaration of isnanf(), if not declared in <math.h>. */ +# if defined __sgi + /* We can't include <ieeefp.h>, because it conflicts with our definition of + isnand. Therefore declare isnanf separately. */ +extern int isnanf (float x); +# endif # endif #else /* Test whether X is a NaN. */ -# undef isnand -# define isnand rpl_isnand -extern int isnand (double x); +# undef isnanf +# define isnanf rpl_isnanf +extern int isnanf (float x); #endif diff --git a/lib/isnand-nolibm.h b/lib/isnanl-nolibm.h similarity index 74% copy from lib/isnand-nolibm.h copy to lib/isnanl-nolibm.h index 3510202..c5d0323 100644 --- a/lib/isnand-nolibm.h +++ b/lib/isnanl-nolibm.h @@ -14,20 +14,20 @@ You should have received a copy of the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#if HAVE_ISNAND_IN_LIBC -/* Get declaration of isnan macro. */ +#if HAVE_ISNANL_IN_LIBC +/* Get declaration of isnan macro or (older) isnanl function. */ # include <math.h> # if __GNUC__ >= 4 /* GCC 4.0 and newer provides three built-ins for isnan. */ -# undef isnand -# define isnand(x) __builtin_isnan ((double)(x)) -# else -# undef isnand -# define isnand(x) isnan ((double)(x)) +# undef isnanl +# define isnanl(x) __builtin_isnanl ((long double)(x)) +# elif defined isnan +# undef isnanl +# define isnanl(x) isnan ((long double)(x)) # endif #else /* Test whether X is a NaN. */ -# undef isnand -# define isnand rpl_isnand -extern int isnand (double x); +# undef isnanl +# define isnanl rpl_isnanl +extern int isnanl (long double x); #endif diff --git a/lib/signbitd.c b/lib/signbitd.c new file mode 100644 index 0000000..1c813da --- /dev/null +++ b/lib/signbitd.c @@ -0,0 +1,64 @@ +/* signbit() macro: Determine the sign bit of a floating-point number. + Copyright (C) 2007-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <math.h> + +#include <string.h> +#include "isnand-nolibm.h" +#include "float+.h" + +#ifdef gl_signbitd_OPTIMIZED_MACRO +# undef gl_signbitd +#endif + +int +gl_signbitd (double arg) +{ +#if defined DBL_SIGNBIT_WORD && defined DBL_SIGNBIT_BIT + /* The use of a union to extract the bits of the representation of a + 'long double' is safe in practice, despite of the "aliasing rules" of + C99, because the GCC docs say + "Even with '-fstrict-aliasing', type-punning is allowed, provided the + memory is accessed through the union type." + and similarly for other compilers. */ +# define NWORDS \ + ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) + union { double value; unsigned int word[NWORDS]; } m; + m.value = arg; + return (m.word[DBL_SIGNBIT_WORD] >> DBL_SIGNBIT_BIT) & 1; +#elif HAVE_COPYSIGN_IN_LIBC + return copysign (1.0, arg) < 0; +#else + /* This does not do the right thing for NaN, but this is irrelevant for + most use cases. */ + if (isnand (arg)) + return 0; + if (arg < 0.0) + return 1; + else if (arg == 0.0) + { + /* Distinguish 0.0 and -0.0. */ + static double plus_zero = 0.0; + double arg_mem = arg; + return (memcmp (&plus_zero, &arg_mem, SIZEOF_DBL) != 0); + } + else + return 0; +#endif +} diff --git a/lib/signbitf.c b/lib/signbitf.c new file mode 100644 index 0000000..817484b --- /dev/null +++ b/lib/signbitf.c @@ -0,0 +1,64 @@ +/* signbit() macro: Determine the sign bit of a floating-point number. + Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <math.h> + +#include <string.h> +#include "isnanf-nolibm.h" +#include "float+.h" + +#ifdef gl_signbitf_OPTIMIZED_MACRO +# undef gl_signbitf +#endif + +int +gl_signbitf (float arg) +{ +#if defined FLT_SIGNBIT_WORD && defined FLT_SIGNBIT_BIT + /* The use of a union to extract the bits of the representation of a + 'long double' is safe in practice, despite of the "aliasing rules" of + C99, because the GCC docs say + "Even with '-fstrict-aliasing', type-punning is allowed, provided the + memory is accessed through the union type." + and similarly for other compilers. */ +# define NWORDS \ + ((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) + union { float value; unsigned int word[NWORDS]; } m; + m.value = arg; + return (m.word[FLT_SIGNBIT_WORD] >> FLT_SIGNBIT_BIT) & 1; +#elif HAVE_COPYSIGNF_IN_LIBC + return copysignf (1.0f, arg) < 0; +#else + /* This does not do the right thing for NaN, but this is irrelevant for + most use cases. */ + if (isnanf (arg)) + return 0; + if (arg < 0.0f) + return 1; + else if (arg == 0.0f) + { + /* Distinguish 0.0f and -0.0f. */ + static float plus_zero = 0.0f; + float arg_mem = arg; + return (memcmp (&plus_zero, &arg_mem, SIZEOF_FLT) != 0); + } + else + return 0; +#endif +} diff --git a/lib/signbitl.c b/lib/signbitl.c new file mode 100644 index 0000000..159cfce --- /dev/null +++ b/lib/signbitl.c @@ -0,0 +1,64 @@ +/* signbit() macro: Determine the sign bit of a floating-point number. + Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include <math.h> + +#include <string.h> +#include "isnanl-nolibm.h" +#include "float+.h" + +#ifdef gl_signbitl_OPTIMIZED_MACRO +# undef gl_signbitl +#endif + +int +gl_signbitl (long double arg) +{ +#if defined LDBL_SIGNBIT_WORD && defined LDBL_SIGNBIT_BIT + /* The use of a union to extract the bits of the representation of a + 'long double' is safe in practice, despite of the "aliasing rules" of + C99, because the GCC docs say + "Even with '-fstrict-aliasing', type-punning is allowed, provided the + memory is accessed through the union type." + and similarly for other compilers. */ +# define NWORDS \ + ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) + union { long double value; unsigned int word[NWORDS]; } m; + m.value = arg; + return (m.word[LDBL_SIGNBIT_WORD] >> LDBL_SIGNBIT_BIT) & 1; +#elif HAVE_COPYSIGNL_IN_LIBC + return copysignl (1.0L, arg) < 0; +#else + /* This does not do the right thing for NaN, but this is irrelevant for + most use cases. */ + if (isnanl (arg)) + return 0; + if (arg < 0.0L) + return 1; + else if (arg == 0.0L) + { + /* Distinguish 0.0L and -0.0L. */ + static long double plus_zero = 0.0L; + long double arg_mem = arg; + return (memcmp (&plus_zero, &arg_mem, SIZEOF_LDBL) != 0); + } + else + return 0; +#endif +} diff --git a/m4/copysign.m4 b/m4/copysign.m4 new file mode 100644 index 0000000..382a6c6 --- /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/isinf.m4 b/m4/isfinite.m4 similarity index 61% copy from m4/isinf.m4 copy to m4/isfinite.m4 index 513a1ba..b54b403 100644 --- a/m4/isinf.m4 +++ b/m4/isfinite.m4 @@ -1,59 +1,55 @@ -# isinf.m4 serial 9 +# 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_ISINF], +AC_DEFUN([gl_ISFINITE], [ AC_REQUIRE([gl_MATH_H_DEFAULTS]) - dnl Persuade glibc <math.h> to declare isinf. + dnl Persuade glibc <math.h> to declare isfinite. AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - AC_CHECK_DECLS([isinf], , , - [[#include <math.h> - #ifndef isinf - #error "isinf must be a macro, not a function" - #endif - ]]) - if test "$ac_cv_have_decl_isinf" = yes; then - gl_CHECK_MATH_LIB([ISINF_LIBM], [x = isinf (x) + isinf ((float) x);]) - if test "$ISINF_LIBM" != missing; then - dnl Test whether isinf() on 'long double' works. - gl_ISINFL_WORKS - case "$gl_cv_func_isinfl_works" in + 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) ;; - *) ISINF_LIBM=missing;; + *) 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_isinf" != yes || - test "$ISINF_LIBM" = missing; then - REPLACE_ISINF=1 - dnl No libraries are needed to link lib/isinf.c. - ISINF_LIBM= + 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([ISINF_LIBM]) + AC_SUBST([ISFINITE_LIBM]) ]) -dnl Test whether isinf() works: -dnl 1) Whether it correctly returns false for LDBL_MAX. -dnl 2) Whether on 'long double' recognizes all numbers which are neither -dnl finite nor infinite. This test fails on OpenBSD/x86, but could also -dnl fail e.g. on i686, x86_64, ia64, 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_ISINFL_WORKS], +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 isinf(long double) works], [gl_cv_func_isinfl_works], + AC_CACHE_CHECK([whether isfinite(long double) works], [gl_cv_func_isfinitel_works], [ - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include <float.h> #include <limits.h> #include <math.h> @@ -76,14 +72,11 @@ int main () { int result = 0; - if (isinf (LDBL_MAX)) - result |= 1; - { memory_long_double m; unsigned int i; - /* The isinf macro should be immune against changes in the sign bit and + /* 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). */ @@ -91,8 +84,8 @@ int main () m.word[NWORDS / 2] ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1); for (i = 0; i < NWORDS; i++) m.word[i] |= 1; - if (isinf (m.value)) - result |= 2; + 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 @@ -111,17 +104,17 @@ int main () { /* Quiet NaN. */ static memory_long_double x = { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) }; - if (isinf (x.value)) + if (isfinite (x.value)) result |= 2; } { /* Signalling NaN. */ static memory_long_double x = { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) }; - if (isinf (x.value)) + if (isfinite (x.value)) result |= 2; } - /* The isinf macro should recognize Pseudo-NaNs, Pseudo-Infinities, + /* 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. @@ -131,44 +124,41 @@ int main () { /* Pseudo-NaN. */ static memory_long_double x = { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) }; - if (isinf (x.value)) + if (isfinite (x.value)) result |= 4; } { /* Pseudo-Infinity. */ static memory_long_double x = { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) }; - if (isinf (x.value)) + if (isfinite (x.value)) result |= 8; } { /* Pseudo-Zero. */ static memory_long_double x = { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) }; - if (isinf (x.value)) + if (isfinite (x.value)) result |= 16; } { /* Unnormalized number. */ static memory_long_double x = { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) }; - if (isinf (x.value)) + if (isfinite (x.value)) result |= 32; } { /* Pseudo-Denormal. */ static memory_long_double x = { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) }; - if (isinf (x.value)) + if (isfinite (x.value)) result |= 64; } #endif return result; -}]])], [gl_cv_func_isinfl_works=yes], [gl_cv_func_isinfl_works=no], - [ - case "$host" in - # Guess no on OpenBSD ia64, x86_64, i386. - ia64-*-openbsd* | x86_64-*-openbsd* | i*86-*-openbsd*) - gl_cv_func_isinfl_works="guessing no";; - *) - gl_cv_func_isinfl_works="guessing yes";; +}]])], [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 0000000..d58caaf --- /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; +} +]]) hooks/post-receive -- GNU Guile
