mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-21 01:12:26 +08:00
Refactor some libm type-generic macros.
This patch refactors some type-generic libm macros, in both math.h and math_private.h, to be based on a common __MATH_TG macro rather than all replicating similar logic to choose a function to call based on the type of the argument. This should serve to illustrate what I think float128 support for such macros should look like: common macros such as __MATH_TG may need different definitions depending on whether float128 is supported in glibc, so that the individual macros themselves do not need conditionals on float128 support. Tested for x86_64, x86, mips64 and powerpc. * math/math.h (__MATH_TG): New macro. [__USE_ISOC99] (fpclassify): Define using __MATH_TG. [__USE_ISOC99] (signbit): Likewise. [__USE_ISOC99] (isfinite): Likewise. [__USE_ISOC99] (isnan): Likewise. [__USE_ISOC99] (isinf): Likewise. [__GLIBC_USE (IEC_60559_BFP_EXT)] (issignaling): Likewise. [__GLIBC_USE (IEC_60559_BFP_EXT)] (__MATH_EVAL_FMT2): New macro. [__GLIBC_USE (IEC_60559_BFP_EXT)] (iseqsig): Define using __MATH_TG and __MATH_EVAL_FMT2. * sysdeps/generic/math_private.h (fabs_tg): Define using __MATH_TG. * sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h [!__NO_LONG_DOUBLE_MATH] (__iscanonicalf): New macro. [!__NO_LONG_DOUBLE_MATH] (__iscanonical): Likewise. [!__NO_LONG_DOUBLE_MATH] (iscanonical): Define using __MATH_TG. * sysdeps/ieee754/ldbl-96/bits/iscanonical.h (__iscanonicalf): New macro. (__iscanonical): Likewise. (iscanonical): Define using __MATH_TG.
This commit is contained in:
parent
0a557c105c
commit
b4e75104b4
23
ChangeLog
23
ChangeLog
@ -1,3 +1,26 @@
|
||||
2016-11-10 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* math/math.h (__MATH_TG): New macro.
|
||||
[__USE_ISOC99] (fpclassify): Define using __MATH_TG.
|
||||
[__USE_ISOC99] (signbit): Likewise.
|
||||
[__USE_ISOC99] (isfinite): Likewise.
|
||||
[__USE_ISOC99] (isnan): Likewise.
|
||||
[__USE_ISOC99] (isinf): Likewise.
|
||||
[__GLIBC_USE (IEC_60559_BFP_EXT)] (issignaling): Likewise.
|
||||
[__GLIBC_USE (IEC_60559_BFP_EXT)] (__MATH_EVAL_FMT2): New macro.
|
||||
[__GLIBC_USE (IEC_60559_BFP_EXT)] (iseqsig): Define using
|
||||
__MATH_TG and __MATH_EVAL_FMT2.
|
||||
* sysdeps/generic/math_private.h (fabs_tg): Define using
|
||||
__MATH_TG.
|
||||
* sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h
|
||||
[!__NO_LONG_DOUBLE_MATH] (__iscanonicalf): New macro.
|
||||
[!__NO_LONG_DOUBLE_MATH] (__iscanonical): Likewise.
|
||||
[!__NO_LONG_DOUBLE_MATH] (iscanonical): Define using __MATH_TG.
|
||||
* sysdeps/ieee754/ldbl-96/bits/iscanonical.h (__iscanonicalf): New
|
||||
macro.
|
||||
(__iscanonical): Likewise.
|
||||
(iscanonical): Define using __MATH_TG.
|
||||
|
||||
2016-11-10 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
* sysdeps/unix/sysv/linux/sh/kernel-features.h: Add include
|
||||
|
125
math/math.h
125
math/math.h
@ -199,6 +199,27 @@ extern int signgam;
|
||||
#endif
|
||||
|
||||
|
||||
/* Depending on the type of TG_ARG, call an appropriately suffixed
|
||||
version of FUNC with arguments (including parentheses) ARGS.
|
||||
Suffixed functions may not exist for long double if it has the same
|
||||
format as double, or for other types with the same format as float,
|
||||
double or long double. The behavior is undefined if the argument
|
||||
does not have a real floating type. The definition may use a
|
||||
conditional expression, so all suffixed versions of FUNC must
|
||||
return the same type (FUNC may include a cast if necessary rather
|
||||
than being a single identifier). */
|
||||
#ifdef __NO_LONG_DOUBLE_MATH
|
||||
# define __MATH_TG(TG_ARG, FUNC, ARGS) \
|
||||
(sizeof (TG_ARG) == sizeof (float) ? FUNC ## f ARGS : FUNC ARGS)
|
||||
#else
|
||||
# define __MATH_TG(TG_ARG, FUNC, ARGS) \
|
||||
(sizeof (TG_ARG) == sizeof (float) \
|
||||
? FUNC ## f ARGS \
|
||||
: sizeof (TG_ARG) == sizeof (double) \
|
||||
? FUNC ARGS \
|
||||
: FUNC ## l ARGS)
|
||||
#endif
|
||||
|
||||
/* ISO C99 defines some generic macros which work on any data type. */
|
||||
#ifdef __USE_ISOC99
|
||||
|
||||
@ -231,49 +252,22 @@ enum
|
||||
&& !defined __OPTIMIZE_SIZE__
|
||||
# define fpclassify(x) __builtin_fpclassify (FP_NAN, FP_INFINITE, \
|
||||
FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x)
|
||||
# elif defined __NO_LONG_DOUBLE_MATH
|
||||
# define fpclassify(x) \
|
||||
(sizeof (x) == sizeof (float) ? __fpclassifyf (x) : __fpclassify (x))
|
||||
# else
|
||||
# define fpclassify(x) \
|
||||
(sizeof (x) == sizeof (float) \
|
||||
? __fpclassifyf (x) \
|
||||
: sizeof (x) == sizeof (double) \
|
||||
? __fpclassify (x) : __fpclassifyl (x))
|
||||
# define fpclassify(x) __MATH_TG ((x), __fpclassify, (x))
|
||||
# endif
|
||||
|
||||
/* Return nonzero value if sign of X is negative. */
|
||||
# if __GNUC_PREREQ (4,0)
|
||||
# define signbit(x) \
|
||||
(sizeof (x) == sizeof (float) \
|
||||
? __builtin_signbitf (x) \
|
||||
: sizeof (x) == sizeof (double) \
|
||||
? __builtin_signbit (x) : __builtin_signbitl (x))
|
||||
# define signbit(x) __MATH_TG ((x), __builtin_signbit, (x))
|
||||
# else
|
||||
# ifdef __NO_LONG_DOUBLE_MATH
|
||||
# define signbit(x) \
|
||||
(sizeof (x) == sizeof (float) ? __signbitf (x) : __signbit (x))
|
||||
# else
|
||||
# define signbit(x) \
|
||||
(sizeof (x) == sizeof (float) \
|
||||
? __signbitf (x) \
|
||||
: sizeof (x) == sizeof (double) \
|
||||
? __signbit (x) : __signbitl (x))
|
||||
# endif
|
||||
# define signbit(x) __MATH_TG ((x), __signbit, (x))
|
||||
# endif
|
||||
|
||||
/* Return nonzero value if X is not +-Inf or NaN. */
|
||||
# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__
|
||||
# define isfinite(x) __builtin_isfinite (x)
|
||||
# elif defined __NO_LONG_DOUBLE_MATH
|
||||
# define isfinite(x) \
|
||||
(sizeof (x) == sizeof (float) ? __finitef (x) : __finite (x))
|
||||
# else
|
||||
# define isfinite(x) \
|
||||
(sizeof (x) == sizeof (float) \
|
||||
? __finitef (x) \
|
||||
: sizeof (x) == sizeof (double) \
|
||||
? __finite (x) : __finitel (x))
|
||||
# define isfinite(x) __MATH_TG ((x), __finite, (x))
|
||||
# endif
|
||||
|
||||
/* Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */
|
||||
@ -287,29 +281,15 @@ enum
|
||||
we already have this functions `__isnan' and it is faster. */
|
||||
# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__
|
||||
# define isnan(x) __builtin_isnan (x)
|
||||
# elif defined __NO_LONG_DOUBLE_MATH
|
||||
# define isnan(x) \
|
||||
(sizeof (x) == sizeof (float) ? __isnanf (x) : __isnan (x))
|
||||
# else
|
||||
# define isnan(x) \
|
||||
(sizeof (x) == sizeof (float) \
|
||||
? __isnanf (x) \
|
||||
: sizeof (x) == sizeof (double) \
|
||||
? __isnan (x) : __isnanl (x))
|
||||
# define isnan(x) __MATH_TG ((x), __isnan, (x))
|
||||
# endif
|
||||
|
||||
/* Return nonzero value if X is positive or negative infinity. */
|
||||
# if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__
|
||||
# define isinf(x) __builtin_isinf_sign (x)
|
||||
# elif defined __NO_LONG_DOUBLE_MATH
|
||||
# define isinf(x) \
|
||||
(sizeof (x) == sizeof (float) ? __isinff (x) : __isinf (x))
|
||||
# else
|
||||
# define isinf(x) \
|
||||
(sizeof (x) == sizeof (float) \
|
||||
? __isinff (x) \
|
||||
: sizeof (x) == sizeof (double) \
|
||||
? __isinf (x) : __isinfl (x))
|
||||
# define isinf(x) __MATH_TG ((x), __isinf, (x))
|
||||
# endif
|
||||
|
||||
/* Bitmasks for the math_errhandling macro. */
|
||||
@ -329,16 +309,7 @@ enum
|
||||
# include <bits/iscanonical.h>
|
||||
|
||||
/* Return nonzero value if X is a signaling NaN. */
|
||||
# ifdef __NO_LONG_DOUBLE_MATH
|
||||
# define issignaling(x) \
|
||||
(sizeof (x) == sizeof (float) ? __issignalingf (x) : __issignaling (x))
|
||||
# else
|
||||
# define issignaling(x) \
|
||||
(sizeof (x) == sizeof (float) \
|
||||
? __issignalingf (x) \
|
||||
: sizeof (x) == sizeof (double) \
|
||||
? __issignaling (x) : __issignalingl (x))
|
||||
# endif
|
||||
# define issignaling(x) __MATH_TG ((x), __issignaling, (x))
|
||||
|
||||
/* Return nonzero value if X is subnormal. */
|
||||
# define issubnormal(x) (fpclassify (x) == FP_SUBNORMAL)
|
||||
@ -555,36 +526,20 @@ extern int matherr (struct exception *__exc);
|
||||
#endif
|
||||
|
||||
#if __GLIBC_USE (IEC_60559_BFP_EXT)
|
||||
/* An expression whose type has the widest of the evaluation formats
|
||||
of X and Y (which are of floating-point types). */
|
||||
# if __FLT_EVAL_METHOD__ == 2 || __FLT_EVAL_METHOD__ > 64
|
||||
# define __MATH_EVAL_FMT2(x, y) ((x) + (y) + 0.0L)
|
||||
# elif __FLT_EVAL_METHOD__ == 1 || __FLT_EVAL_METHOD__ > 32
|
||||
# define __MATH_EVAL_FMT2(x, y) ((x) + (y) + 0.0)
|
||||
# else
|
||||
# define __MATH_EVAL_FMT2(x, y) ((x) + (y))
|
||||
# endif
|
||||
|
||||
/* Return X == Y but raising "invalid" and setting errno if X or Y is
|
||||
a NaN. */
|
||||
# ifdef __NO_LONG_DOUBLE_MATH
|
||||
# if (__FLT_EVAL_METHOD__ == 1 \
|
||||
|| __FLT_EVAL_METHOD__ == 2 \
|
||||
|| __FLT_EVAL_METHOD__ > 32)
|
||||
# define iseqsig(x, y) __iseqsig ((x), (y))
|
||||
# else
|
||||
# define iseqsig(x, y) \
|
||||
(sizeof ((x) + (y)) == sizeof (float) \
|
||||
? __iseqsigf ((x), (y)) \
|
||||
: __iseqsig ((x), (y)))
|
||||
# endif
|
||||
# else
|
||||
# if __FLT_EVAL_METHOD__ == 2 || __FLT_EVAL_METHOD__ > 64
|
||||
# define iseqsig(x, y) __iseqsigl ((x), (y))
|
||||
# elif __FLT_EVAL_METHOD__ == 1 || __FLT_EVAL_METHOD__ > 32
|
||||
# define iseqsig(x, y) \
|
||||
(sizeof ((x) + (y)) <= sizeof (double) \
|
||||
? __iseqsig ((x), (y)) \
|
||||
: __iseqsigl ((x), (y)))
|
||||
# else
|
||||
# define iseqsig(x, y) \
|
||||
(sizeof ((x) + (y)) == sizeof (float) \
|
||||
? __iseqsigf ((x), (y)) \
|
||||
: sizeof ((x) + (y)) == sizeof (double) \
|
||||
? __iseqsig ((x), (y)) \
|
||||
: __iseqsigl ((x), (y)))
|
||||
# endif
|
||||
# endif
|
||||
# define iseqsig(x, y) \
|
||||
__MATH_TG (__MATH_EVAL_FMT2 (x, y), __iseqsig, ((x), (y)))
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
@ -427,12 +427,7 @@ extern long double __lgamma_productl (long double t, long double x,
|
||||
})
|
||||
#endif
|
||||
|
||||
#define fabs_tg(x) __builtin_choose_expr \
|
||||
(__builtin_types_compatible_p (__typeof (x), float), \
|
||||
__builtin_fabsf (x), \
|
||||
__builtin_choose_expr \
|
||||
(__builtin_types_compatible_p (__typeof (x), double), \
|
||||
__builtin_fabs (x), __builtin_fabsl (x)))
|
||||
#define fabs_tg(x) __MATH_TG ((x), (__typeof (x)) __builtin_fabs, (x))
|
||||
#define min_of_type(type) __builtin_choose_expr \
|
||||
(__builtin_types_compatible_p (type, float), \
|
||||
FLT_MIN, \
|
||||
|
@ -25,6 +25,8 @@
|
||||
#else
|
||||
extern int __iscanonicall (long double __x)
|
||||
__THROW __attribute__ ((__const__));
|
||||
# define __iscanonicalf(x) ((void) (__typeof (x)) (x), 1)
|
||||
# define __iscanonical(x) ((void) (__typeof (x)) (x), 1)
|
||||
|
||||
/* Return nonzero value if X is canonical. In IEEE interchange binary
|
||||
formats, all values are canonical, but the argument must still be
|
||||
@ -32,8 +34,5 @@ extern int __iscanonicall (long double __x)
|
||||
conversion, before being discarded; in IBM long double, there are
|
||||
encodings that are not consistently handled as corresponding to any
|
||||
particular value of the type, and we return 0 for those. */
|
||||
# define iscanonical(x) \
|
||||
(sizeof (x) == sizeof (long double) \
|
||||
? __iscanonicall (x) \
|
||||
: ((void) (__typeof (x)) (x), 1))
|
||||
# define iscanonical(x) __MATH_TG ((x), __iscanonical, (x))
|
||||
#endif
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
extern int __iscanonicall (long double __x)
|
||||
__THROW __attribute__ ((__const__));
|
||||
#define __iscanonicalf(x) ((void) (__typeof (x)) (x), 1)
|
||||
#define __iscanonical(x) ((void) (__typeof (x)) (x), 1)
|
||||
|
||||
/* Return nonzero value if X is canonical. In IEEE interchange binary
|
||||
formats, all values are canonical, but the argument must still be
|
||||
@ -29,7 +31,4 @@ extern int __iscanonicall (long double __x)
|
||||
conversion, before being discarded; in extended precision, there
|
||||
are encodings that are not consistently handled as corresponding to
|
||||
any particular value of the type, and we return 0 for those. */
|
||||
#define iscanonical(x) \
|
||||
(sizeof (x) == sizeof (long double) \
|
||||
? __iscanonicall (x) \
|
||||
: ((void) (__typeof (x)) (x), 1))
|
||||
#define iscanonical(x) __MATH_TG ((x), __iscanonical, (x))
|
||||
|
Loading…
Reference in New Issue
Block a user