about summary refs log tree commit diff
path: root/math
diff options
context:
space:
mode:
Diffstat (limited to 'math')
-rw-r--r--math/Makefile14
-rw-r--r--math/bits/mathcalls-narrow.h21
-rw-r--r--math/math-narrow.h146
-rw-r--r--math/math.h284
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'.  */