aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog23
-rw-r--r--NEWS8
-rwxr-xr-xmath/gen-tgmath-tests.py18
-rw-r--r--math/tgmath.h151
4 files changed, 160 insertions, 40 deletions
diff --git a/ChangeLog b/ChangeLog
index a6fbb36..8334e48 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 ba3e77b..84c69bf 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 31a3bd2..04492cd 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 7afe41e..f75e3dc 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). */