diff options
Diffstat (limited to 'math')
-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 |
4 files changed, 464 insertions, 1 deletions
diff --git a/math/Makefile b/math/Makefile index 5538aa2207..ee0cd6fce1 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'. */ |