about summary refs log tree commit diff
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 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).  */