Mercurial > hg > octave-lyh > gnulib-hg
changeset 9645:c8174371956e
Exploit the __builtin_signbit GCC built-in.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sat, 26 Jan 2008 02:26:52 +0100 |
parents | 42367c277240 |
children | a113e473cc98 |
files | ChangeLog lib/math.in.h m4/math_h.m4 m4/signbit.m4 modules/math |
diffstat | 5 files changed, 165 insertions(+), 102 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2008-01-25 Paul Eggert <eggert@cs.ucla.edu> + Bruno Haible <bruno@clisp.org> + + * m4/signbit.m4 (gl_SIGNBIT): Require a macro definition. Test whether + the GCC builtins for signbits are present and set + REPLACE_SIGNBIT_USING_GCC if so. + * lib/math.in.h (signbit): Define using GCC builtins if + REPLACE_SIGNBIT_USING_GCC is set. + * m4/math_h.m4 (gl_MATH_H_DEFAULTS): Initialize + REPLACE_SIGNBIT_USING_GCC. + * modules/math (Makefile.am): Substitute REPLACE_SIGNBIT_USING_GCC. + 2008-01-25 Jim Meyering <meyering@redhat.com> Prefer <config.h> over "config.h". See autoconf doc for explanation.
--- a/lib/math.in.h +++ b/lib/math.in.h @@ -353,6 +353,14 @@ #if @GNULIB_SIGNBIT@ +# if @REPLACE_SIGNBIT_USING_GCC@ +# undef signbit + /* GCC 4.0 and newer provides three built-ins for signbit. */ +# define signbit(x) \ + (sizeof (x) == sizeof (long double) ? __builtin_signbitl (x) : \ + sizeof (x) == sizeof (double) ? __builtin_signbit (x) : \ + __builtin_signbitf (x)) +# endif # if @REPLACE_SIGNBIT@ # undef signbit extern int gl_signbitf (float arg);
--- a/m4/math_h.m4 +++ b/m4/math_h.m4 @@ -1,5 +1,5 @@ -# math_h.m4 serial 8 -dnl Copyright (C) 2007 Free Software Foundation, Inc. +# math_h.m4 serial 9 +dnl Copyright (C) 2007-2008 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. @@ -36,30 +36,31 @@ GNULIB_TRUNCF=0; AC_SUBST([GNULIB_TRUNCF]) GNULIB_TRUNCL=0; AC_SUBST([GNULIB_TRUNCL]) dnl Assume proper GNU behavior unless another module says otherwise. - HAVE_DECL_ACOSL=1; AC_SUBST([HAVE_DECL_ACOSL]) - HAVE_DECL_ASINL=1; AC_SUBST([HAVE_DECL_ASINL]) - HAVE_DECL_ATANL=1; AC_SUBST([HAVE_DECL_ATANL]) - HAVE_DECL_COSL=1; AC_SUBST([HAVE_DECL_COSL]) - HAVE_DECL_EXPL=1; AC_SUBST([HAVE_DECL_EXPL]) - HAVE_DECL_FREXPL=1; AC_SUBST([HAVE_DECL_FREXPL]) - HAVE_DECL_LDEXPL=1; AC_SUBST([HAVE_DECL_LDEXPL]) - HAVE_DECL_LOGL=1; AC_SUBST([HAVE_DECL_LOGL]) - HAVE_DECL_SINL=1; AC_SUBST([HAVE_DECL_SINL]) - HAVE_DECL_SQRTL=1; AC_SUBST([HAVE_DECL_SQRTL]) - HAVE_DECL_TANL=1; AC_SUBST([HAVE_DECL_TANL]) - HAVE_DECL_TRUNC=1; AC_SUBST([HAVE_DECL_TRUNC]) - HAVE_DECL_TRUNCF=1; AC_SUBST([HAVE_DECL_TRUNCF]) - HAVE_DECL_TRUNCL=1; AC_SUBST([HAVE_DECL_TRUNCL]) - REPLACE_CEILF=0; AC_SUBST([REPLACE_CEILF]) - REPLACE_CEILL=0; AC_SUBST([REPLACE_CEILL]) - REPLACE_FLOORF=0; AC_SUBST([REPLACE_FLOORF]) - REPLACE_FLOORL=0; AC_SUBST([REPLACE_FLOORL]) - REPLACE_FREXP=0; AC_SUBST([REPLACE_FREXP]) - REPLACE_FREXPL=0; AC_SUBST([REPLACE_FREXPL]) - REPLACE_ISFINITE=0; AC_SUBST([REPLACE_ISFINITE]) - REPLACE_LDEXPL=0; AC_SUBST([REPLACE_LDEXPL]) - REPLACE_ROUND=0; AC_SUBST([REPLACE_ROUND]) - REPLACE_ROUNDF=0; AC_SUBST([REPLACE_ROUNDF]) - REPLACE_ROUNDL=0; AC_SUBST([REPLACE_ROUNDL]) - REPLACE_SIGNBIT=0; AC_SUBST([REPLACE_SIGNBIT]) + HAVE_DECL_ACOSL=1; AC_SUBST([HAVE_DECL_ACOSL]) + HAVE_DECL_ASINL=1; AC_SUBST([HAVE_DECL_ASINL]) + HAVE_DECL_ATANL=1; AC_SUBST([HAVE_DECL_ATANL]) + HAVE_DECL_COSL=1; AC_SUBST([HAVE_DECL_COSL]) + HAVE_DECL_EXPL=1; AC_SUBST([HAVE_DECL_EXPL]) + HAVE_DECL_FREXPL=1; AC_SUBST([HAVE_DECL_FREXPL]) + HAVE_DECL_LDEXPL=1; AC_SUBST([HAVE_DECL_LDEXPL]) + HAVE_DECL_LOGL=1; AC_SUBST([HAVE_DECL_LOGL]) + HAVE_DECL_SINL=1; AC_SUBST([HAVE_DECL_SINL]) + HAVE_DECL_SQRTL=1; AC_SUBST([HAVE_DECL_SQRTL]) + HAVE_DECL_TANL=1; AC_SUBST([HAVE_DECL_TANL]) + HAVE_DECL_TRUNC=1; AC_SUBST([HAVE_DECL_TRUNC]) + HAVE_DECL_TRUNCF=1; AC_SUBST([HAVE_DECL_TRUNCF]) + HAVE_DECL_TRUNCL=1; AC_SUBST([HAVE_DECL_TRUNCL]) + REPLACE_CEILF=0; AC_SUBST([REPLACE_CEILF]) + REPLACE_CEILL=0; AC_SUBST([REPLACE_CEILL]) + REPLACE_FLOORF=0; AC_SUBST([REPLACE_FLOORF]) + REPLACE_FLOORL=0; AC_SUBST([REPLACE_FLOORL]) + REPLACE_FREXP=0; AC_SUBST([REPLACE_FREXP]) + REPLACE_FREXPL=0; AC_SUBST([REPLACE_FREXPL]) + REPLACE_ISFINITE=0; AC_SUBST([REPLACE_ISFINITE]) + REPLACE_LDEXPL=0; AC_SUBST([REPLACE_LDEXPL]) + REPLACE_ROUND=0; AC_SUBST([REPLACE_ROUND]) + REPLACE_ROUNDF=0; AC_SUBST([REPLACE_ROUNDF]) + REPLACE_ROUNDL=0; AC_SUBST([REPLACE_ROUNDL]) + REPLACE_SIGNBIT=0; AC_SUBST([REPLACE_SIGNBIT]) + REPLACE_SIGNBIT_USING_GCC=0; AC_SUBST([REPLACE_SIGNBIT_USING_GCC]) ])
--- a/m4/signbit.m4 +++ b/m4/signbit.m4 @@ -1,5 +1,5 @@ -# signbit.m4 serial 2 -dnl Copyright (C) 2007 Free Software Foundation, Inc. +# signbit.m4 serial 3 +dnl Copyright (C) 2007-2008 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. @@ -11,7 +11,119 @@ [ AC_TRY_RUN([ #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], + [gl_cv_func_signbit="guessing no"]) + ]) + 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_TRY_RUN([ +#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], + [gl_cv_func_signbit_gcc="guessing no"]) + ]) + dnl Use the compiler built-ins whenever possible, because they are more + dnl efficient than the system library functions (if they exist). + if test "$gl_cv_func_signbit_gcc" = yes; then + REPLACE_SIGNBIT_USING_GCC=1 + else + if test "$gl_cv_func_signbit" != yes; then + REPLACE_SIGNBIT=1 + AC_LIBOBJ([signbitf]) + AC_LIBOBJ([signbitd]) + AC_LIBOBJ([signbitl]) + 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_TRY_LINK([#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_TRY_LINK([#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_TRY_LINK([#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 + fi + fi +]) + +AC_DEFUN([gl_SIGNBIT_TEST_PROGRAM], [ float p0f = 0.0f; float m0f = -0.0f; double p0d = 0.0; @@ -54,78 +166,7 @@ return 1; } return 0; -}], [gl_cv_func_signbit=yes], [gl_cv_func_signbit=no], - [gl_cv_func_signbit="guessing no"]) - ]) - if test "$gl_cv_func_signbit" != yes; then - REPLACE_SIGNBIT=1 - AC_LIBOBJ([signbitf]) - AC_LIBOBJ([signbitd]) - AC_LIBOBJ([signbitl]) - 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_TRY_LINK([#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_TRY_LINK([#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_TRY_LINK([#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 - fi +} ]) AC_DEFUN([gl_FLOAT_SIGN_LOCATION],
--- a/modules/math +++ b/modules/math @@ -64,6 +64,7 @@ -e 's|@''REPLACE_ROUNDF''@|$(REPLACE_ROUNDF)|g' \ -e 's|@''REPLACE_ROUNDL''@|$(REPLACE_ROUNDL)|g' \ -e 's|@''REPLACE_SIGNBIT''@|$(REPLACE_SIGNBIT)|g' \ + -e 's|@''REPLACE_SIGNBIT_USING_GCC''@|$(REPLACE_SIGNBIT_USING_GCC)|g' \ -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ < $(srcdir)/math.in.h; \ } > $@-t