diff options
-rw-r--r-- | ChangeLog | 23 | ||||
-rw-r--r-- | NEWS | 8 | ||||
-rwxr-xr-x | math/gen-tgmath-tests.py | 18 | ||||
-rw-r--r-- | math/tgmath.h | 151 |
4 files changed, 160 insertions, 40 deletions
diff --git a/ChangeLog b/ChangeLog index a6fbb36ac1..8334e48c13 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,28 @@ 2017-06-28 Joseph Myers <joseph@codesourcery.com> + * math/tgmath.h: Include <bits/libc-header-start.h> and + <bits/floatn.h>. + (__TGMATH_F128): New macro. + (__TGMATH_CF128): Likewise. + (__TGMATH_UNARY_REAL_ONLY): Use __TGMATH_F128. + (__TGMATH_UNARY_REAL_RET_ONLY): Likewise. + (__TGMATH_BINARY_FIRST_REAL_ONLY): Likewise. + (__TGMATH_BINARY_FIRST_REAL_STD_ONLY): New macro. + (__TGMATH_BINARY_REAL_ONLY): Use __TGMATH_F128. + (__TGMATH_BINARY_REAL_STD_ONLY): New macro. + (__TGMATH_BINARY_REAL_RET_ONLY): Use __TGMATH_F128. + (__TGMATH_TERNARY_FIRST_SECOND_REAL_ONLY): Likewise. + (__TGMATH_TERNARY_REAL_ONLY): Likewise. + (__TGMATH_TERNARY_FIRST_REAL_RET_ONLY): Likewise. + (__TGMATH_UNARY_REAL_IMAG): Use __TGMATH_CF128. + (__TGMATH_UNARY_IMAG): Use __TGMATH_F128. + (__TGMATH_UNARY_REAL_IMAG_RET_REAL): Use __TGMATH_CF128. + (__TGMATH_BINARY_REAL_IMAG): Likewise. + (nexttoward): Use __TGMATH_BINARY_FIRST_REAL_STD_ONLY. + [__USE_MISC] (scalb): Use __TGMATH_BINARY_REAL_STD_ONLY. + * math/gen-tgmath-tests.py (Type.init_types): Enable _FloatN and + _FloatNx types if the corresponding HUGE_VAL macros are defined. + * math/tgmath.h [__USE_GNU] (log10): Use clog10 not __clog10. * math/gen-tgmath-tests.py (Tests.add_all_tests): Test log10 for complex arguments. diff --git a/NEWS b/NEWS index ba3e77b66a..84c69bf056 100644 --- a/NEWS +++ b/NEWS @@ -135,10 +135,10 @@ Version 2.26 * Support is added, on powerpc64le, x86_64, x86 and ia64, for interfaces supporting the _Float128 type from ISO/IEC TS 18661-3:2015. Most of the interfaces are taken from TS 18661-3. The type-generic macros in <math.h> - support this type, but those in <tgmath.h> do not. The GNU C Library now - requires GCC 6.2 or later to build for powerpc64le. When used with GCC - versions before GCC 7, these interfaces may be used with the type under - the non-standard name __float128. + and <tgmath.h> support this type. The GNU C Library now requires GCC 6.2 + or later to build for powerpc64le. When used with GCC versions before GCC + 7, these interfaces may be used with the type under the non-standard name + __float128. New <stdlib.h> functions from ISO/IEC TS 18661-3: diff --git a/math/gen-tgmath-tests.py b/math/gen-tgmath-tests.py index 31a3bd2e2c..04492cd3d5 100755 --- a/math/gen-tgmath-tests.py +++ b/math/gen-tgmath-tests.py @@ -165,25 +165,25 @@ class Type(object): """Initialize all the known types.""" Type.create_type('_Float16', 'f16', 'FLT16_MANT_DIG', complex_name='__CFLOAT16', - condition='0', order=(0, 0)) + condition='defined HUGE_VAL_F16', order=(0, 0)) Type.create_type('float', 'f', 'FLT_MANT_DIG', order=(1, 1)) Type.create_type('_Float32', 'f32', 'FLT32_MANT_DIG', complex_name='__CFLOAT32', - condition='0', order=(2, 2)) + condition='defined HUGE_VAL_F32', order=(2, 2)) Type.create_type('_Float32x', 'f32x', 'FLT32X_MANT_DIG', complex_name='__CFLOAT32X', - condition='0', order=(3, 3)) + condition='defined HUGE_VAL_F32X', order=(3, 3)) Type.create_type('double', '', 'DBL_MANT_DIG', order=(4, 4)) Type.create_type('long double', 'l', 'LDBL_MANT_DIG', order=(5, 7)) Type.create_type('_Float64', 'f64', 'FLT64_MANT_DIG', complex_name='__CFLOAT64', - condition='0', order=(6, 5)) + condition='defined HUGE_VAL_F64', order=(6, 5)) Type.create_type('_Float64x', 'f64x', 'FLT64X_MANT_DIG', complex_name='__CFLOAT64X', - condition='0', order=(7, 6)) + condition='defined HUGE_VAL_F64X', order=(7, 6)) Type.create_type('_Float128', 'f128', 'FLT128_MANT_DIG', complex_name='__CFLOAT128', - condition='0', order=(8, 8)) + condition='defined HUGE_VAL_F128', order=(8, 8)) Type.create_type('char', integer=True) Type.create_type('signed char', integer=True) Type.create_type('unsigned char', integer=True) @@ -202,10 +202,12 @@ class Type(object): # whether long double has the same format as double. Type.create_type('long_double_Float64', 'LDBL_MANT_DIG', complex_name='complex_long_double_Float64', - condition='0', order=(6, 7), internal=True) + condition='defined HUGE_VAL_F64', order=(6, 7), + internal=True) Type.create_type('long_double_Float64x', 'FLT64X_MANT_DIG', complex_name='complex_long_double_Float64x', - condition='0', order=(7, 7), internal=True) + condition='defined HUGE_VAL_F64X', order=(7, 7), + internal=True) @staticmethod def can_combine_types(types): diff --git a/math/tgmath.h b/math/tgmath.h index 7afe41e859..f75e3dca78 100644 --- a/math/tgmath.h +++ b/math/tgmath.h @@ -22,7 +22,11 @@ #ifndef _TGMATH_H #define _TGMATH_H 1 +#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION +#include <bits/libc-header-start.h> + /* Include the needed headers. */ +#include <bits/floatn.h> #include <math.h> #include <complex.h> @@ -66,6 +70,23 @@ __tgmath_real_type_sub (__typeof__ ((__typeof__ (expr)) 0), \ __floating_type (__typeof__ (expr))) +/* Expand to text that checks if ARG_COMB has type _Float128, and if + so calls the appropriately suffixed FCT (which may include a cast), + or FCT and CFCT for complex functions, with arguments ARG_CALL. */ +# if __HAVE_FLOAT128 && __GLIBC_USE (IEC_60559_TYPES_EXT) +# define __TGMATH_F128(arg_comb, fct, arg_call) \ + __builtin_types_compatible_p (__typeof (arg_comb), _Float128) \ + ? fct ## f128 arg_call : +# define __TGMATH_CF128(arg_comb, fct, cfct, arg_call) \ + __builtin_types_compatible_p (__typeof (__real__ (arg_comb)), _Float128) \ + ? (sizeof (__real__ (arg_comb)) == sizeof (arg_comb) \ + ? fct ## f128 arg_call \ + : cfct ## f128 arg_call) : +# else +# define __TGMATH_F128(arg_comb, fct, arg_call) /* Nothing. */ +# define __TGMATH_CF128(arg_comb, fct, cfct, arg_call) /* Nothing. */ +# endif + /* We have two kinds of generic macros: to support functions which are only defined on real valued parameters and those which are defined @@ -76,7 +97,9 @@ ? (__tgmath_real_type (Val)) Fct (Val) \ : (sizeof (Val) == sizeof (float)) \ ? (__tgmath_real_type (Val)) Fct##f (Val) \ - : (__tgmath_real_type (Val)) __tgml(Fct) (Val))) + : __TGMATH_F128 ((Val), (__tgmath_real_type (Val)) Fct, \ + (Val)) \ + (__tgmath_real_type (Val)) __tgml(Fct) (Val))) # define __TGMATH_UNARY_REAL_RET_ONLY(Val, Fct) \ (__extension__ ((sizeof (Val) == sizeof (double) \ @@ -84,7 +107,8 @@ ? Fct (Val) \ : (sizeof (Val) == sizeof (float)) \ ? Fct##f (Val) \ - : __tgml(Fct) (Val))) + : __TGMATH_F128 ((Val), Fct, (Val)) \ + __tgml(Fct) (Val))) # define __TGMATH_BINARY_FIRST_REAL_ONLY(Val1, Val2, Fct) \ (__extension__ ((sizeof (Val1) == sizeof (double) \ @@ -92,14 +116,47 @@ ? (__tgmath_real_type (Val1)) Fct (Val1, Val2) \ : (sizeof (Val1) == sizeof (float)) \ ? (__tgmath_real_type (Val1)) Fct##f (Val1, Val2) \ + : __TGMATH_F128 ((Val1), (__tgmath_real_type (Val1)) Fct, \ + (Val1, Val2)) \ + (__tgmath_real_type (Val1)) __tgml(Fct) (Val1, Val2))) + +# define __TGMATH_BINARY_FIRST_REAL_STD_ONLY(Val1, Val2, Fct) \ + (__extension__ ((sizeof (Val1) == sizeof (double) \ + || __builtin_classify_type (Val1) != 8) \ + ? (__tgmath_real_type (Val1)) Fct (Val1, Val2) \ + : (sizeof (Val1) == sizeof (float)) \ + ? (__tgmath_real_type (Val1)) Fct##f (Val1, Val2) \ : (__tgmath_real_type (Val1)) __tgml(Fct) (Val1, Val2))) # define __TGMATH_BINARY_REAL_ONLY(Val1, Val2, Fct) \ (__extension__ (((sizeof (Val1) > sizeof (double) \ || sizeof (Val2) > sizeof (double)) \ && __builtin_classify_type ((Val1) + (Val2)) == 8) \ + ? __TGMATH_F128 ((Val1) + (Val2), \ + (__typeof \ + ((__tgmath_real_type (Val1)) 0 \ + + (__tgmath_real_type (Val2)) 0)) Fct, \ + (Val1, Val2)) \ + (__typeof ((__tgmath_real_type (Val1)) 0 \ + + (__tgmath_real_type (Val2)) 0)) \ + __tgml(Fct) (Val1, Val2) \ + : (sizeof (Val1) == sizeof (double) \ + || sizeof (Val2) == sizeof (double) \ + || __builtin_classify_type (Val1) != 8 \ + || __builtin_classify_type (Val2) != 8) \ ? (__typeof ((__tgmath_real_type (Val1)) 0 \ + (__tgmath_real_type (Val2)) 0)) \ + Fct (Val1, Val2) \ + : (__typeof ((__tgmath_real_type (Val1)) 0 \ + + (__tgmath_real_type (Val2)) 0)) \ + Fct##f (Val1, Val2))) + +# define __TGMATH_BINARY_REAL_STD_ONLY(Val1, Val2, Fct) \ + (__extension__ (((sizeof (Val1) > sizeof (double) \ + || sizeof (Val2) > sizeof (double)) \ + && __builtin_classify_type ((Val1) + (Val2)) == 8) \ + ? (__typeof ((__tgmath_real_type (Val1)) 0 \ + + (__tgmath_real_type (Val2)) 0)) \ __tgml(Fct) (Val1, Val2) \ : (sizeof (Val1) == sizeof (double) \ || sizeof (Val2) == sizeof (double) \ @@ -116,7 +173,8 @@ (__extension__ (((sizeof (Val1) > sizeof (double) \ || sizeof (Val2) > sizeof (double)) \ && __builtin_classify_type ((Val1) + (Val2)) == 8) \ - ? __tgml(Fct) (Val1, Val2) \ + ? __TGMATH_F128 ((Val1) + (Val2), Fct, (Val1, Val2)) \ + __tgml(Fct) (Val1, Val2) \ : (sizeof (Val1) == sizeof (double) \ || sizeof (Val2) == sizeof (double) \ || __builtin_classify_type (Val1) != 8 \ @@ -128,9 +186,14 @@ (__extension__ (((sizeof (Val1) > sizeof (double) \ || sizeof (Val2) > sizeof (double)) \ && __builtin_classify_type ((Val1) + (Val2)) == 8) \ - ? (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0)) \ - __tgml(Fct) (Val1, Val2, Val3) \ + ? __TGMATH_F128 ((Val1) + (Val2), \ + (__typeof \ + ((__tgmath_real_type (Val1)) 0 \ + + (__tgmath_real_type (Val2)) 0)) Fct, \ + (Val1, Val2, Val3)) \ + (__typeof ((__tgmath_real_type (Val1)) 0 \ + + (__tgmath_real_type (Val2)) 0)) \ + __tgml(Fct) (Val1, Val2, Val3) \ : (sizeof (Val1) == sizeof (double) \ || sizeof (Val2) == sizeof (double) \ || __builtin_classify_type (Val1) != 8 \ @@ -148,9 +211,15 @@ || sizeof (Val3) > sizeof (double)) \ && __builtin_classify_type ((Val1) + (Val2) + (Val3)) \ == 8) \ - ? (__typeof ((__tgmath_real_type (Val1)) 0 \ - + (__tgmath_real_type (Val2)) 0 \ - + (__tgmath_real_type (Val3)) 0)) \ + ? __TGMATH_F128 ((Val1) + (Val2) + (Val3), \ + (__typeof \ + ((__tgmath_real_type (Val1)) 0 \ + + (__tgmath_real_type (Val2)) 0 \ + + (__tgmath_real_type (Val3)) 0)) Fct, \ + (Val1, Val2, Val3)) \ + (__typeof ((__tgmath_real_type (Val1)) 0 \ + + (__tgmath_real_type (Val2)) 0 \ + + (__tgmath_real_type (Val3)) 0)) \ __tgml(Fct) (Val1, Val2, Val3) \ : (sizeof (Val1) == sizeof (double) \ || sizeof (Val2) == sizeof (double) \ @@ -173,7 +242,8 @@ ? Fct (Val1, Val2, Val3) \ : (sizeof (Val1) == sizeof (float)) \ ? Fct##f (Val1, Val2, Val3) \ - : __tgml(Fct) (Val1, Val2, Val3))) + : __TGMATH_F128 ((Val1), Fct, (Val1, Val2, Val3)) \ + __tgml(Fct) (Val1, Val2, Val3))) /* XXX This definition has to be changed as soon as the compiler understands the imaginary keyword. */ @@ -187,9 +257,12 @@ ? ((sizeof (__real__ (Val)) == sizeof (Val)) \ ? (__tgmath_real_type (Val)) Fct##f (Val) \ : (__tgmath_real_type (Val)) Cfct##f (Val)) \ - : ((sizeof (__real__ (Val)) == sizeof (Val)) \ - ? (__tgmath_real_type (Val)) __tgml(Fct) (Val) \ - : (__tgmath_real_type (Val)) __tgml(Cfct) (Val)))) + : __TGMATH_CF128 ((Val), (__tgmath_real_type (Val)) Fct, \ + (__tgmath_real_type (Val)) Cfct, \ + (Val)) \ + ((sizeof (__real__ (Val)) == sizeof (Val)) \ + ? (__tgmath_real_type (Val)) __tgml(Fct) (Val) \ + : (__tgmath_real_type (Val)) __tgml(Cfct) (Val)))) # define __TGMATH_UNARY_IMAG(Val, Cfct) \ (__extension__ ((sizeof (__real__ (Val)) == sizeof (double) \ @@ -199,8 +272,12 @@ : (sizeof (__real__ (Val)) == sizeof (float)) \ ? (__typeof__ ((__tgmath_real_type (Val)) 0 \ + _Complex_I)) Cfct##f (Val) \ - : (__typeof__ ((__tgmath_real_type (Val)) 0 \ - + _Complex_I)) __tgml(Cfct) (Val))) + : __TGMATH_F128 (__real__ (Val), \ + (__typeof__ \ + ((__tgmath_real_type (Val)) 0 \ + + _Complex_I)) Cfct, (Val)) \ + (__typeof__ ((__tgmath_real_type (Val)) 0 \ + + _Complex_I)) __tgml(Cfct) (Val))) /* XXX This definition has to be changed as soon as the compiler understands the imaginary keyword. */ @@ -218,11 +295,19 @@ Fct##f (Val) \ : (__typeof__ (__real__ (__tgmath_real_type (Val)) 0))\ Cfct##f (Val)) \ - : ((sizeof (__real__ (Val)) == sizeof (Val)) \ - ? (__typeof__ (__real__ (__tgmath_real_type (Val)) 0))\ - __tgml(Fct) (Val) \ - : (__typeof__ (__real__ (__tgmath_real_type (Val)) 0))\ - __tgml(Cfct) (Val)))) + : __TGMATH_CF128 ((Val), \ + (__typeof__ \ + (__real__ \ + (__tgmath_real_type (Val)) 0)) Fct, \ + (__typeof__ \ + (__real__ \ + (__tgmath_real_type (Val)) 0)) Cfct, \ + (Val)) \ + ((sizeof (__real__ (Val)) == sizeof (Val)) \ + ? (__typeof__ (__real__ (__tgmath_real_type (Val)) 0)) \ + __tgml(Fct) (Val) \ + : (__typeof__ (__real__ (__tgmath_real_type (Val)) 0)) \ + __tgml(Cfct) (Val)))) /* XXX This definition has to be changed as soon as the compiler understands the imaginary keyword. */ @@ -231,14 +316,24 @@ || sizeof (__real__ (Val2)) > sizeof (double)) \ && __builtin_classify_type (__real__ (Val1) \ + __real__ (Val2)) == 8) \ - ? ((sizeof (__real__ (Val1)) == sizeof (Val1) \ - && sizeof (__real__ (Val2)) == sizeof (Val2)) \ - ? (__typeof ((__tgmath_real_type (Val1)) 0 \ + ? __TGMATH_CF128 ((Val1) + (Val2), \ + (__typeof \ + ((__tgmath_real_type (Val1)) 0 \ + + (__tgmath_real_type (Val2)) 0)) \ + Fct, \ + (__typeof \ + ((__tgmath_real_type (Val1)) 0 \ + + (__tgmath_real_type (Val2)) 0)) \ + Cfct, \ + (Val1, Val2)) \ + ((sizeof (__real__ (Val1)) == sizeof (Val1) \ + && sizeof (__real__ (Val2)) == sizeof (Val2)) \ + ? (__typeof ((__tgmath_real_type (Val1)) 0 \ + (__tgmath_real_type (Val2)) 0)) \ - __tgml(Fct) (Val1, Val2) \ - : (__typeof ((__tgmath_real_type (Val1)) 0 \ + __tgml(Fct) (Val1, Val2) \ + : (__typeof ((__tgmath_real_type (Val1)) 0 \ + (__tgmath_real_type (Val2)) 0)) \ - __tgml(Cfct) (Val1, Val2)) \ + __tgml(Cfct) (Val1, Val2)) \ : (sizeof (__real__ (Val1)) == sizeof (double) \ || sizeof (__real__ (Val2)) == sizeof (double) \ || __builtin_classify_type (__real__ (Val1)) != 8 \ @@ -422,14 +517,14 @@ /* Return X + epsilon if X < Y, X - epsilon if X > Y. */ #define nextafter(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, nextafter) #define nexttoward(Val1, Val2) \ - __TGMATH_BINARY_FIRST_REAL_ONLY (Val1, Val2, nexttoward) + __TGMATH_BINARY_FIRST_REAL_STD_ONLY (Val1, Val2, nexttoward) /* Return the remainder of integer divison X / Y with infinite precision. */ #define remainder(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, remainder) /* Return X times (2 to the Nth power). */ #ifdef __USE_MISC -# define scalb(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, scalb) +# define scalb(Val1, Val2) __TGMATH_BINARY_REAL_STD_ONLY (Val1, Val2, scalb) #endif /* Return X times (2 to the Nth power). */ |