On Wed, 22 Jun 2016, Bill Schmidt wrote:

> Hi Joseph,
> 
> That's indeed preferable for the long term -- given how close we are to the 
> cutoff for 6.2, though, I'm worried about adding any new dependencies for 
> getting this upstream.  I'd suggest that we go ahead with reviewing this 
> patch in the short term, and I'll be happy to work with you later on getting
> the impedance matching right when they become arch-neutral.

The architecture-independent built-in functions really aren't hard.  See 
this patch, on top of my main _FloatN / _FloatNx patch.  (Not written up 
or fully regression-tested, and I want to add more test coverage, but it 
seems to work.)  To keep this patch minimal I didn't include updates to a 
few case statements only needed for optimization, e.g. in 
tree_call_nonnegative_warnv_p, but when those are changed you get 
optimizations automatically for these functions that would be harder to 
get with anything architecture-specific.

Regarding your patch:

(a) for GCC 6 (supposing my patch is used for trunk), it's missing 
documentation for the new functions (this patch has documentation for the 
architecture-independent functions);

(b) for trunk, having an insn pattern infkf1 for a built-in function that 
loads a constant is not appropriate (other insn patterns to optimize the 
architecture-independent built-in functions may well be appropriate).  
Rather, if there is a particularly efficient way of generating code to 
load a certain constant, the back end should be set up to use that way 
whenever that constant occurs (more generally, whenever any constant to 
which that efficient way applies occurs) - including for example when it 
occurs from folding arithmetic, say (__float128) __builtin_inff (), not 
just from __builtin_inff128 ().

diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
index 7fab9f8..468313c4 100644
--- a/gcc/builtin-types.def
+++ b/gcc/builtin-types.def
@@ -76,6 +76,27 @@ DEF_PRIMITIVE_TYPE (BT_UNWINDWORD, 
(*lang_hooks.types.type_for_mode)
 DEF_PRIMITIVE_TYPE (BT_FLOAT, float_type_node)
 DEF_PRIMITIVE_TYPE (BT_DOUBLE, double_type_node)
 DEF_PRIMITIVE_TYPE (BT_LONGDOUBLE, long_double_type_node)
+DEF_PRIMITIVE_TYPE (BT_FLOAT16, (float16_type_node
+                                ? float16_type_node
+                                : error_mark_node))
+DEF_PRIMITIVE_TYPE (BT_FLOAT32, (float32_type_node
+                                ? float32_type_node
+                                : error_mark_node))
+DEF_PRIMITIVE_TYPE (BT_FLOAT64, (float64_type_node
+                                ? float64_type_node
+                                : error_mark_node))
+DEF_PRIMITIVE_TYPE (BT_FLOAT128, (float128_type_node
+                                 ? float128_type_node
+                                 : error_mark_node))
+DEF_PRIMITIVE_TYPE (BT_FLOAT32X, (float32x_type_node
+                                 ? float32x_type_node
+                                 : error_mark_node))
+DEF_PRIMITIVE_TYPE (BT_FLOAT64X, (float64x_type_node
+                                 ? float64x_type_node
+                                 : error_mark_node))
+DEF_PRIMITIVE_TYPE (BT_FLOAT128X, (float128x_type_node
+                                  ? float128x_type_node
+                                  : error_mark_node))
 DEF_PRIMITIVE_TYPE (BT_COMPLEX_FLOAT, complex_float_type_node)
 DEF_PRIMITIVE_TYPE (BT_COMPLEX_DOUBLE, complex_double_type_node)
 DEF_PRIMITIVE_TYPE (BT_COMPLEX_LONGDOUBLE, complex_long_double_type_node)
@@ -146,6 +167,13 @@ DEF_FUNCTION_TYPE_0 (BT_FN_DOUBLE, BT_DOUBLE)
    distinguish it from two types in sequence, "long" followed by
    "double".  */
 DEF_FUNCTION_TYPE_0 (BT_FN_LONGDOUBLE, BT_LONGDOUBLE)
+DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT16, BT_FLOAT16)
+DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT32, BT_FLOAT32)
+DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT64, BT_FLOAT64)
+DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT128, BT_FLOAT128)
+DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT32X, BT_FLOAT32X)
+DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT64X, BT_FLOAT64X)
+DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT128X, BT_FLOAT128X)
 DEF_FUNCTION_TYPE_0 (BT_FN_DFLOAT32, BT_DFLOAT32)
 DEF_FUNCTION_TYPE_0 (BT_FN_DFLOAT64, BT_DFLOAT64)
 DEF_FUNCTION_TYPE_0 (BT_FN_DFLOAT128, BT_DFLOAT128)
@@ -157,6 +185,13 @@ DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_FLOAT, BT_FLOAT, BT_FLOAT)
 DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_DOUBLE, BT_DOUBLE, BT_DOUBLE)
 DEF_FUNCTION_TYPE_1 (BT_FN_LONGDOUBLE_LONGDOUBLE,
                     BT_LONGDOUBLE, BT_LONGDOUBLE)
+DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT16_FLOAT16, BT_FLOAT16, BT_FLOAT16)
+DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT32_FLOAT32, BT_FLOAT32, BT_FLOAT32)
+DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT64_FLOAT64, BT_FLOAT64, BT_FLOAT64)
+DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT128_FLOAT128, BT_FLOAT128, BT_FLOAT128)
+DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT32X_FLOAT32X, BT_FLOAT32X, BT_FLOAT32X)
+DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT64X_FLOAT64X, BT_FLOAT64X, BT_FLOAT64X)
+DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT128X_FLOAT128X, BT_FLOAT128X, BT_FLOAT128X)
 DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT,
                     BT_COMPLEX_FLOAT, BT_COMPLEX_FLOAT)
 DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE,
@@ -208,6 +243,13 @@ DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_CONST_STRING, BT_FLOAT, 
BT_CONST_STRING)
 DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_CONST_STRING, BT_DOUBLE, BT_CONST_STRING)
 DEF_FUNCTION_TYPE_1 (BT_FN_LONGDOUBLE_CONST_STRING,
                     BT_LONGDOUBLE, BT_CONST_STRING)
+DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT16_CONST_STRING, BT_FLOAT16, BT_CONST_STRING)
+DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT32_CONST_STRING, BT_FLOAT32, BT_CONST_STRING)
+DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT64_CONST_STRING, BT_FLOAT64, BT_CONST_STRING)
+DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT128_CONST_STRING, BT_FLOAT128, BT_CONST_STRING)
+DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT32X_CONST_STRING, BT_FLOAT32X, BT_CONST_STRING)
+DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT64X_CONST_STRING, BT_FLOAT64X, BT_CONST_STRING)
+DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT128X_CONST_STRING, BT_FLOAT128X, 
BT_CONST_STRING)
 DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT32_CONST_STRING, BT_DFLOAT32, BT_CONST_STRING)
 DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT64_CONST_STRING, BT_DFLOAT64, BT_CONST_STRING)
 DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT128_CONST_STRING,
@@ -271,6 +313,20 @@ DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_DOUBLE,
                     BT_DOUBLE, BT_DOUBLE, BT_DOUBLE)
 DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE,
                     BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE)
+DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT16_FLOAT16_FLOAT16,
+                    BT_FLOAT16, BT_FLOAT16, BT_FLOAT16)
+DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT32_FLOAT32_FLOAT32,
+                    BT_FLOAT32, BT_FLOAT32, BT_FLOAT32)
+DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT64_FLOAT64_FLOAT64,
+                    BT_FLOAT64, BT_FLOAT64, BT_FLOAT64)
+DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT128_FLOAT128_FLOAT128,
+                    BT_FLOAT128, BT_FLOAT128, BT_FLOAT128)
+DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT32X_FLOAT32X_FLOAT32X,
+                    BT_FLOAT32X, BT_FLOAT32X, BT_FLOAT32X)
+DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT64X_FLOAT64X_FLOAT64X,
+                    BT_FLOAT64X, BT_FLOAT64X, BT_FLOAT64X)
+DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT128X_FLOAT128X_FLOAT128X,
+                    BT_FLOAT128X, BT_FLOAT128X, BT_FLOAT128X)
 DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_FLOATPTR,
                     BT_FLOAT, BT_FLOAT, BT_FLOAT_PTR)
 DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_DOUBLEPTR,
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 5d234a5..f8ec9cf 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5761,6 +5761,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, 
machine_mode mode,
   switch (fcode)
     {
     CASE_FLT_FN (BUILT_IN_FABS):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
     case BUILT_IN_FABSD32:
     case BUILT_IN_FABSD64:
     case BUILT_IN_FABSD128:
@@ -5770,6 +5771,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, 
machine_mode mode,
       break;
 
     CASE_FLT_FN (BUILT_IN_COPYSIGN):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_COPYSIGN):
       target = expand_builtin_copysign (exp, target, subtarget);
       if (target)
        return target;
@@ -8094,12 +8096,14 @@ fold_builtin_0 (location_t loc, tree fndecl)
       return fold_builtin_LINE (loc, type);
 
     CASE_FLT_FN (BUILT_IN_INF):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_INF):
     case BUILT_IN_INFD32:
     case BUILT_IN_INFD64:
     case BUILT_IN_INFD128:
       return fold_builtin_inf (loc, type, true);
 
     CASE_FLT_FN (BUILT_IN_HUGE_VAL):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_HUGE_VAL):
       return fold_builtin_inf (loc, type, false);
 
     case BUILT_IN_CLASSIFY_TYPE:
@@ -8148,6 +8152,7 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0)
       return fold_builtin_strlen (loc, type, arg0);
 
     CASE_FLT_FN (BUILT_IN_FABS):
+    CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
     case BUILT_IN_FABSD32:
     case BUILT_IN_FABSD64:
     case BUILT_IN_FABSD128:
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 33a7626..814ca15 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -87,6 +87,19 @@ along with GCC; see the file COPYING3.  If not see
   DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, BT_LAST,     \
               false, false, false, ATTRS, true, true)
 
+/* A set of GCC builtins for _FloatN and _FloatNx types.  TYPE_MACRO
+   is called with an argument such as FLOAT32 to produce the enum
+   value for the type.  */
+#undef DEF_GCC_FLOATN_NX_BUILTINS
+#define DEF_GCC_FLOATN_NX_BUILTINS(ENUM, NAME, TYPE_MACRO, ATTRS)      \
+  DEF_GCC_BUILTIN (ENUM ## F16, NAME "f16", TYPE_MACRO (FLOAT16), ATTRS) \
+  DEF_GCC_BUILTIN (ENUM ## F32, NAME "f32", TYPE_MACRO (FLOAT32), ATTRS) \
+  DEF_GCC_BUILTIN (ENUM ## F64, NAME "f64", TYPE_MACRO (FLOAT64), ATTRS) \
+  DEF_GCC_BUILTIN (ENUM ## F128, NAME "f128", TYPE_MACRO (FLOAT128), ATTRS) \
+  DEF_GCC_BUILTIN (ENUM ## F32X, NAME "f32x", TYPE_MACRO (FLOAT32X), ATTRS) \
+  DEF_GCC_BUILTIN (ENUM ## F64X, NAME "f64x", TYPE_MACRO (FLOAT64X), ATTRS) \
+  DEF_GCC_BUILTIN (ENUM ## F128X, NAME "f128x", TYPE_MACRO (FLOAT128X), ATTRS)
+
 /* A library builtin (like __builtin_strchr) is a builtin equivalent
    of an ANSI/ISO standard library function.  In addition to the
    `__builtin' version, we will create an ordinary version (e.g,
@@ -296,6 +309,9 @@ DEF_C99_C90RES_BUILTIN (BUILT_IN_CEILL, "ceill", 
BT_FN_LONGDOUBLE_LONGDOUBLE, AT
 DEF_C99_BUILTIN        (BUILT_IN_COPYSIGN, "copysign", 
BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_COPYSIGNF, "copysignf", 
BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_COPYSIGNL, "copysignl", 
BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#define COPYSIGN_TYPE(F) BT_FN_##F##_##F##_##F
+DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_COPYSIGN, "copysign", COPYSIGN_TYPE, 
ATTR_CONST_NOTHROW_LEAF_LIST)
+#undef COPYSIGN_TYPE
 DEF_LIB_BUILTIN        (BUILT_IN_COS, "cos", BT_FN_DOUBLE_DOUBLE, 
ATTR_MATHFN_FPROUNDING)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_COSF, "cosf", BT_FN_FLOAT_FLOAT, 
ATTR_MATHFN_FPROUNDING)
 DEF_LIB_BUILTIN        (BUILT_IN_COSH, "cosh", BT_FN_DOUBLE_DOUBLE, 
ATTR_MATHFN_FPROUNDING_ERRNO)
@@ -326,6 +342,9 @@ DEF_C99_BUILTIN        (BUILT_IN_EXPM1L, "expm1l", 
BT_FN_LONGDOUBLE_LONGDOUBLE,
 DEF_LIB_BUILTIN        (BUILT_IN_FABS, "fabs", BT_FN_DOUBLE_DOUBLE, 
ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSF, "fabsf", BT_FN_FLOAT_FLOAT, 
ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSL, "fabsl", BT_FN_LONGDOUBLE_LONGDOUBLE, 
ATTR_CONST_NOTHROW_LEAF_LIST)
+#define FABS_TYPE(F) BT_FN_##F##_##F
+DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_FABS, "fabs", FABS_TYPE, 
ATTR_CONST_NOTHROW_LEAF_LIST)
+#undef FABS_TYPE
 DEF_GCC_BUILTIN        (BUILT_IN_FABSD32, "fabsd32", BT_FN_DFLOAT32_DFLOAT32, 
ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_FABSD64, "fabsd64", BT_FN_DFLOAT64_DFLOAT64, 
ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_FABSD128, "fabsd128", 
BT_FN_DFLOAT128_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
@@ -359,6 +378,8 @@ DEF_EXT_LIB_BUILTIN    (BUILT_IN_GAMMAL_R, "gammal_r", 
BT_FN_LONGDOUBLE_LONGDOUB
 DEF_GCC_BUILTIN        (BUILT_IN_HUGE_VAL, "huge_val", BT_FN_DOUBLE, 
ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_HUGE_VALF, "huge_valf", BT_FN_FLOAT, 
ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_HUGE_VALL, "huge_vall", BT_FN_LONGDOUBLE, 
ATTR_CONST_NOTHROW_LEAF_LIST)
+#define INF_TYPE(F) BT_FN_##F
+DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_HUGE_VAL, "huge_val", INF_TYPE, 
ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_HYPOT, "hypot", BT_FN_DOUBLE_DOUBLE_DOUBLE, 
ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_BUILTIN        (BUILT_IN_HYPOTF, "hypotf", BT_FN_FLOAT_FLOAT_FLOAT, 
ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_C99_BUILTIN        (BUILT_IN_HYPOTL, "hypotl", 
BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
@@ -374,6 +395,8 @@ DEF_C99_BUILTIN        (BUILT_IN_ILOGBL, "ilogbl", 
BT_FN_INT_LONGDOUBLE, ATTR_MA
 DEF_GCC_BUILTIN        (BUILT_IN_INF, "inf", BT_FN_DOUBLE, 
ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_INFF, "inff", BT_FN_FLOAT, 
ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_INFL, "infl", BT_FN_LONGDOUBLE, 
ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_INF, "inf", INF_TYPE, 
ATTR_CONST_NOTHROW_LEAF_LIST)
+#undef INF_TYPE
 DEF_GCC_BUILTIN               (BUILT_IN_INFD32, "infd32", BT_FN_DFLOAT32, 
ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_INFD64, "infd64", BT_FN_DFLOAT64, 
ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_INFD128, "infd128", BT_FN_DFLOAT128, 
ATTR_CONST_NOTHROW_LEAF_LIST)
@@ -446,12 +469,16 @@ DEF_C99_C90RES_BUILTIN (BUILT_IN_MODFL, "modfl", 
BT_FN_LONGDOUBLE_LONGDOUBLE_LON
 DEF_C99_BUILTIN        (BUILT_IN_NAN, "nan", BT_FN_DOUBLE_CONST_STRING, 
ATTR_CONST_NOTHROW_NONNULL)
 DEF_C99_BUILTIN        (BUILT_IN_NANF, "nanf", BT_FN_FLOAT_CONST_STRING, 
ATTR_CONST_NOTHROW_NONNULL)
 DEF_C99_BUILTIN        (BUILT_IN_NANL, "nanl", BT_FN_LONGDOUBLE_CONST_STRING, 
ATTR_CONST_NOTHROW_NONNULL)
+#define NAN_TYPE(F) BT_FN_##F##_CONST_STRING
+DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_NAN, "nan", NAN_TYPE, 
ATTR_CONST_NOTHROW_NONNULL)
 DEF_GCC_BUILTIN        (BUILT_IN_NAND32, "nand32", 
BT_FN_DFLOAT32_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
 DEF_GCC_BUILTIN        (BUILT_IN_NAND64, "nand64", 
BT_FN_DFLOAT64_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
 DEF_GCC_BUILTIN        (BUILT_IN_NAND128, "nand128", 
BT_FN_DFLOAT128_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
 DEF_GCC_BUILTIN        (BUILT_IN_NANS, "nans", BT_FN_DOUBLE_CONST_STRING, 
ATTR_CONST_NOTHROW_NONNULL)
 DEF_GCC_BUILTIN        (BUILT_IN_NANSF, "nansf", BT_FN_FLOAT_CONST_STRING, 
ATTR_CONST_NOTHROW_NONNULL)
 DEF_GCC_BUILTIN        (BUILT_IN_NANSL, "nansl", 
BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
+DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_NANS, "nans", NAN_TYPE, 
ATTR_CONST_NOTHROW_NONNULL)
+#undef NAN_TYPE
 DEF_C99_BUILTIN        (BUILT_IN_NEARBYINT, "nearbyint", BT_FN_DOUBLE_DOUBLE, 
ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_NEARBYINTF, "nearbyintf", BT_FN_FLOAT_FLOAT, 
ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_NEARBYINTL, "nearbyintl", 
BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index c61ece9..0cd7b1e 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -10811,6 +10811,13 @@ that are recognized in any mode since ISO C90 reserves 
these names for
 the purpose to which ISO C99 puts them.  All these functions have
 corresponding versions prefixed with @code{__builtin_}.
 
+There are also built-in functions @code{__builtin_fabsf@var{n}},
+@code{__builtin_fabsf@var{n}x}, @code{__builtin_copysignf@var{n}} and
+@code{__builtin_copysignf@var{n}x}, corresponding to the TS 18661-3
+functions @code{fabsf@var{n}}, @code{fabsf@var{n}x},
+@code{copysignf@var{n}} and @code{copysignf@var{n}x}, for supported
+types @code{_Float@var{n}} and @code{_Float@var{n}x}.
+
 There are also GNU extension functions @code{clog10}, @code{clog10f} and
 @code{clog10l} which names are reserved by ISO C99 for future use.
 All these functions have versions prefixed with @code{__builtin_}.
@@ -11349,6 +11356,16 @@ Similar to @code{__builtin_huge_val}, except the return
 type is @code{long double}.
 @end deftypefn
 
+@deftypefn {Built-in Function} _Float@var{n} __builtin_huge_valf@var{n} (void)
+Similar to @code{__builtin_huge_val}, except the return type is
+@code{_Float@var{n}}.
+@end deftypefn
+
+@deftypefn {Built-in Function} _Float@var{n}x __builtin_huge_valf@var{n}x 
(void)
+Similar to @code{__builtin_huge_val}, except the return type is
+@code{_Float@var{n}x}.
+@end deftypefn
+
 @deftypefn {Built-in Function} int __builtin_fpclassify (int, int, int, int, 
int, ...)
 This built-in implements the C99 fpclassify functionality.  The first
 five int arguments should be the target library's notion of the
@@ -11387,6 +11404,16 @@ Similar to @code{__builtin_inf}, except the return
 type is @code{long double}.
 @end deftypefn
 
+@deftypefn {Built-in Function} _Float@var{n} __builtin_inff@var{n} (void)
+Similar to @code{__builtin_inf}, except the return
+type is @code{_Float@var{n}}.
+@end deftypefn
+
+@deftypefn {Built-in Function} _Float@var{n} __builtin_inff@var{n}x (void)
+Similar to @code{__builtin_inf}, except the return
+type is @code{_Float@var{n}x}.
+@end deftypefn
+
 @deftypefn {Built-in Function} int __builtin_isinf_sign (...)
 Similar to @code{isinf}, except the return value is -1 for
 an argument of @code{-Inf} and 1 for an argument of @code{+Inf}.
@@ -11433,6 +11460,16 @@ Similar to @code{__builtin_nan}, except the return 
type is @code{float}.
 Similar to @code{__builtin_nan}, except the return type is @code{long double}.
 @end deftypefn
 
+@deftypefn {Built-in Function} _Float@var{n} __builtin_nanf@var{n} (const char 
*str)
+Similar to @code{__builtin_nan}, except the return type is
+@code{_Float@var{n}}.
+@end deftypefn
+
+@deftypefn {Built-in Function} _Float@var{n}x __builtin_nanf@var{n}x (const 
char *str)
+Similar to @code{__builtin_nan}, except the return type is
+@code{_Float@var{n}x}.
+@end deftypefn
+
 @deftypefn {Built-in Function} double __builtin_nans (const char *str)
 Similar to @code{__builtin_nan}, except the significand is forced
 to be a signaling NaN@.  The @code{nans} function is proposed by
@@ -11447,6 +11484,16 @@ Similar to @code{__builtin_nans}, except the return 
type is @code{float}.
 Similar to @code{__builtin_nans}, except the return type is @code{long double}.
 @end deftypefn
 
+@deftypefn {Built-in Function} _Float@var{n} __builtin_nansf@var{n} (const 
char *str)
+Similar to @code{__builtin_nans}, except the return type is
+@code{_Float@var{n}}.
+@end deftypefn
+
+@deftypefn {Built-in Function} _Float@var{n}x __builtin_nansf@var{n}x (const 
char *str)
+Similar to @code{__builtin_nans}, except the return type is
+@code{_Float@var{n}x}.
+@end deftypefn
+
 @deftypefn {Built-in Function} int __builtin_ffs (int x)
 Returns one plus the index of the least significant 1-bit of @var{x}, or
 if @var{x} is zero, returns zero.
diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c
index 923a5d4..2bbc887 100644
--- a/gcc/fold-const-call.c
+++ b/gcc/fold-const-call.c
@@ -1131,12 +1131,14 @@ fold_const_call (combined_fn fn, tree type, tree arg)
       return NULL_TREE;
 
     CASE_CFN_NAN:
+    CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NAN):
     case CFN_BUILT_IN_NAND32:
     case CFN_BUILT_IN_NAND64:
     case CFN_BUILT_IN_NAND128:
       return fold_const_builtin_nan (type, arg, true);
 
     CASE_CFN_NANS:
+    CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NANS):
       return fold_const_builtin_nan (type, arg, false);
 
     default:
diff --git a/gcc/testsuite/gcc.dg/torture/float128-builtin.c 
b/gcc/testsuite/gcc.dg/torture/float128-builtin.c
new file mode 100644
index 0000000..2f4936f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float128-builtin.c
@@ -0,0 +1,8 @@
+/* Test _Float128 built-in functions.  */
+/* { dg-do run } */
+/* { dg-require-effective-target float128 } */
+/* { dg-options "" } */
+
+#define WIDTH 128
+#define EXT 0
+#include "floatn-builtin.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float128x-builtin.c 
b/gcc/testsuite/gcc.dg/torture/float128x-builtin.c
new file mode 100644
index 0000000..33ceeec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float128x-builtin.c
@@ -0,0 +1,8 @@
+/* Test _Float128x built-in functions.  */
+/* { dg-do run } */
+/* { dg-require-effective-target float128x } */
+/* { dg-options "" } */
+
+#define WIDTH 128
+#define EXT 1
+#include "floatn-builtin.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float16-builtin.c 
b/gcc/testsuite/gcc.dg/torture/float16-builtin.c
new file mode 100644
index 0000000..2a043fc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float16-builtin.c
@@ -0,0 +1,8 @@
+/* Test _Float16 built-in functions.  */
+/* { dg-do run } */
+/* { dg-require-effective-target float16 } */
+/* { dg-options "" } */
+
+#define WIDTH 16
+#define EXT 0
+#include "floatn-builtin.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float32-builtin.c 
b/gcc/testsuite/gcc.dg/torture/float32-builtin.c
new file mode 100644
index 0000000..25c7072
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float32-builtin.c
@@ -0,0 +1,8 @@
+/* Test _Float32 built-in functions.  */
+/* { dg-do run } */
+/* { dg-require-effective-target float32 } */
+/* { dg-options "" } */
+
+#define WIDTH 32
+#define EXT 0
+#include "floatn-builtin.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float32x-builtin.c 
b/gcc/testsuite/gcc.dg/torture/float32x-builtin.c
new file mode 100644
index 0000000..63f23e5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float32x-builtin.c
@@ -0,0 +1,8 @@
+/* Test _Float32x built-in functions.  */
+/* { dg-do run } */
+/* { dg-require-effective-target float32x } */
+/* { dg-options "" } */
+
+#define WIDTH 32
+#define EXT 1
+#include "floatn-builtin.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float64-builtin.c 
b/gcc/testsuite/gcc.dg/torture/float64-builtin.c
new file mode 100644
index 0000000..8e8c123
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float64-builtin.c
@@ -0,0 +1,8 @@
+/* Test _Float64 built-in functions.  */
+/* { dg-do run } */
+/* { dg-require-effective-target float64 } */
+/* { dg-options "" } */
+
+#define WIDTH 64
+#define EXT 0
+#include "floatn-builtin.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float64x-builtin.c 
b/gcc/testsuite/gcc.dg/torture/float64x-builtin.c
new file mode 100644
index 0000000..4d91c4b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float64x-builtin.c
@@ -0,0 +1,8 @@
+/* Test _Float64x built-in functions.  */
+/* { dg-do run } */
+/* { dg-require-effective-target float64x } */
+/* { dg-options "" } */
+
+#define WIDTH 64
+#define EXT 1
+#include "floatn-builtin.h"
diff --git a/gcc/testsuite/gcc.dg/torture/floatn-builtin.h 
b/gcc/testsuite/gcc.dg/torture/floatn-builtin.h
new file mode 100644
index 0000000..c562812
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/floatn-builtin.h
@@ -0,0 +1,64 @@
+/* Tests for _FloatN / _FloatNx types: compile and execution tests for
+   built-in functions.  Before including this file, define WIDTH as
+   the value N; define EXT to 1 for _FloatNx and 0 for _FloatN.  */
+
+#define CONCATX(X, Y) X ## Y
+#define CONCAT(X, Y) CONCATX (X, Y)
+#define CONCAT3(X, Y, Z) CONCAT (CONCAT (X, Y), Z)
+#define CONCAT4(W, X, Y, Z) CONCAT (CONCAT (CONCAT (W, X), Y), Z)
+
+#if EXT
+# define TYPE CONCAT3 (_Float, WIDTH, x)
+# define CST(C) CONCAT4 (C, f, WIDTH, x)
+# define FN(F) CONCAT4 (F, f, WIDTH, x)
+#else
+# define TYPE CONCAT (_Float, WIDTH)
+# define CST(C) CONCAT3 (C, f, WIDTH)
+# define FN(F) CONCAT3 (F, f, WIDTH)
+#endif
+
+extern void exit (int);
+extern void abort (void);
+
+extern TYPE test_type;
+extern __typeof (FN (__builtin_inf) ()) test_type;
+extern __typeof (FN (__builtin_huge_val) ()) test_type;
+extern __typeof (FN (__builtin_nan) ("")) test_type;
+extern __typeof (FN (__builtin_nans) ("")) test_type;
+extern __typeof (FN (__builtin_fabs) (0)) test_type;
+extern __typeof (FN (__builtin_copysign) (0, 0)) test_type;
+
+volatile TYPE inf_cst = FN (__builtin_inf) ();
+volatile TYPE huge_val_cst = FN (__builtin_huge_val) ();
+volatile TYPE nan_cst = FN (__builtin_nan) ("");
+volatile TYPE nans_cst = FN (__builtin_nans) ("");
+volatile TYPE neg0 = -CST (0.0), neg1 = -CST (1.0), one = 1.0;
+
+int
+main (void)
+{
+  volatile TYPE r;
+  if (!__builtin_isinf (inf_cst))
+    abort ();
+  if (!__builtin_isinf (huge_val_cst))
+    abort ();
+  if (inf_cst != huge_val_cst)
+    abort ();
+  if (!__builtin_isnan (nan_cst))
+    abort ();
+  if (!__builtin_isnan (nans_cst))
+    abort ();
+  r = FN (__builtin_fabs) (neg1);
+  if (r != CST (1.0))
+    abort ();
+  r = FN (__builtin_copysign) (one, neg0);
+  if (r != neg1)
+    abort ();
+  r = FN (__builtin_copysign) (inf_cst, neg1);
+  if (r != -huge_val_cst)
+    abort ();
+  r = FN (__builtin_copysign) (-inf_cst, one);
+  if (r != huge_val_cst)
+    abort ();
+  exit (0);
+}
diff --git a/gcc/tree.h b/gcc/tree.h
index acb8bf1..db6fbcf 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -234,6 +234,9 @@ as_internal_fn (combined_fn code)
 /* Helper macros for math builtins.  */
 
 #define CASE_FLT_FN(FN) case FN: case FN##F: case FN##L
+#define CASE_FLT_FN_FLOATN_NX(FN)                         \
+  case FN##F16: case FN##F32: case FN##F64: case FN##F128: \
+  case FN##F32X: case FN##F64X: case FN##F128X
 #define CASE_FLT_FN_REENT(FN) case FN##_R: case FN##F_R: case FN##L_R
 #define CASE_INT_FN(FN) case FN: case FN##L: case FN##LL: case FN##IMAX
 
@@ -3617,11 +3620,16 @@ tree_operand_check_code (const_tree __t, enum tree_code 
__code, int __i,
 #define FLOATN_NX_TYPE_NODE(IDX)       global_trees[TI_FLOATN_NX_TYPE_FIRST + 
(IDX)]
 #define FLOATNX_TYPE_NODE(IDX)         global_trees[TI_FLOATNX_TYPE_FIRST + 
(IDX)]
 
-/* Names for individual types, where required by back ends
-   (architecture-independent code should always iterate over all such
-   types).  */
+/* Names for individual types (code should normally iterate over all
+   such types; these are only for back-end use, or in contexts such as
+   *.def where iteration if not possible).  */
+#define float16_type_node              global_trees[TI_FLOAT16_TYPE]
+#define float32_type_node              global_trees[TI_FLOAT32_TYPE]
+#define float64_type_node              global_trees[TI_FLOAT64_TYPE]
 #define float128_type_node             global_trees[TI_FLOAT128_TYPE]
+#define float32x_type_node             global_trees[TI_FLOAT32X_TYPE]
 #define float64x_type_node             global_trees[TI_FLOAT64X_TYPE]
+#define float128x_type_node            global_trees[TI_FLOAT128X_TYPE]
 
 #define float_ptr_type_node            global_trees[TI_FLOAT_PTR_TYPE]
 #define double_ptr_type_node           global_trees[TI_DOUBLE_PTR_TYPE]

-- 
Joseph S. Myers
jos...@codesourcery.com

Reply via email to