diff --git a/glib/gnulib/isinf.c b/glib/gnulib/isinf.c new file mode 100644 index 000000000..e7b44b98d --- /dev/null +++ b/glib/gnulib/isinf.c @@ -0,0 +1,30 @@ +#ifndef _MSC_VER +#error "This implementation is currently supported for Visual Studio only!" +#endif + +#include "config.h" +#include +#include +#include + +int +gl_isinff (float x) +{ +#if defined (_WIN64) && (defined (_M_X64) || defined (_M_AMD64)) + return !_finitef (x); +#else + return !_finite (x); +#endif +} + +int +gl_isinfd (double x) +{ + return !_finite (x); +} + +int +gl_isinfl (long double x) +{ + return gl_isinfd (x); +} \ No newline at end of file diff --git a/glib/gnulib/isnanf-nolibm.h b/glib/gnulib/isnanf-nolibm.h new file mode 100644 index 000000000..47c52f7f3 --- /dev/null +++ b/glib/gnulib/isnanf-nolibm.h @@ -0,0 +1,40 @@ +/* Test for NaN that does not need libm. + Copyright (C) 2007-2019 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 PublicLicense as published by + the Free Software Foundation; either version 2.1 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 PublicLicense for more details. + + You should have received a copy of the GNU Lesser General PublicLicense + along with this program. If not, see . */ + +#if HAVE_ISNANF_IN_LIBC +/* Get declaration of isnan macro or (older) isnanf function. */ +# include +# if __GNUC__ >= 4 + /* GCC 4.0 and newer provides three built-ins for isnan. */ +# undef isnanf +# define isnanf(x) __builtin_isnanf ((float)(x)) +# elif defined isnan +# undef isnanf +# define isnanf(x) isnan ((float)(x)) +# else + /* Get declaration of isnanf(), if not declared in . */ +# if defined __sgi + /* We can't include , 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 isnanf +# define isnanf rpl_isnanf +extern int isnanf (float x); +#endif diff --git a/glib/gnulib/isnanf.c b/glib/gnulib/isnanf.c new file mode 100644 index 000000000..8651733a1 --- /dev/null +++ b/glib/gnulib/isnanf.c @@ -0,0 +1,20 @@ +/* Test for NaN that does not need libm. + Copyright (C) 2007, 2009-2019 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 PublicLicense as published by + the Free Software Foundation; either version 2.1 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 PublicLicense for more details. + + You should have received a copy of the GNU Lesser General PublicLicense + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2007. */ + +#define USE_FLOAT +#include "isnan.c" diff --git a/glib/gnulib/meson.build b/glib/gnulib/meson.build index 2d369a6ef..af697f29c 100644 --- a/glib/gnulib/meson.build +++ b/glib/gnulib/meson.build @@ -51,10 +51,6 @@ unneeded_funcs = [ 'ILOGB', 'ILOGBF', 'ILOGBL', - 'ISFINITE', - 'ISINF', - 'ISNAN', - 'ISNANF', 'LDEXPF', 'LOG', 'LOG10', @@ -84,7 +80,6 @@ unneeded_funcs = [ 'ROUND', 'ROUNDF', 'ROUNDL', - 'SIGNBIT', 'SINF', 'SINHF', 'SINL', @@ -110,9 +105,14 @@ endforeach needed_funcs = [ 'FREXP', 'FREXPL', + 'ISFINITE', + 'ISINF', + 'ISNAN', 'ISNAND', + 'ISNANF', 'ISNANL', 'LDEXPL', + 'SIGNBIT', ] foreach f : needed_funcs @@ -296,6 +296,29 @@ endif math_h_config.set ('REPLACE_LDEXPL', gl_cv_func_ldexpl_works ? 0 : 1) math_h_config.set ('HAVE_DECL_LDEXPL', gl_cv_func_ldexpl_decl ? 0 : 1) +inf_tmpl = '''#include + double x; + int main () {return @0@ (x);} + ''' + +other_needed_math_sources = [] +# Some compilers may not have isfinite, isinf available +foreach f: ['isfinite', 'isinf', 'isnan', 'isnanf', 'signbit'] + links = cc.links (inf_tmpl.format('@0@'.format(f)), + dependencies : [libm]) + math_h_config.set ('HAVE_@0@'.format(f.to_upper()), links ? 1 : 0) + math_h_config.set ('HAVE_@0@_IN_LIBC'.format(f.to_upper()), links ? 1 : 0) + math_h_config.set ('REPLACE_@0@'.format(f.to_upper()), links ? 0 : 1) + set_variable ('have_@0@'.format(f), links) + if not links + if f == 'signbit' + other_needed_math_sources += [ 'signbitd.c', 'signbitf.c', 'signbitl.c' ] + elif f != 'isfinite' and f != 'isnan' + other_needed_math_sources += [ '@0@.c'.format(f) ] + endif + endif +endforeach + math_h = configure_file (input: 'gnulib_math.h.in', output: 'gnulib_math.h', configuration: math_h_config) @@ -309,6 +332,8 @@ if not gl_cv_func_frexpl_works gnulib_sources += ['frexpl.c'] endif +gnulib_sources += other_needed_math_sources + gnulib_lib = static_library('gnulib', gnulib_sources, dependencies : [libm], include_directories : [configinc, glibinc, include_directories ('.')], diff --git a/glib/gnulib/signbitd.c b/glib/gnulib/signbitd.c new file mode 100644 index 000000000..7b20f9b2c --- /dev/null +++ b/glib/gnulib/signbitd.c @@ -0,0 +1,64 @@ +/* signbit() macro: Determine the sign bit of a floating-point number. + Copyright (C) 2007-2019 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 PublicLicense as published by + the Free Software Foundation; either version 2.1 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 PublicLicense for more details. + + You should have received a copy of the GNU Lesser General PublicLicense + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include +#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/glib/gnulib/signbitf.c b/glib/gnulib/signbitf.c new file mode 100644 index 000000000..57e6ef4c7 --- /dev/null +++ b/glib/gnulib/signbitf.c @@ -0,0 +1,64 @@ +/* signbit() macro: Determine the sign bit of a floating-point number. + Copyright (C) 2007, 2009-2019 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 PublicLicense as published by + the Free Software Foundation; either version 2.1 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 PublicLicense for more details. + + You should have received a copy of the GNU Lesser General PublicLicense + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include +#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/glib/gnulib/signbitl.c b/glib/gnulib/signbitl.c new file mode 100644 index 000000000..b1714aadc --- /dev/null +++ b/glib/gnulib/signbitl.c @@ -0,0 +1,64 @@ +/* signbit() macro: Determine the sign bit of a floating-point number. + Copyright (C) 2007, 2009-2019 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 PublicLicense as published by + the Free Software Foundation; either version 2.1 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 PublicLicense for more details. + + You should have received a copy of the GNU Lesser General PublicLicense + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include +#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 +}