diff options
-rw-r--r-- | include/bits/mathcalls-narrow.h | 1 | ||||
-rw-r--r-- | math/Makefile | 14 | ||||
-rw-r--r-- | math/bits/mathcalls-narrow.h | 21 | ||||
-rw-r--r-- | math/math-narrow.h | 146 | ||||
-rw-r--r-- | math/math.h | 284 | ||||
-rw-r--r-- | sysdeps/i386/fpu/fenv_private.h | 2 | ||||
-rw-r--r-- | sysdeps/ieee754/float128/float128_private.h | 17 |
7 files changed, 484 insertions, 1 deletions
diff --git a/include/bits/mathcalls-narrow.h b/include/bits/mathcalls-narrow.h new file mode 100644 index 0000000000..0c66ecf889 --- /dev/null +++ b/include/bits/mathcalls-narrow.h @@ -0,0 +1 @@ +#include <math/bits/mathcalls-narrow.h> diff --git a/math/Makefile b/math/Makefile index ec7d91ca3d..247163cf0e 100644 --- a/math/Makefile +++ b/math/Makefile @@ -29,7 +29,7 @@ headers := math.h bits/mathcalls.h bits/mathinline.h \ bits/libm-simd-decl-stubs.h bits/iscanonical.h \ bits/flt-eval-method.h bits/fp-fast.h bits/fp-logb.h \ bits/long-double.h bits/mathcalls-helper-functions.h \ - bits/floatn.h bits/floatn-common.h + bits/floatn.h bits/floatn-common.h bits/mathcalls-narrow.h # FPU support code. aux := setfpucw fpu_control @@ -89,6 +89,16 @@ libm-compat-calls = \ w_lgammaF_r_compat w_lgammaF_compat2 w_expF_compat \ w_lgamma_compatF k_standardF +libm-narrow-fns = +libm-narrow-types-basic = s_fF s_f32xFf64 +libm-narrow-types-ldouble-yes = s_fFl s_dFl +libm-narrow-types-float128-yes = s_f32Ff128 s_f64Ff128 s_f64xFf128 +libm-narrow-types-float128-alias-yes = s_f64xFf128 +libm-narrow-types = $(libm-narrow-types-basic) \ + $(libm-narrow-types-ldouble-$(long-double-fcts)) \ + $(libm-narrow-types-float128-$(float128-fcts)) \ + $(libm-narrow-types-float128-alias-$(float128-alias-fcts)) + # Type specific routine support. # # The following three variables control what is included for each type: @@ -148,6 +158,8 @@ libm-routines = $(strip $(libm-support) \ $(libm-compat-calls)) \ $(call type-foreach, $(libm-calls)) \ $(foreach t, $(types), $(type-$(t)-routines))) \ + $(foreach f,$(libm-narrow-fns), \ + $(subst F,$(f),$(libm-narrow-types))) # These functions are in libc instead of libm because __printf_fp # calls them, so any program using printf will need them linked in, diff --git a/math/bits/mathcalls-narrow.h b/math/bits/mathcalls-narrow.h new file mode 100644 index 0000000000..0f1f0510a0 --- /dev/null +++ b/math/bits/mathcalls-narrow.h @@ -0,0 +1,21 @@ +/* Declare functions returning a narrower type. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library 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.1 of the License, or (at your option) any later version. + + The GNU C Library 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 the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _MATH_H +# error "Never include <bits/mathcalls-narrow.h> directly; include <math.h> instead." +#endif diff --git a/math/math-narrow.h b/math/math-narrow.h new file mode 100644 index 0000000000..1a3a5c57d7 --- /dev/null +++ b/math/math-narrow.h @@ -0,0 +1,146 @@ +/* Helper macros for functions returning a narrower type. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library 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.1 of the License, or (at your option) any later version. + + The GNU C Library 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 the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _MATH_NARROW_H +#define _MATH_NARROW_H 1 + +#include <bits/floatn.h> +#include <bits/long-double.h> +#include <errno.h> +#include <fenv.h> +#include <ieee754.h> +#include <math_private.h> + +/* Carry out a computation using round-to-odd. The computation is + EXPR; the union type in which to store the result is UNION and the + subfield of the "ieee" field of that union with the low part of the + mantissa is MANTISSA; SUFFIX is the suffix for the libc_fe* macros + to ensure that the correct rounding mode is used, for platforms + with multiple rounding modes where those macros set only the + relevant mode. This macro does not work correctly if the sign of + an exact zero result depends on the rounding mode, so that case + must be checked for separately. */ +#define ROUND_TO_ODD(EXPR, UNION, SUFFIX, MANTISSA) \ + ({ \ + fenv_t env; \ + UNION u; \ + \ + libc_feholdexcept_setround ## SUFFIX (&env, FE_TOWARDZERO); \ + u.d = (EXPR); \ + math_force_eval (u.d); \ + u.ieee.MANTISSA \ + |= libc_feupdateenv_test ## SUFFIX (&env, FE_INEXACT) != 0; \ + \ + u.d; \ + }) + +/* The following macros declare aliases for a narrowing function. The + sole argument is the base name of a family of functions, such as + "add". If any platform changes long double format after the + introduction of narrowing functions, in a way requiring symbol + versioning compatibility, additional variants of these macros will + be needed. */ + +#define libm_alias_float_double_main(func) \ + weak_alias (__f ## func, f ## func) \ + weak_alias (__f ## func, f32 ## func ## f64) \ + weak_alias (__f ## func, f32 ## func ## f32x) + +#ifdef NO_LONG_DOUBLE +# define libm_alias_float_double(func) \ + libm_alias_float_double_main (func) \ + weak_alias (__f ## func, f ## func ## l) +#else +# define libm_alias_float_double(func) \ + libm_alias_float_double_main (func) +#endif + +#define libm_alias_float32x_float64_main(func) \ + weak_alias (__f32x ## func ## f64, f32x ## func ## f64) + +#ifdef NO_LONG_DOUBLE +# define libm_alias_float32x_float64(func) \ + libm_alias_float32x_float64_main (func) \ + weak_alias (__f32x ## func ## f64, d ## func ## l) +#elif defined __LONG_DOUBLE_MATH_OPTIONAL +# define libm_alias_float32x_float64(func) \ + libm_alias_float32x_float64_main (func) \ + weak_alias (__f32x ## func ## f64, __nldbl_d ## func ## l) +#else +# define libm_alias_float32x_float64(func) \ + libm_alias_float32x_float64_main (func) +#endif + +#if __HAVE_FLOAT128 && !__HAVE_DISTINCT_FLOAT128 +# define libm_alias_float_ldouble_f128(func) \ + weak_alias (__f ## func ## l, f32 ## func ## f128) +# define libm_alias_double_ldouble_f128(func) \ + weak_alias (__d ## func ## l, f32x ## func ## f128) \ + weak_alias (__d ## func ## l, f64 ## func ## f128) +#else +# define libm_alias_float_ldouble_f128(func) +# define libm_alias_double_ldouble_f128(func) +#endif + +#if __HAVE_FLOAT64X_LONG_DOUBLE +# define libm_alias_float_ldouble_f64x(func) \ + weak_alias (__f ## func ## l, f32 ## func ## f64x) +# define libm_alias_double_ldouble_f64x(func) \ + weak_alias (__d ## func ## l, f32x ## func ## f64x) \ + weak_alias (__d ## func ## l, f64 ## func ## f64x) +#else +# define libm_alias_float_ldouble_f64x(func) +# define libm_alias_double_ldouble_f64x(func) +#endif + +#define libm_alias_float_ldouble(func) \ + weak_alias (__f ## func ## l, f ## func ## l) \ + libm_alias_float_ldouble_f128 (func) \ + libm_alias_float_ldouble_f64x (func) + +#define libm_alias_double_ldouble(func) \ + weak_alias (__d ## func ## l, d ## func ## l) \ + libm_alias_double_ldouble_f128 (func) \ + libm_alias_double_ldouble_f64x (func) + +#define libm_alias_float64x_float128(func) \ + weak_alias (__f64x ## func ## f128, f64x ## func ## f128) + +#define libm_alias_float32_float128_main(func) \ + weak_alias (__f32 ## func ## f128, f32 ## func ## f128) + +#define libm_alias_float64_float128_main(func) \ + weak_alias (__f64 ## func ## f128, f64 ## func ## f128) \ + weak_alias (__f64 ## func ## f128, f32x ## func ## f128) + +#if __HAVE_FLOAT64X_LONG_DOUBLE +# define libm_alias_float32_float128(func) \ + libm_alias_float32_float128_main (func) +# define libm_alias_float64_float128(func) \ + libm_alias_float64_float128_main (func) +#else +# define libm_alias_float32_float128(func) \ + libm_alias_float32_float128_main (func) \ + weak_alias (__f32 ## func ## f128, f32 ## func ## f64x) +# define libm_alias_float64_float128(func) \ + libm_alias_float64_float128_main (func) \ + weak_alias (__f64 ## func ## f128, f64 ## func ## f64x) \ + weak_alias (__f64 ## func ## f128, f32x ## func ## f64x) +#endif + +#endif /* math-narrow.h. */ diff --git a/math/math.h b/math/math.h index 3c515f817f..2e2696854b 100644 --- a/math/math.h +++ b/math/math.h @@ -483,6 +483,290 @@ extern long double __REDIRECT_NTH (nexttowardl, #undef __MATHDECL #undef __MATHCALL +/* Declare functions returning a narrower type. */ +#define __MATHCALL_NARROW_ARGS_1 (_Marg_ __x) +#define __MATHCALL_NARROW_ARGS_2 (_Marg_ __x, _Marg_ __y) +#define __MATHCALL_NARROW_ARGS_3 (_Marg_ __x, _Marg_ __y, _Marg_ __z) +#define __MATHCALL_NARROW_NORMAL(func, nargs) \ + extern _Mret_ func __MATHCALL_NARROW_ARGS_ ## nargs __THROW +#define __MATHCALL_NARROW_REDIR(func, redir, nargs) \ + extern _Mret_ __REDIRECT_NTH (func, __MATHCALL_NARROW_ARGS_ ## nargs, \ + redir) +#define __MATHCALL_NARROW(func, redir, nargs) \ + __MATHCALL_NARROW_NORMAL (func, nargs) + +#if __GLIBC_USE (IEC_60559_BFP_EXT) + +# define _Mret_ float +# define _Marg_ double +# define __MATHCALL_NAME(name) f ## name +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME + +# define _Mret_ float +# define _Marg_ long double +# define __MATHCALL_NAME(name) f ## name ## l +# ifdef __LDBL_COMPAT +# define __MATHCALL_REDIR_NAME(name) f ## name +# undef __MATHCALL_NARROW +# define __MATHCALL_NARROW(func, redir, nargs) \ + __MATHCALL_NARROW_REDIR (func, redir, nargs) +# endif +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# ifdef __LDBL_COMPAT +# undef __MATHCALL_REDIR_NAME +# undef __MATHCALL_NARROW +# define __MATHCALL_NARROW(func, redir, nargs) \ + __MATHCALL_NARROW_NORMAL (func, nargs) +# endif + +# define _Mret_ double +# define _Marg_ long double +# define __MATHCALL_NAME(name) d ## name ## l +# ifdef __LDBL_COMPAT +# define __MATHCALL_REDIR_NAME(name) __nldbl_d ## name ## l +# undef __MATHCALL_NARROW +# define __MATHCALL_NARROW(func, redir, nargs) \ + __MATHCALL_NARROW_REDIR (func, redir, nargs) +# endif +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# ifdef __LDBL_COMPAT +# undef __MATHCALL_REDIR_NAME +# undef __MATHCALL_NARROW +# define __MATHCALL_NARROW(func, redir, nargs) \ + __MATHCALL_NARROW_NORMAL (func, nargs) +# endif + +#endif + +#if __GLIBC_USE (IEC_60559_TYPES_EXT) + +# if __HAVE_FLOAT16 && __HAVE_FLOAT32 +# define _Mret_ _Float16 +# define _Marg_ _Float32 +# define __MATHCALL_NAME(name) f16 ## name ## f32 +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT16 && __HAVE_FLOAT32X +# define _Mret_ _Float16 +# define _Marg_ _Float32x +# define __MATHCALL_NAME(name) f16 ## name ## f32x +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT16 && __HAVE_FLOAT64 +# define _Mret_ _Float16 +# define _Marg_ _Float64 +# define __MATHCALL_NAME(name) f16 ## name ## f64 +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT16 && __HAVE_FLOAT64X +# define _Mret_ _Float16 +# define _Marg_ _Float64x +# define __MATHCALL_NAME(name) f16 ## name ## f64x +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT16 && __HAVE_FLOAT128 +# define _Mret_ _Float16 +# define _Marg_ _Float128 +# define __MATHCALL_NAME(name) f16 ## name ## f128 +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT16 && __HAVE_FLOAT128X +# define _Mret_ _Float16 +# define _Marg_ _Float128x +# define __MATHCALL_NAME(name) f16 ## name ## f128x +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT32 && __HAVE_FLOAT32X +# define _Mret_ _Float32 +# define _Marg_ _Float32x +# define __MATHCALL_NAME(name) f32 ## name ## f32x +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT32 && __HAVE_FLOAT64 +# define _Mret_ _Float32 +# define _Marg_ _Float64 +# define __MATHCALL_NAME(name) f32 ## name ## f64 +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT32 && __HAVE_FLOAT64X +# define _Mret_ _Float32 +# define _Marg_ _Float64x +# define __MATHCALL_NAME(name) f32 ## name ## f64x +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT32 && __HAVE_FLOAT128 +# define _Mret_ _Float32 +# define _Marg_ _Float128 +# define __MATHCALL_NAME(name) f32 ## name ## f128 +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT32 && __HAVE_FLOAT128X +# define _Mret_ _Float32 +# define _Marg_ _Float128x +# define __MATHCALL_NAME(name) f32 ## name ## f128x +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT32X && __HAVE_FLOAT64 +# define _Mret_ _Float32x +# define _Marg_ _Float64 +# define __MATHCALL_NAME(name) f32x ## name ## f64 +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT32X && __HAVE_FLOAT64X +# define _Mret_ _Float32x +# define _Marg_ _Float64x +# define __MATHCALL_NAME(name) f32x ## name ## f64x +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT32X && __HAVE_FLOAT128 +# define _Mret_ _Float32x +# define _Marg_ _Float128 +# define __MATHCALL_NAME(name) f32x ## name ## f128 +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT32X && __HAVE_FLOAT128X +# define _Mret_ _Float32x +# define _Marg_ _Float128x +# define __MATHCALL_NAME(name) f32x ## name ## f128x +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT64 && __HAVE_FLOAT64X +# define _Mret_ _Float64 +# define _Marg_ _Float64x +# define __MATHCALL_NAME(name) f64 ## name ## f64x +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT64 && __HAVE_FLOAT128 +# define _Mret_ _Float64 +# define _Marg_ _Float128 +# define __MATHCALL_NAME(name) f64 ## name ## f128 +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT64 && __HAVE_FLOAT128X +# define _Mret_ _Float64 +# define _Marg_ _Float128x +# define __MATHCALL_NAME(name) f64 ## name ## f128x +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT64X && __HAVE_FLOAT128 +# define _Mret_ _Float64x +# define _Marg_ _Float128 +# define __MATHCALL_NAME(name) f64x ## name ## f128 +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT64X && __HAVE_FLOAT128X +# define _Mret_ _Float64x +# define _Marg_ _Float128x +# define __MATHCALL_NAME(name) f64x ## name ## f128x +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +# if __HAVE_FLOAT128 && __HAVE_FLOAT128X +# define _Mret_ _Float128 +# define _Marg_ _Float128x +# define __MATHCALL_NAME(name) f128 ## name ## f128x +# include <bits/mathcalls-narrow.h> +# undef _Mret_ +# undef _Marg_ +# undef __MATHCALL_NAME +# endif + +#endif + +#undef __MATHCALL_NARROW_ARGS_1 +#undef __MATHCALL_NARROW_ARGS_2 +#undef __MATHCALL_NARROW_ARGS_3 +#undef __MATHCALL_NARROW_NORMAL +#undef __MATHCALL_NARROW_REDIR +#undef __MATHCALL_NARROW #if defined __USE_MISC || defined __USE_XOPEN /* This variable is used by `gamma' and `lgamma'. */ diff --git a/sysdeps/i386/fpu/fenv_private.h b/sysdeps/i386/fpu/fenv_private.h index 953b559f93..b55ada8ff8 100644 --- a/sysdeps/i386/fpu/fenv_private.h +++ b/sysdeps/i386/fpu/fenv_private.h @@ -337,6 +337,8 @@ libc_feresetround_387 (fenv_t *e) x86_64, so that must be set for float128 computations. */ # define SET_RESTORE_ROUNDF128(RM) \ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_sse, libc_feresetround_sse) +# define libc_feholdexcept_setroundf128 libc_feholdexcept_setround_sse +# define libc_feupdateenv_testf128 libc_feupdateenv_test_sse #endif /* We have support for rounding mode context. */ diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h index c9d9924169..d0d41c3cef 100644 --- a/sysdeps/ieee754/float128/float128_private.h +++ b/sysdeps/ieee754/float128/float128_private.h @@ -54,6 +54,16 @@ # define SET_RESTORE_ROUNDL(RM) SET_RESTORE_ROUNDF128 (RM) #endif +#ifdef libc_feholdexcept_setroundf128 +# undef libc_feholdexcept_setroundl +# define libc_feholdexcept_setroundl(ENV, RM) \ + libc_feholdexcept_setroundf128 (ENV, RM) +#endif + +#ifdef libc_feupdateenv_testf128 +# undef libc_feupdateenv_testl +# define libc_feupdateenv_testl(ENV, EX) libc_feupdateenv_testf128 (ENV, EX) +#endif /* misc macros from the header below. */ #include <fix-fp-int-convert-overflow.h> @@ -122,6 +132,13 @@ #define libm_alias_ldouble_r(from, to, r) libm_alias_float128_r (from, to, r) +#include <math/math-narrow.h> +#undef libm_alias_float_ldouble +#define libm_alias_float_ldouble(func) libm_alias_float32_float128 (func) +#undef libm_alias_double_ldouble +#define libm_alias_double_ldouble(func) libm_alias_float64_float128 (func) + + /* IEEE function renames. */ #define __ieee754_acoshl __ieee754_acoshf128 #define __ieee754_acosl __ieee754_acosf128 |