public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-3354] libstdc++: Partial library support for std::float{16, 32, 64, 128}_t and std::bfloat16_t
@ 2022-10-18  9:43 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2022-10-18  9:43 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:a23225fb4f764dfc3e3e729c7d7238f03f282aaa

commit r13-3354-ga23225fb4f764dfc3e3e729c7d7238f03f282aaa
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Oct 18 11:37:13 2022 +0200

    libstdc++: Partial library support for std::float{16,32,64,128}_t and std::bfloat16_t
    
    The following patch is partial support for std::float{16,32,64,128}_t
    and std::bfloat16_t in libstdc++.
    https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1467r9.html
    says that <ostream>, <istream>, <charconv> and <complex>
    need changes toom, but that isn't implemented so far.
    In <cmath> the only thing missing I'm aware of is
    std::nextafter std::float16_t and std::bfloat16_t overloads (I think
    we probably need to implement that out of line somewhere, or inline? - might
    need inline asm barriers) and std::nexttoward overloads (those are
    intentional, you said there is a LWG issue about that).
    Also, this patch has the glibc 2.26+ std::float128_t support for platforms
    where long double isn't IEEE quad format temporarily disabled
    because it depends on
    https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603665.html
    changes which aren't in yet.
    
    The patch also doesn't include any testcases to cover the <type_traits>
    changes, it isn't clear to me where to put that.
    
    2022-10-18  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/106652
            * include/std/stdfloat: New file.
            * include/std/numbers (__glibcxx_numbers): Define and use it
            for __float128 explicit instantiations as well as
            _Float{16,32,64,128} and __gnu_cxx::__bfloat16_t.
            * include/std/atomic (atomic<_Float16>, atomic<_Float32>,
            atomic<_Float64>, atomic<_Float128>, atomic<__gnu_cxx::__bfloat16_t>):
            New explicit instantiations.
            * include/std/type_traits (__is_floating_point_helper<_Float16>,
            __is_floating_point_helper<_Float32>,
            __is_floating_point_helper<_Float64>,
            __is_floating_point_helper<_Float128>,
            __is_floating_point_helper<__gnu_cxx::__bfloat16_t>): Likewise.
            * include/std/limits (__glibcxx_concat3_, __glibcxx_concat3,
            __glibcxx_float_n): Define.
            (numeric_limits<_Float16>, numeric_limits<_Float32>,
            numeric_limits<_Float64>, numeric_limits<_Float128>,
            numeric_limits<__gnu_cxx::__bfloat16_t>): New explicit instantiations.
            * include/bits/std_abs.h (abs): New overloads for
            _Float{16,32,64,128} and __gnu_cxx::__bfloat16_t.
            * include/bits/c++config (_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128): Define
            if long double is IEEE quad.
            (__gnu_cxx::__bfloat16_t): New using.
            * include/c_global/cmath (acos, asin, atan, atan2, ceil, cos, cosh,
            exp, fabs, floor, fmod, frexp, ldexp, log, log10, modf, pow, sin,
            sinh, sqrt, tan, tanh, fpclassify, isfinite, isinf, isnan, isnormal,
            signbit, isgreater, isgreaterequal, isless, islessequal,
            islessgreater, isunordered, acosh, asinh, atanh, cbrt, copysign, erf,
            erfc, exp2, expm1, fdim, fma, fmax, fmin, hypot, ilogb, lgamma,
            llrint, llround, log1p, log2, logb, lrint, lround, nearbyint,
            nextafter, remainder, rint, round, scalbln, scalbn, tgamma, trunc,
            lerp): New overloads with _Float{16,32,64,128} or
            __gnu_cxx::__bfloat16_t types.
            * config/os/gnu-linux/os_defines.h (_GLIBCXX_HAVE_FLOAT128_MATH):
            Prepare for definition if glibc 2.26 and later implements *f128 APIs
            but comment out the actual definition for now.
            * include/ext/type_traits.h (__promote<_Float16>, __promote<_Float32>,
            __promote<_Float64>, __promote<_Float128>,
            __promote<__gnu_cxx::__bfloat16_t>): New specializations.
            * include/Makefile.am (std_headers): Add stdfloat.
            * include/Makefile.in: Regenerated.
            * include/precompiled/stdc++.h: Include stdfloat.
            * testsuite/18_support/headers/stdfloat/types_std.cc: New test.
            * testsuite/18_support/headers/limits/synopsis_cxx23.cc: New test.
            * testsuite/26_numerics/headers/cmath/c99_classification_macros_c++23.cc:
            New test.
            * testsuite/26_numerics/headers/cmath/functions_std_c++23.cc: New test.
            * testsuite/26_numerics/numbers/4.cc: New test.
            * testsuite/29_atomics/atomic_float/requirements_cxx23.cc: New test.

Diff:
---
 libstdc++-v3/config/os/gnu-linux/os_defines.h      |   11 +
 libstdc++-v3/include/Makefile.am                   |    1 +
 libstdc++-v3/include/Makefile.in                   |    1 +
 libstdc++-v3/include/bits/c++config                |   14 +
 libstdc++-v3/include/bits/std_abs.h                |   34 +
 libstdc++-v3/include/c_global/cmath                | 1883 +++++++++++++++++++-
 libstdc++-v3/include/ext/type_traits.h             |   30 +
 libstdc++-v3/include/precompiled/stdc++.h          |    1 +
 libstdc++-v3/include/std/atomic                    |   85 +
 libstdc++-v3/include/std/limits                    |  184 ++
 libstdc++-v3/include/std/numbers                   |  152 +-
 libstdc++-v3/include/std/stdfloat                  |   62 +
 libstdc++-v3/include/std/type_traits               |   30 +
 .../18_support/headers/limits/synopsis_cxx23.cc    |   43 +
 .../18_support/headers/stdfloat/types_std.cc       |   40 +
 .../cmath/c99_classification_macros_c++23.cc       |   96 +
 .../headers/cmath/functions_std_c++23.cc           |  146 ++
 libstdc++-v3/testsuite/26_numerics/numbers/4.cc    |  122 ++
 .../29_atomics/atomic_float/requirements_cxx23.cc  |  112 ++
 19 files changed, 2885 insertions(+), 162 deletions(-)

diff --git a/libstdc++-v3/config/os/gnu-linux/os_defines.h b/libstdc++-v3/config/os/gnu-linux/os_defines.h
index c0caa21a013..e5b640a0738 100644
--- a/libstdc++-v3/config/os/gnu-linux/os_defines.h
+++ b/libstdc++-v3/config/os/gnu-linux/os_defines.h
@@ -49,6 +49,17 @@
 // version dynamically in case it has changed since libstdc++ was configured.
 #define _GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC __GLIBC_PREREQ(2,23)
 
+// Glibc 2.26 on i?86/x86-64/ia64/ppc64le added *f128 support.
+// Glibc 2.27 added it also on many other arches but those have IEEE quad
+// long double.
+#if __GLIBC_PREREQ(2, 26) \
+    && (defined(__i386__) || defined(__x86_64__) || defined (__ia64__) \
+	|| (defined(__powerpc__) && defined(_ARCH_PWR8) \
+	    && defined(__LITTLE_ENDIAN__) && (_CALL_ELF == 2) \
+	    && defined(__FLOAT128__)))
+//# define _GLIBCXX_HAVE_FLOAT128_MATH 1
+#endif
+
 #if __GLIBC_PREREQ(2, 27)
 // Since glibc 2.27 pthread_self() is usable without linking to libpthread.
 # define _GLIBCXX_NATIVE_THREAD_ID pthread_self()
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 97542524a69..96137a6621a 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -95,6 +95,7 @@ std_headers = \
 	${std_srcdir}/stack \
 	${std_srcdir}/stacktrace \
 	${std_srcdir}/stdexcept \
+	${std_srcdir}/stdfloat \
 	${std_srcdir}/stop_token \
 	${std_srcdir}/streambuf \
 	${std_srcdir}/string \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 0a3a1e34491..dac77654bdf 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -452,6 +452,7 @@ std_freestanding = \
 @GLIBCXX_HOSTED_TRUE@	${std_srcdir}/stack \
 @GLIBCXX_HOSTED_TRUE@	${std_srcdir}/stacktrace \
 @GLIBCXX_HOSTED_TRUE@	${std_srcdir}/stdexcept \
+@GLIBCXX_HOSTED_TRUE@	${std_srcdir}/stdfloat \
 @GLIBCXX_HOSTED_TRUE@	${std_srcdir}/stop_token \
 @GLIBCXX_HOSTED_TRUE@	${std_srcdir}/streambuf \
 @GLIBCXX_HOSTED_TRUE@	${std_srcdir}/string \
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 191880fb99d..50406066afe 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -796,6 +796,20 @@ namespace std
 # define _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 1
 #endif
 
+// Define if long double has the IEEE binary128 format.
+#if __LDBL_MANT_DIG__ == 113 \
+  && __LDBL_MIN_EXP__ == -16381 \
+  && __LDBL_MAX_EXP__ == 16384
+# define _GLIBCXX_LDOUBLE_IS_IEEE_BINARY128 1
+#endif
+
+#ifdef __STDCPP_BFLOAT16_T__
+namespace __gnu_cxx
+{
+  using __bfloat16_t = decltype(0.0bf16);
+}
+#endif
+
 #ifdef __has_builtin
 # ifdef __is_identifier
 // Intel and older Clang require !__is_identifier for some built-ins:
diff --git a/libstdc++-v3/include/bits/std_abs.h b/libstdc++-v3/include/bits/std_abs.h
index c8d589d2b0a..3363e71fd66 100644
--- a/libstdc++-v3/include/bits/std_abs.h
+++ b/libstdc++-v3/include/bits/std_abs.h
@@ -97,6 +97,40 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; }
 #endif
 
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  constexpr _Float16
+  abs(_Float16 __x)
+  { return _Float16(__builtin_fabsf(__x)); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  constexpr _Float32
+  abs(_Float32 __x)
+  { return __builtin_fabsf(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  constexpr _Float64
+  abs(_Float64 __x)
+  { return __builtin_fabs(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+  constexpr _Float128
+  abs(_Float128 __x)
+  { return __builtin_fabsl(__x); }
+#elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
+  constexpr _Float128
+  abs(_Float128 __x)
+  { return __builtin_fabsf128(__x); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  constexpr __gnu_cxx::__bfloat16_t
+  abs(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_fabsf(__x)); }
+#endif
+
 #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
   __extension__ inline _GLIBCXX_CONSTEXPR
   __float128
diff --git a/libstdc++-v3/include/c_global/cmath b/libstdc++-v3/include/c_global/cmath
index cc14982d3bb..81635a03f7f 100644
--- a/libstdc++-v3/include/c_global/cmath
+++ b/libstdc++-v3/include/c_global/cmath
@@ -515,6 +515,564 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     tanh(_Tp __x)
     { return __builtin_tanh(__x); }
 
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  constexpr _Float16
+  acos(_Float16 __x)
+  { return _Float16(__builtin_acosf(__x)); }
+
+  constexpr _Float16
+  asin(_Float16 __x)
+  { return _Float16(__builtin_asinf(__x)); }
+
+  constexpr _Float16
+  atan(_Float16 __x)
+  { return _Float16(__builtin_atanf(__x)); }
+
+  constexpr _Float16
+  atan2(_Float16 __y, _Float16 __x)
+  { return _Float16(__builtin_atan2f(__y, __x)); }
+
+  constexpr _Float16
+  ceil(_Float16 __x)
+  { return _Float16(__builtin_ceilf(__x)); }
+
+  constexpr _Float16
+  cos(_Float16 __x)
+  { return _Float16(__builtin_cosf(__x)); }
+
+  constexpr _Float16
+  cosh(_Float16 __x)
+  { return _Float16(__builtin_coshf(__x)); }
+
+  constexpr _Float16
+  exp(_Float16 __x)
+  { return _Float16(__builtin_expf(__x)); }
+
+  constexpr _Float16
+  fabs(_Float16 __x)
+  { return _Float16(__builtin_fabsf(__x)); }
+
+  constexpr _Float16
+  floor(_Float16 __x)
+  { return _Float16(__builtin_floorf(__x)); }
+
+  constexpr _Float16
+  fmod(_Float16 __x, _Float16 __y)
+  { return _Float16(__builtin_fmodf(__x, __y)); }
+
+  inline _Float16
+  frexp(_Float16 __x, int* __exp)
+  { return _Float16(__builtin_frexpf(__x, __exp)); }
+
+  constexpr _Float16
+  ldexp(_Float16 __x, int __exp)
+  { return _Float16(__builtin_ldexpf(__x, __exp)); }
+
+  constexpr _Float16
+  log(_Float16 __x)
+  { return _Float16(__builtin_logf(__x)); }
+
+  constexpr _Float16
+  log10(_Float16 __x)
+  { return _Float16(__builtin_log10f(__x)); }
+
+  inline _Float16
+  modf(_Float16 __x, _Float16* __iptr)
+  {
+    float __i, __ret = __builtin_modff(__x, &__i);
+    *__iptr = _Float16(__i);
+    return _Float16(__ret);
+  }
+
+  constexpr _Float16
+  pow(_Float16 __x, _Float16 __y)
+  { return _Float16(__builtin_powf(__x, __y)); }
+
+  constexpr _Float16
+  sin(_Float16 __x)
+  { return _Float16(__builtin_sinf(__x)); }
+
+  constexpr _Float16
+  sinh(_Float16 __x)
+  { return _Float16(__builtin_sinhf(__x)); }
+
+  constexpr _Float16
+  sqrt(_Float16 __x)
+  { return _Float16(__builtin_sqrtf(__x)); }
+
+  constexpr _Float16
+  tan(_Float16 __x)
+  { return _Float16(__builtin_tanf(__x)); }
+
+  constexpr _Float16
+  tanh(_Float16 __x)
+  { return _Float16(__builtin_tanhf(__x)); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  constexpr _Float32
+  acos(_Float32 __x)
+  { return __builtin_acosf(__x); }
+
+  constexpr _Float32
+  asin(_Float32 __x)
+  { return __builtin_asinf(__x); }
+
+  constexpr _Float32
+  atan(_Float32 __x)
+  { return __builtin_atanf(__x); }
+
+  constexpr _Float32
+  atan2(_Float32 __y, _Float32 __x)
+  { return __builtin_atan2f(__y, __x); }
+
+  constexpr _Float32
+  ceil(_Float32 __x)
+  { return __builtin_ceilf(__x); }
+
+  constexpr _Float32
+  cos(_Float32 __x)
+  { return __builtin_cosf(__x); }
+
+  constexpr _Float32
+  cosh(_Float32 __x)
+  { return __builtin_coshf(__x); }
+
+  constexpr _Float32
+  exp(_Float32 __x)
+  { return __builtin_expf(__x); }
+
+  constexpr _Float32
+  fabs(_Float32 __x)
+  { return __builtin_fabsf(__x); }
+
+  constexpr _Float32
+  floor(_Float32 __x)
+  { return __builtin_floorf(__x); }
+
+  constexpr _Float32
+  fmod(_Float32 __x, _Float32 __y)
+  { return __builtin_fmodf(__x, __y); }
+
+  inline _Float32
+  frexp(_Float32 __x, int* __exp)
+  { return __builtin_frexpf(__x, __exp); }
+
+  constexpr _Float32
+  ldexp(_Float32 __x, int __exp)
+  { return __builtin_ldexpf(__x, __exp); }
+
+  constexpr _Float32
+  log(_Float32 __x)
+  { return __builtin_logf(__x); }
+
+  constexpr _Float32
+  log10(_Float32 __x)
+  { return __builtin_log10f(__x); }
+
+  inline _Float32
+  modf(_Float32 __x, _Float32* __iptr)
+  {
+    float __i, __ret = __builtin_modff(__x, &__i);
+    *__iptr = __i;
+    return __ret;
+  }
+
+  constexpr _Float32
+  pow(_Float32 __x, _Float32 __y)
+  { return __builtin_powf(__x, __y); }
+
+  constexpr _Float32
+  sin(_Float32 __x)
+  { return __builtin_sinf(__x); }
+
+  constexpr _Float32
+  sinh(_Float32 __x)
+  { return __builtin_sinhf(__x); }
+
+  constexpr _Float32
+  sqrt(_Float32 __x)
+  { return __builtin_sqrtf(__x); }
+
+  constexpr _Float32
+  tan(_Float32 __x)
+  { return __builtin_tanf(__x); }
+
+  constexpr _Float32
+  tanh(_Float32 __x)
+  { return __builtin_tanhf(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  constexpr _Float64
+  acos(_Float64 __x)
+  { return __builtin_acos(__x); }
+
+  constexpr _Float64
+  asin(_Float64 __x)
+  { return __builtin_asin(__x); }
+
+  constexpr _Float64
+  atan(_Float64 __x)
+  { return __builtin_atan(__x); }
+
+  constexpr _Float64
+  atan2(_Float64 __y, _Float64 __x)
+  { return __builtin_atan2(__y, __x); }
+
+  constexpr _Float64
+  ceil(_Float64 __x)
+  { return __builtin_ceil(__x); }
+
+  constexpr _Float64
+  cos(_Float64 __x)
+  { return __builtin_cos(__x); }
+
+  constexpr _Float64
+  cosh(_Float64 __x)
+  { return __builtin_cosh(__x); }
+
+  constexpr _Float64
+  exp(_Float64 __x)
+  { return __builtin_exp(__x); }
+
+  constexpr _Float64
+  fabs(_Float64 __x)
+  { return __builtin_fabs(__x); }
+
+  constexpr _Float64
+  floor(_Float64 __x)
+  { return __builtin_floor(__x); }
+
+  constexpr _Float64
+  fmod(_Float64 __x, _Float64 __y)
+  { return __builtin_fmod(__x, __y); }
+
+  inline _Float64
+  frexp(_Float64 __x, int* __exp)
+  { return __builtin_frexp(__x, __exp); }
+
+  constexpr _Float64
+  ldexp(_Float64 __x, int __exp)
+  { return __builtin_ldexp(__x, __exp); }
+
+  constexpr _Float64
+  log(_Float64 __x)
+  { return __builtin_log(__x); }
+
+  constexpr _Float64
+  log10(_Float64 __x)
+  { return __builtin_log10(__x); }
+
+  inline _Float64
+  modf(_Float64 __x, _Float64* __iptr)
+  {
+    double __i, __ret = __builtin_modf(__x, &__i);
+    *__iptr = __i;
+    return __ret;
+  }
+
+  constexpr _Float64
+  pow(_Float64 __x, _Float64 __y)
+  { return __builtin_pow(__x, __y); }
+
+  constexpr _Float64
+  sin(_Float64 __x)
+  { return __builtin_sin(__x); }
+
+  constexpr _Float64
+  sinh(_Float64 __x)
+  { return __builtin_sinh(__x); }
+
+  constexpr _Float64
+  sqrt(_Float64 __x)
+  { return __builtin_sqrt(__x); }
+
+  constexpr _Float64
+  tan(_Float64 __x)
+  { return __builtin_tan(__x); }
+
+  constexpr _Float64
+  tanh(_Float64 __x)
+  { return __builtin_tanh(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+  constexpr _Float128
+  acos(_Float128 __x)
+  { return __builtin_acosl(__x); }
+
+  constexpr _Float128
+  asin(_Float128 __x)
+  { return __builtin_asinl(__x); }
+
+  constexpr _Float128
+  atan(_Float128 __x)
+  { return __builtin_atanl(__x); }
+
+  constexpr _Float128
+  atan2(_Float128 __y, _Float128 __x)
+  { return __builtin_atan2l(__y, __x); }
+
+  constexpr _Float128
+  ceil(_Float128 __x)
+  { return __builtin_ceill(__x); }
+
+  constexpr _Float128
+  cos(_Float128 __x)
+  { return __builtin_cosl(__x); }
+
+  constexpr _Float128
+  cosh(_Float128 __x)
+  { return __builtin_coshl(__x); }
+
+  constexpr _Float128
+  exp(_Float128 __x)
+  { return __builtin_expl(__x); }
+
+  constexpr _Float128
+  fabs(_Float128 __x)
+  { return __builtin_fabsl(__x); }
+
+  constexpr _Float128
+  floor(_Float128 __x)
+  { return __builtin_floorl(__x); }
+
+  constexpr _Float128
+  fmod(_Float128 __x, _Float128 __y)
+  { return __builtin_fmodl(__x, __y); }
+
+  inline _Float128
+  frexp(_Float128 __x, int* __exp)
+  { return __builtin_frexpl(__x, __exp); }
+
+  constexpr _Float128
+  ldexp(_Float128 __x, int __exp)
+  { return __builtin_ldexpl(__x, __exp); }
+
+  constexpr _Float128
+  log(_Float128 __x)
+  { return __builtin_logl(__x); }
+
+  constexpr _Float128
+  log10(_Float128 __x)
+  { return __builtin_log10l(__x); }
+
+  inline _Float128
+  modf(_Float128 __x, _Float128* __iptr)
+  {
+    long double __i, __ret = __builtin_modfl(__x, &__i);
+    *__iptr = __i;
+    return __ret;
+  }
+
+  constexpr _Float128
+  pow(_Float128 __x, _Float128 __y)
+  { return __builtin_powl(__x, __y); }
+
+  constexpr _Float128
+  sin(_Float128 __x)
+  { return __builtin_sinl(__x); }
+
+  constexpr _Float128
+  sinh(_Float128 __x)
+  { return __builtin_sinhl(__x); }
+
+  constexpr _Float128
+  sqrt(_Float128 __x)
+  { return __builtin_sqrtl(__x); }
+
+  constexpr _Float128
+  tan(_Float128 __x)
+  { return __builtin_tanl(__x); }
+
+  constexpr _Float128
+  tanh(_Float128 __x)
+  { return __builtin_tanhl(__x); }
+#elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
+  constexpr _Float128
+  acos(_Float128 __x)
+  { return __builtin_acosf128(__x); }
+
+  constexpr _Float128
+  asin(_Float128 __x)
+  { return __builtin_asinf128(__x); }
+
+  constexpr _Float128
+  atan(_Float128 __x)
+  { return __builtin_atanf128(__x); }
+
+  constexpr _Float128
+  atan2(_Float128 __y, _Float128 __x)
+  { return __builtin_atan2f128(__y, __x); }
+
+  constexpr _Float128
+  ceil(_Float128 __x)
+  { return __builtin_ceilf128(__x); }
+
+  constexpr _Float128
+  cos(_Float128 __x)
+  { return __builtin_cosf128(__x); }
+
+  constexpr _Float128
+  cosh(_Float128 __x)
+  { return __builtin_coshf128(__x); }
+
+  constexpr _Float128
+  exp(_Float128 __x)
+  { return __builtin_expf128(__x); }
+
+  constexpr _Float128
+  fabs(_Float128 __x)
+  { return __builtin_fabsf128(__x); }
+
+  constexpr _Float128
+  floor(_Float128 __x)
+  { return __builtin_floorf128(__x); }
+
+  constexpr _Float128
+  fmod(_Float128 __x, _Float128 __y)
+  { return __builtin_fmodf128(__x, __y); }
+
+  inline _Float128
+  frexp(_Float128 __x, int* __exp)
+  { return __builtin_frexpf128(__x, __exp); }
+
+  constexpr _Float128
+  ldexp(_Float128 __x, int __exp)
+  { return __builtin_ldexpf128(__x, __exp); }
+
+  constexpr _Float128
+  log(_Float128 __x)
+  { return __builtin_logf128(__x); }
+
+  constexpr _Float128
+  log10(_Float128 __x)
+  { return __builtin_log10f128(__x); }
+
+  inline _Float128
+  modf(_Float128 __x, _Float128* __iptr)
+  { return __builtin_modff128(__x, __iptr); }
+
+  constexpr _Float128
+  pow(_Float128 __x, _Float128 __y)
+  { return __builtin_powf128(__x, __y); }
+
+  constexpr _Float128
+  sin(_Float128 __x)
+  { return __builtin_sinf128(__x); }
+
+  constexpr _Float128
+  sinh(_Float128 __x)
+  { return __builtin_sinhf128(__x); }
+
+  constexpr _Float128
+  sqrt(_Float128 __x)
+  { return __builtin_sqrtf128(__x); }
+
+  constexpr _Float128
+  tan(_Float128 __x)
+  { return __builtin_tanf128(__x); }
+
+  constexpr _Float128
+  tanh(_Float128 __x)
+  { return __builtin_tanhf128(__x); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  constexpr __gnu_cxx::__bfloat16_t
+  acos(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_acosf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  asin(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_asinf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  atan(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_atanf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  atan2(__gnu_cxx::__bfloat16_t __y, __gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_atan2f(__y, __x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  ceil(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_ceilf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  cos(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_cosf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  cosh(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_coshf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  exp(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_expf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  fabs(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_fabsf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  floor(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_floorf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  fmod(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __gnu_cxx::__bfloat16_t(__builtin_fmodf(__x, __y)); }
+
+  inline __gnu_cxx::__bfloat16_t
+  frexp(__gnu_cxx::__bfloat16_t __x, int* __exp)
+  { return __gnu_cxx::__bfloat16_t(__builtin_frexpf(__x, __exp)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  ldexp(__gnu_cxx::__bfloat16_t __x, int __exp)
+  { return __gnu_cxx::__bfloat16_t(__builtin_ldexpf(__x, __exp)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  log(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_logf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  log10(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_log10f(__x)); }
+
+  inline __gnu_cxx::__bfloat16_t
+  modf(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t* __iptr)
+  {
+    float __i, __ret = __builtin_modff(__x, &__i);
+    *__iptr = __gnu_cxx::__bfloat16_t(__i);
+    return __gnu_cxx::__bfloat16_t(__ret);
+  }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  pow(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __gnu_cxx::__bfloat16_t(__builtin_powf(__x, __y)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  sin(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_sinf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  sinh(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_sinhf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  sqrt(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_sqrtf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  tan(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_tanf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  tanh(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_tanhf(__x)); }
+#endif
+
 #if _GLIBCXX_USE_C99_MATH
 #if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC
 
@@ -948,84 +1506,340 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
 #endif // C++11
-#endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */
-#endif /* _GLIBCXX_USE_C99_MATH */
 
-#if __cplusplus >= 201103L
+#ifdef __STDCPP_FLOAT16_T__
+  constexpr int
+  fpclassify(_Float16 __x)
+  { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
+				FP_SUBNORMAL, FP_ZERO, __x); }
 
-#ifdef _GLIBCXX_USE_C99_MATH_TR1
+  constexpr bool
+  isfinite(_Float16 __x)
+  { return __builtin_isfinite(__x); }
 
-#undef acosh
-#undef acoshf
-#undef acoshl
-#undef asinh
-#undef asinhf
-#undef asinhl
-#undef atanh
-#undef atanhf
-#undef atanhl
-#undef cbrt
-#undef cbrtf
-#undef cbrtl
-#undef copysign
-#undef copysignf
-#undef copysignl
-#undef erf
-#undef erff
-#undef erfl
-#undef erfc
-#undef erfcf
-#undef erfcl
-#undef exp2
-#undef exp2f
-#undef exp2l
-#undef expm1
-#undef expm1f
-#undef expm1l
-#undef fdim
-#undef fdimf
-#undef fdiml
-#undef fma
-#undef fmaf
-#undef fmal
-#undef fmax
-#undef fmaxf
-#undef fmaxl
-#undef fmin
-#undef fminf
-#undef fminl
-#undef hypot
-#undef hypotf
-#undef hypotl
-#undef ilogb
-#undef ilogbf
-#undef ilogbl
-#undef lgamma
-#undef lgammaf
-#undef lgammal
-#ifndef _GLIBCXX_NO_C99_ROUNDING_FUNCS
-#undef llrint
-#undef llrintf
-#undef llrintl
-#undef llround
-#undef llroundf
-#undef llroundl
+  constexpr bool
+  isinf(_Float16 __x)
+  { return __builtin_isinf(__x); }
+
+  constexpr bool
+  isnan(_Float16 __x)
+  { return __builtin_isnan(__x); }
+
+  constexpr bool
+  isnormal(_Float16 __x)
+  { return __builtin_isnormal(__x); }
+
+  constexpr bool
+  signbit(_Float16 __x)
+  { return __builtin_signbit(__x); }
+
+  constexpr bool
+  isgreater(_Float16 __x, _Float16 __y)
+  { return __builtin_isgreater(__x, __y); }
+
+  constexpr bool
+  isgreaterequal(_Float16 __x, _Float16 __y)
+  { return __builtin_isgreaterequal(__x, __y); }
+
+  constexpr bool
+  isless(_Float16 __x, _Float16 __y)
+  { return __builtin_isless(__x, __y); }
+
+  constexpr bool
+  islessequal(_Float16 __x, _Float16 __y)
+  { return __builtin_islessequal(__x, __y); }
+
+  constexpr bool
+  islessgreater(_Float16 __x, _Float16 __y)
+  { return __builtin_islessgreater(__x, __y); }
+
+  constexpr bool
+  isunordered(_Float16 __x, _Float16 __y)
+  { return __builtin_isunordered(__x, __y); }
 #endif
-#undef log1p
-#undef log1pf
-#undef log1pl
-#undef log2
-#undef log2f
-#undef log2l
-#undef logb
-#undef logbf
-#undef logbl
-#undef lrint
-#undef lrintf
-#undef lrintl
-#undef lround
-#undef lroundf
-#undef lroundl
+
+#ifdef __STDCPP_FLOAT32_T__
+  constexpr int
+  fpclassify(_Float32 __x)
+  { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
+				FP_SUBNORMAL, FP_ZERO, __x); }
+
+  constexpr bool
+  isfinite(_Float32 __x)
+  { return __builtin_isfinite(__x); }
+
+  constexpr bool
+  isinf(_Float32 __x)
+  { return __builtin_isinf(__x); }
+
+  constexpr bool
+  isnan(_Float32 __x)
+  { return __builtin_isnan(__x); }
+
+  constexpr bool
+  isnormal(_Float32 __x)
+  { return __builtin_isnormal(__x); }
+
+  constexpr bool
+  signbit(_Float32 __x)
+  { return __builtin_signbit(__x); }
+
+  constexpr bool
+  isgreater(_Float32 __x, _Float32 __y)
+  { return __builtin_isgreater(__x, __y); }
+
+  constexpr bool
+  isgreaterequal(_Float32 __x, _Float32 __y)
+  { return __builtin_isgreaterequal(__x, __y); }
+
+  constexpr bool
+  isless(_Float32 __x, _Float32 __y)
+  { return __builtin_isless(__x, __y); }
+
+  constexpr bool
+  islessequal(_Float32 __x, _Float32 __y)
+  { return __builtin_islessequal(__x, __y); }
+
+  constexpr bool
+  islessgreater(_Float32 __x, _Float32 __y)
+  { return __builtin_islessgreater(__x, __y); }
+
+  constexpr bool
+  isunordered(_Float32 __x, _Float32 __y)
+  { return __builtin_isunordered(__x, __y); }
+#endif
+
+#ifdef __STDCPP_FLOAT64_T__
+  constexpr int
+  fpclassify(_Float64 __x)
+  { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
+				FP_SUBNORMAL, FP_ZERO, __x); }
+
+  constexpr bool
+  isfinite(_Float64 __x)
+  { return __builtin_isfinite(__x); }
+
+  constexpr bool
+  isinf(_Float64 __x)
+  { return __builtin_isinf(__x); }
+
+  constexpr bool
+  isnan(_Float64 __x)
+  { return __builtin_isnan(__x); }
+
+  constexpr bool
+  isnormal(_Float64 __x)
+  { return __builtin_isnormal(__x); }
+
+  constexpr bool
+  signbit(_Float64 __x)
+  { return __builtin_signbit(__x); }
+
+  constexpr bool
+  isgreater(_Float64 __x, _Float64 __y)
+  { return __builtin_isgreater(__x, __y); }
+
+  constexpr bool
+  isgreaterequal(_Float64 __x, _Float64 __y)
+  { return __builtin_isgreaterequal(__x, __y); }
+
+  constexpr bool
+  isless(_Float64 __x, _Float64 __y)
+  { return __builtin_isless(__x, __y); }
+
+  constexpr bool
+  islessequal(_Float64 __x, _Float64 __y)
+  { return __builtin_islessequal(__x, __y); }
+
+  constexpr bool
+  islessgreater(_Float64 __x, _Float64 __y)
+  { return __builtin_islessgreater(__x, __y); }
+
+  constexpr bool
+  isunordered(_Float64 __x, _Float64 __y)
+  { return __builtin_isunordered(__x, __y); }
+#endif
+
+#ifdef __STDCPP_FLOAT128_T__
+  constexpr int
+  fpclassify(_Float128 __x)
+  { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
+				FP_SUBNORMAL, FP_ZERO, __x); }
+
+  constexpr bool
+  isfinite(_Float128 __x)
+  { return __builtin_isfinite(__x); }
+
+  constexpr bool
+  isinf(_Float128 __x)
+  { return __builtin_isinf(__x); }
+
+  constexpr bool
+  isnan(_Float128 __x)
+  { return __builtin_isnan(__x); }
+
+  constexpr bool
+  isnormal(_Float128 __x)
+  { return __builtin_isnormal(__x); }
+
+  constexpr bool
+  signbit(_Float128 __x)
+  { return __builtin_signbit(__x); }
+
+  constexpr bool
+  isgreater(_Float128 __x, _Float128 __y)
+  { return __builtin_isgreater(__x, __y); }
+
+  constexpr bool
+  isgreaterequal(_Float128 __x, _Float128 __y)
+  { return __builtin_isgreaterequal(__x, __y); }
+
+  constexpr bool
+  isless(_Float128 __x, _Float128 __y)
+  { return __builtin_isless(__x, __y); }
+
+  constexpr bool
+  islessequal(_Float128 __x, _Float128 __y)
+  { return __builtin_islessequal(__x, __y); }
+
+  constexpr bool
+  islessgreater(_Float128 __x, _Float128 __y)
+  { return __builtin_islessgreater(__x, __y); }
+
+  constexpr bool
+  isunordered(_Float128 __x, _Float128 __y)
+  { return __builtin_isunordered(__x, __y); }
+#endif
+
+#ifdef __STDCPP_BFLOAT16_T__
+  constexpr int
+  fpclassify(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
+				FP_SUBNORMAL, FP_ZERO, __x); }
+
+  constexpr bool
+  isfinite(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_isfinite(__x); }
+
+  constexpr bool
+  isinf(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_isinf(__x); }
+
+  constexpr bool
+  isnan(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_isnan(__x); }
+
+  constexpr bool
+  isnormal(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_isnormal(__x); }
+
+  constexpr bool
+  signbit(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_signbit(__x); }
+
+  constexpr bool
+  isgreater(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_isgreater(__x, __y); }
+
+  constexpr bool
+  isgreaterequal(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_isgreaterequal(__x, __y); }
+
+  constexpr bool
+  isless(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_isless(__x, __y); }
+
+  constexpr bool
+  islessequal(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_islessequal(__x, __y); }
+
+  constexpr bool
+  islessgreater(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_islessgreater(__x, __y); }
+
+  constexpr bool
+  isunordered(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_isunordered(__x, __y); }
+#endif
+
+#endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */
+#endif /* _GLIBCXX_USE_C99_MATH */
+
+#if __cplusplus >= 201103L
+
+#ifdef _GLIBCXX_USE_C99_MATH_TR1
+
+#undef acosh
+#undef acoshf
+#undef acoshl
+#undef asinh
+#undef asinhf
+#undef asinhl
+#undef atanh
+#undef atanhf
+#undef atanhl
+#undef cbrt
+#undef cbrtf
+#undef cbrtl
+#undef copysign
+#undef copysignf
+#undef copysignl
+#undef erf
+#undef erff
+#undef erfl
+#undef erfc
+#undef erfcf
+#undef erfcl
+#undef exp2
+#undef exp2f
+#undef exp2l
+#undef expm1
+#undef expm1f
+#undef expm1l
+#undef fdim
+#undef fdimf
+#undef fdiml
+#undef fma
+#undef fmaf
+#undef fmal
+#undef fmax
+#undef fmaxf
+#undef fmaxl
+#undef fmin
+#undef fminf
+#undef fminl
+#undef hypot
+#undef hypotf
+#undef hypotl
+#undef ilogb
+#undef ilogbf
+#undef ilogbl
+#undef lgamma
+#undef lgammaf
+#undef lgammal
+#ifndef _GLIBCXX_NO_C99_ROUNDING_FUNCS
+#undef llrint
+#undef llrintf
+#undef llrintl
+#undef llround
+#undef llroundf
+#undef llroundl
+#endif
+#undef log1p
+#undef log1pf
+#undef log1pl
+#undef log2
+#undef log2f
+#undef log2l
+#undef logb
+#undef logbf
+#undef logbl
+#undef lrint
+#undef lrintf
+#undef lrintl
+#undef lround
+#undef lroundf
+#undef lroundl
 #undef nan
 #undef nanf
 #undef nanl
@@ -1843,36 +2657,841 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return __builtin_trunc(__x); }
 #endif
 
-#endif // _GLIBCXX_USE_C99_MATH_TR1
-#endif // C++11
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  constexpr _Float16
+  acosh(_Float16 __x)
+  { return _Float16(__builtin_acoshf(__x)); }
 
-#if __cplusplus >= 201703L
+  constexpr _Float16
+  asinh(_Float16 __x)
+  { return _Float16(__builtin_asinhf(__x)); }
 
-  // [c.math.hypot3], three-dimensional hypotenuse
-#define __cpp_lib_hypot 201603L
+  constexpr _Float16
+  atanh(_Float16 __x)
+  { return _Float16(__builtin_atanhf(__x)); }
 
-  template<typename _Tp>
-    inline _Tp
-    __hypot3(_Tp __x, _Tp __y, _Tp __z)
-    {
-      __x = std::abs(__x);
-      __y = std::abs(__y);
-      __z = std::abs(__z);
-      if (_Tp __a = __x < __y ? __y < __z ? __z : __y : __x < __z ? __z : __x)
-	return __a * std::sqrt((__x / __a) * (__x / __a)
-			       + (__y / __a) * (__y / __a)
-			       + (__z / __a) * (__z / __a));
-      else
-	return {};
-    }
+  constexpr _Float16
+  cbrt(_Float16 __x)
+  { return _Float16(__builtin_cbrtf(__x)); }
 
-  inline float
-  hypot(float __x, float __y, float __z)
-  { return std::__hypot3<float>(__x, __y, __z); }
+  constexpr _Float16
+  copysign(_Float16 __x, _Float16 __y)
+  { return __builtin_copysignf16(__x, __y); }
 
-  inline double
-  hypot(double __x, double __y, double __z)
-  { return std::__hypot3<double>(__x, __y, __z); }
+  constexpr _Float16
+  erf(_Float16 __x)
+  { return _Float16(__builtin_erff(__x)); }
+
+  constexpr _Float16
+  erfc(_Float16 __x)
+  { return _Float16(__builtin_erfcf(__x)); }
+
+  constexpr _Float16
+  exp2(_Float16 __x)
+  { return _Float16(__builtin_exp2f(__x)); }
+
+  constexpr _Float16
+  expm1(_Float16 __x)
+  { return _Float16(__builtin_expm1f(__x)); }
+
+  constexpr _Float16
+  fdim(_Float16 __x, _Float16 __y)
+  { return _Float16(__builtin_fdimf(__x, __y)); }
+
+  constexpr _Float16
+  fma(_Float16 __x, _Float16 __y, _Float16 __z)
+  { return _Float16(__builtin_fmaf(__x, __y, __z)); }
+
+  constexpr _Float16
+  fmax(_Float16 __x, _Float16 __y)
+  { return _Float16(__builtin_fmaxf(__x, __y)); }
+
+  constexpr _Float16
+  fmin(_Float16 __x, _Float16 __y)
+  { return _Float16(__builtin_fminf(__x, __y)); }
+
+  constexpr _Float16
+  hypot(_Float16 __x, _Float16 __y)
+  { return _Float16(__builtin_hypotf(__x, __y)); }
+
+  constexpr int
+  ilogb(_Float16 __x)
+  { return _Float16(__builtin_ilogbf(__x)); }
+
+  constexpr _Float16
+  lgamma(_Float16 __x)
+  { return _Float16(__builtin_lgammaf(__x)); }
+
+  constexpr long long
+  llrint(_Float16 __x)
+  { return _Float16(__builtin_llrintf(__x)); }
+
+  constexpr long long
+  llround(_Float16 __x)
+  { return _Float16(__builtin_llroundf(__x)); }
+
+  constexpr _Float16
+  log1p(_Float16 __x)
+  { return _Float16(__builtin_log1pf(__x)); }
+
+  // DR 568.
+  constexpr _Float16
+  log2(_Float16 __x)
+  { return _Float16(__builtin_log2f(__x)); }
+
+  constexpr _Float16
+  logb(_Float16 __x)
+  { return _Float16(__builtin_logbf(__x)); }
+
+  constexpr long
+  lrint(_Float16 __x)
+  { return _Float16(__builtin_lrintf(__x)); }
+
+  constexpr long
+  lround(_Float16 __x)
+  { return _Float16(__builtin_lroundf(__x)); }
+
+  constexpr _Float16
+  nearbyint(_Float16 __x)
+  { return _Float16(__builtin_nearbyintf(__x)); }
+
+  // nextafter not implemented so far.
+
+  constexpr _Float16
+  remainder(_Float16 __x, _Float16 __y)
+  { return _Float16(__builtin_remainderf(__x, __y)); }
+
+  inline _Float16
+  remquo(_Float16 __x, _Float16 __y, int* __pquo)
+  { return _Float16(__builtin_remquof(__x, __y, __pquo)); }
+
+  constexpr _Float16
+  rint(_Float16 __x)
+  { return _Float16(__builtin_rintf(__x)); }
+
+  constexpr _Float16
+  round(_Float16 __x)
+  { return _Float16(__builtin_roundf(__x)); }
+
+  constexpr _Float16
+  scalbln(_Float16 __x, long __ex)
+  { return _Float16(__builtin_scalblnf(__x, __ex)); }
+
+  constexpr _Float16
+  scalbn(_Float16 __x, int __ex)
+  { return _Float16(__builtin_scalbnf(__x, __ex)); }
+
+  constexpr _Float16
+  tgamma(_Float16 __x)
+  { return _Float16(__builtin_tgammaf(__x)); }
+
+  constexpr _Float16
+  trunc(_Float16 __x)
+  { return _Float16(__builtin_truncf(__x)); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  constexpr _Float32
+  acosh(_Float32 __x)
+  { return __builtin_acoshf(__x); }
+
+  constexpr _Float32
+  asinh(_Float32 __x)
+  { return __builtin_asinhf(__x); }
+
+  constexpr _Float32
+  atanh(_Float32 __x)
+  { return __builtin_atanhf(__x); }
+
+  constexpr _Float32
+  cbrt(_Float32 __x)
+  { return __builtin_cbrtf(__x); }
+
+  constexpr _Float32
+  copysign(_Float32 __x, _Float32 __y)
+  { return __builtin_copysignf(__x, __y); }
+
+  constexpr _Float32
+  erf(_Float32 __x)
+  { return __builtin_erff(__x); }
+
+  constexpr _Float32
+  erfc(_Float32 __x)
+  { return __builtin_erfcf(__x); }
+
+  constexpr _Float32
+  exp2(_Float32 __x)
+  { return __builtin_exp2f(__x); }
+
+  constexpr _Float32
+  expm1(_Float32 __x)
+  { return __builtin_expm1f(__x); }
+
+  constexpr _Float32
+  fdim(_Float32 __x, _Float32 __y)
+  { return __builtin_fdimf(__x, __y); }
+
+  constexpr _Float32
+  fma(_Float32 __x, _Float32 __y, _Float32 __z)
+  { return __builtin_fmaf(__x, __y, __z); }
+
+  constexpr _Float32
+  fmax(_Float32 __x, _Float32 __y)
+  { return __builtin_fmaxf(__x, __y); }
+
+  constexpr _Float32
+  fmin(_Float32 __x, _Float32 __y)
+  { return __builtin_fminf(__x, __y); }
+
+  constexpr _Float32
+  hypot(_Float32 __x, _Float32 __y)
+  { return __builtin_hypotf(__x, __y); }
+
+  constexpr int
+  ilogb(_Float32 __x)
+  { return __builtin_ilogbf(__x); }
+
+  constexpr _Float32
+  lgamma(_Float32 __x)
+  { return __builtin_lgammaf(__x); }
+
+  constexpr long long
+  llrint(_Float32 __x)
+  { return __builtin_llrintf(__x); }
+
+  constexpr long long
+  llround(_Float32 __x)
+  { return __builtin_llroundf(__x); }
+
+  constexpr _Float32
+  log1p(_Float32 __x)
+  { return __builtin_log1pf(__x); }
+
+  // DR 568.
+  constexpr _Float32
+  log2(_Float32 __x)
+  { return __builtin_log2f(__x); }
+
+  constexpr _Float32
+  logb(_Float32 __x)
+  { return __builtin_logbf(__x); }
+
+  constexpr long
+  lrint(_Float32 __x)
+  { return __builtin_lrintf(__x); }
+
+  constexpr long
+  lround(_Float32 __x)
+  { return __builtin_lroundf(__x); }
+
+  constexpr _Float32
+  nearbyint(_Float32 __x)
+  { return __builtin_nearbyintf(__x); }
+
+  constexpr _Float32
+  nextafter(_Float32 __x, _Float32 __y)
+  { return __builtin_nextafterf(__x, __y); }
+
+  constexpr _Float32
+  remainder(_Float32 __x, _Float32 __y)
+  { return __builtin_remainderf(__x, __y); }
+
+  inline _Float32
+  remquo(_Float32 __x, _Float32 __y, int* __pquo)
+  { return __builtin_remquof(__x, __y, __pquo); }
+
+  constexpr _Float32
+  rint(_Float32 __x)
+  { return __builtin_rintf(__x); }
+
+  constexpr _Float32
+  round(_Float32 __x)
+  { return __builtin_roundf(__x); }
+
+  constexpr _Float32
+  scalbln(_Float32 __x, long __ex)
+  { return __builtin_scalblnf(__x, __ex); }
+
+  constexpr _Float32
+  scalbn(_Float32 __x, int __ex)
+  { return __builtin_scalbnf(__x, __ex); }
+
+  constexpr _Float32
+  tgamma(_Float32 __x)
+  { return __builtin_tgammaf(__x); }
+
+  constexpr _Float32
+  trunc(_Float32 __x)
+  { return __builtin_truncf(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  constexpr _Float64
+  acosh(_Float64 __x)
+  { return __builtin_acosh(__x); }
+
+  constexpr _Float64
+  asinh(_Float64 __x)
+  { return __builtin_asinh(__x); }
+
+  constexpr _Float64
+  atanh(_Float64 __x)
+  { return __builtin_atanh(__x); }
+
+  constexpr _Float64
+  cbrt(_Float64 __x)
+  { return __builtin_cbrt(__x); }
+
+  constexpr _Float64
+  copysign(_Float64 __x, _Float64 __y)
+  { return __builtin_copysign(__x, __y); }
+
+  constexpr _Float64
+  erf(_Float64 __x)
+  { return __builtin_erf(__x); }
+
+  constexpr _Float64
+  erfc(_Float64 __x)
+  { return __builtin_erfc(__x); }
+
+  constexpr _Float64
+  exp2(_Float64 __x)
+  { return __builtin_exp2(__x); }
+
+  constexpr _Float64
+  expm1(_Float64 __x)
+  { return __builtin_expm1(__x); }
+
+  constexpr _Float64
+  fdim(_Float64 __x, _Float64 __y)
+  { return __builtin_fdim(__x, __y); }
+
+  constexpr _Float64
+  fma(_Float64 __x, _Float64 __y, _Float64 __z)
+  { return __builtin_fma(__x, __y, __z); }
+
+  constexpr _Float64
+  fmax(_Float64 __x, _Float64 __y)
+  { return __builtin_fmax(__x, __y); }
+
+  constexpr _Float64
+  fmin(_Float64 __x, _Float64 __y)
+  { return __builtin_fmin(__x, __y); }
+
+  constexpr _Float64
+  hypot(_Float64 __x, _Float64 __y)
+  { return __builtin_hypot(__x, __y); }
+
+  constexpr int
+  ilogb(_Float64 __x)
+  { return __builtin_ilogb(__x); }
+
+  constexpr _Float64
+  lgamma(_Float64 __x)
+  { return __builtin_lgamma(__x); }
+
+  constexpr long long
+  llrint(_Float64 __x)
+  { return __builtin_llrint(__x); }
+
+  constexpr long long
+  llround(_Float64 __x)
+  { return __builtin_llround(__x); }
+
+  constexpr _Float64
+  log1p(_Float64 __x)
+  { return __builtin_log1p(__x); }
+
+  // DR 568.
+  constexpr _Float64
+  log2(_Float64 __x)
+  { return __builtin_log2(__x); }
+
+  constexpr _Float64
+  logb(_Float64 __x)
+  { return __builtin_logb(__x); }
+
+  constexpr long
+  lrint(_Float64 __x)
+  { return __builtin_lrint(__x); }
+
+  constexpr long
+  lround(_Float64 __x)
+  { return __builtin_lround(__x); }
+
+  constexpr _Float64
+  nearbyint(_Float64 __x)
+  { return __builtin_nearbyint(__x); }
+
+  constexpr _Float64
+  nextafter(_Float64 __x, _Float64 __y)
+  { return __builtin_nextafter(__x, __y); }
+
+  constexpr _Float64
+  remainder(_Float64 __x, _Float64 __y)
+  { return __builtin_remainder(__x, __y); }
+
+  inline _Float64
+  remquo(_Float64 __x, _Float64 __y, int* __pquo)
+  { return __builtin_remquo(__x, __y, __pquo); }
+
+  constexpr _Float64
+  rint(_Float64 __x)
+  { return __builtin_rint(__x); }
+
+  constexpr _Float64
+  round(_Float64 __x)
+  { return __builtin_round(__x); }
+
+  constexpr _Float64
+  scalbln(_Float64 __x, long __ex)
+  { return __builtin_scalbln(__x, __ex); }
+
+  constexpr _Float64
+  scalbn(_Float64 __x, int __ex)
+  { return __builtin_scalbn(__x, __ex); }
+
+  constexpr _Float64
+  tgamma(_Float64 __x)
+  { return __builtin_tgamma(__x); }
+
+  constexpr _Float64
+  trunc(_Float64 __x)
+  { return __builtin_trunc(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+  constexpr _Float128
+  acosh(_Float128 __x)
+  { return __builtin_acoshl(__x); }
+
+  constexpr _Float128
+  asinh(_Float128 __x)
+  { return __builtin_asinhl(__x); }
+
+  constexpr _Float128
+  atanh(_Float128 __x)
+  { return __builtin_atanhl(__x); }
+
+  constexpr _Float128
+  cbrt(_Float128 __x)
+  { return __builtin_cbrtl(__x); }
+
+  constexpr _Float128
+  copysign(_Float128 __x, _Float128 __y)
+  { return __builtin_copysignl(__x, __y); }
+
+  constexpr _Float128
+  erf(_Float128 __x)
+  { return __builtin_erfl(__x); }
+
+  constexpr _Float128
+  erfc(_Float128 __x)
+  { return __builtin_erfcl(__x); }
+
+  constexpr _Float128
+  exp2(_Float128 __x)
+  { return __builtin_exp2l(__x); }
+
+  constexpr _Float128
+  expm1(_Float128 __x)
+  { return __builtin_expm1l(__x); }
+
+  constexpr _Float128
+  fdim(_Float128 __x, _Float128 __y)
+  { return __builtin_fdiml(__x, __y); }
+
+  constexpr _Float128
+  fma(_Float128 __x, _Float128 __y, _Float128 __z)
+  { return __builtin_fmal(__x, __y, __z); }
+
+  constexpr _Float128
+  fmax(_Float128 __x, _Float128 __y)
+  { return __builtin_fmaxl(__x, __y); }
+
+  constexpr _Float128
+  fmin(_Float128 __x, _Float128 __y)
+  { return __builtin_fminl(__x, __y); }
+
+  constexpr _Float128
+  hypot(_Float128 __x, _Float128 __y)
+  { return __builtin_hypotl(__x, __y); }
+
+  constexpr int
+  ilogb(_Float128 __x)
+  { return __builtin_ilogbl(__x); }
+
+  constexpr _Float128
+  lgamma(_Float128 __x)
+  { return __builtin_lgammal(__x); }
+
+  constexpr long long
+  llrint(_Float128 __x)
+  { return __builtin_llrintl(__x); }
+
+  constexpr long long
+  llround(_Float128 __x)
+  { return __builtin_llroundl(__x); }
+
+  constexpr _Float128
+  log1p(_Float128 __x)
+  { return __builtin_log1pl(__x); }
+
+  // DR 568.
+  constexpr _Float128
+  log2(_Float128 __x)
+  { return __builtin_log2l(__x); }
+
+  constexpr _Float128
+  logb(_Float128 __x)
+  { return __builtin_logbl(__x); }
+
+  constexpr long
+  lrint(_Float128 __x)
+  { return __builtin_lrintl(__x); }
+
+  constexpr long
+  lround(_Float128 __x)
+  { return __builtin_lroundl(__x); }
+
+  constexpr _Float128
+  nearbyint(_Float128 __x)
+  { return __builtin_nearbyintl(__x); }
+
+  constexpr _Float128
+  nextafter(_Float128 __x, _Float128 __y)
+  { return __builtin_nextafterl(__x, __y); }
+
+  constexpr _Float128
+  remainder(_Float128 __x, _Float128 __y)
+  { return __builtin_remainderl(__x, __y); }
+
+  inline _Float128
+  remquo(_Float128 __x, _Float128 __y, int* __pquo)
+  { return __builtin_remquol(__x, __y, __pquo); }
+
+  constexpr _Float128
+  rint(_Float128 __x)
+  { return __builtin_rintl(__x); }
+
+  constexpr _Float128
+  round(_Float128 __x)
+  { return __builtin_roundl(__x); }
+
+  constexpr _Float128
+  scalbln(_Float128 __x, long __ex)
+  { return __builtin_scalblnl(__x, __ex); }
+
+  constexpr _Float128
+  scalbn(_Float128 __x, int __ex)
+  { return __builtin_scalbnl(__x, __ex); }
+
+  constexpr _Float128
+  tgamma(_Float128 __x)
+  { return __builtin_tgammal(__x); }
+
+  constexpr _Float128
+  trunc(_Float128 __x)
+  { return __builtin_truncl(__x); }
+#elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
+  constexpr _Float128
+  acosh(_Float128 __x)
+  { return __builtin_acoshf128(__x); }
+
+  constexpr _Float128
+  asinh(_Float128 __x)
+  { return __builtin_asinhf128(__x); }
+
+  constexpr _Float128
+  atanh(_Float128 __x)
+  { return __builtin_atanhf128(__x); }
+
+  constexpr _Float128
+  cbrt(_Float128 __x)
+  { return __builtin_cbrtf128(__x); }
+
+  constexpr _Float128
+  copysign(_Float128 __x, _Float128 __y)
+  { return __builtin_copysignf128(__x, __y); }
+
+  constexpr _Float128
+  erf(_Float128 __x)
+  { return __builtin_erff128(__x); }
+
+  constexpr _Float128
+  erfc(_Float128 __x)
+  { return __builtin_erfcf128(__x); }
+
+  constexpr _Float128
+  exp2(_Float128 __x)
+  { return __builtin_exp2f128(__x); }
+
+  constexpr _Float128
+  expm1(_Float128 __x)
+  { return __builtin_expm1f128(__x); }
+
+  constexpr _Float128
+  fdim(_Float128 __x, _Float128 __y)
+  { return __builtin_fdimf128(__x, __y); }
+
+  constexpr _Float128
+  fma(_Float128 __x, _Float128 __y, _Float128 __z)
+  { return __builtin_fmaf128(__x, __y, __z); }
+
+  constexpr _Float128
+  fmax(_Float128 __x, _Float128 __y)
+  { return __builtin_fmaxf128(__x, __y); }
+
+  constexpr _Float128
+  fmin(_Float128 __x, _Float128 __y)
+  { return __builtin_fminf128(__x, __y); }
+
+  constexpr _Float128
+  hypot(_Float128 __x, _Float128 __y)
+  { return __builtin_hypotf128(__x, __y); }
+
+  constexpr int
+  ilogb(_Float128 __x)
+  { return __builtin_ilogbf128(__x); }
+
+  constexpr _Float128
+  lgamma(_Float128 __x)
+  { return __builtin_lgammaf128(__x); }
+
+  constexpr long long
+  llrint(_Float128 __x)
+  { return __builtin_llrintf128(__x); }
+
+  constexpr long long
+  llround(_Float128 __x)
+  { return __builtin_llroundf128(__x); }
+
+  constexpr _Float128
+  log1p(_Float128 __x)
+  { return __builtin_log1pf128(__x); }
+
+  // DR 568.
+  constexpr _Float128
+  log2(_Float128 __x)
+  { return __builtin_log2f128(__x); }
+
+  constexpr _Float128
+  logb(_Float128 __x)
+  { return __builtin_logbf128(__x); }
+
+  constexpr long
+  lrint(_Float128 __x)
+  { return __builtin_lrintf128(__x); }
+
+  constexpr long
+  lround(_Float128 __x)
+  { return __builtin_lroundf128(__x); }
+
+  constexpr _Float128
+  nearbyint(_Float128 __x)
+  { return __builtin_nearbyintf128(__x); }
+
+  constexpr _Float128
+  nextafter(_Float128 __x, _Float128 __y)
+  { return __builtin_nextafterf128(__x, __y); }
+
+  constexpr _Float128
+  remainder(_Float128 __x, _Float128 __y)
+  { return __builtin_remainderf128(__x, __y); }
+
+  inline _Float128
+  remquo(_Float128 __x, _Float128 __y, int* __pquo)
+  { return __builtin_remquof128(__x, __y, __pquo); }
+
+  constexpr _Float128
+  rint(_Float128 __x)
+  { return __builtin_rintf128(__x); }
+
+  constexpr _Float128
+  round(_Float128 __x)
+  { return __builtin_roundf128(__x); }
+
+  constexpr _Float128
+  scalbln(_Float128 __x, long __ex)
+  { return __builtin_scalblnf128(__x, __ex); }
+
+  constexpr _Float128
+  scalbn(_Float128 __x, int __ex)
+  { return __builtin_scalbnf128(__x, __ex); }
+
+  constexpr _Float128
+  tgamma(_Float128 __x)
+  { return __builtin_tgammaf128(__x); }
+
+  constexpr _Float128
+  trunc(_Float128 __x)
+  { return __builtin_truncf128(__x); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  constexpr __gnu_cxx::__bfloat16_t
+  acosh(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_acoshf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  asinh(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_asinhf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  atanh(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_atanhf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  cbrt(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_cbrtf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  copysign(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __gnu_cxx::__bfloat16_t(__builtin_copysignf(__x, __y)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  erf(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_erff(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  erfc(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_erfcf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  exp2(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_exp2f(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  expm1(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_expm1f(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  fdim(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __gnu_cxx::__bfloat16_t(__builtin_fdimf(__x, __y)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  fma(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y, __gnu_cxx::__bfloat16_t __z)
+  { return __gnu_cxx::__bfloat16_t(__builtin_fmaf(__x, __y, __z)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  fmax(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __gnu_cxx::__bfloat16_t(__builtin_fmaxf(__x, __y)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  fmin(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __gnu_cxx::__bfloat16_t(__builtin_fminf(__x, __y)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  hypot(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __gnu_cxx::__bfloat16_t(__builtin_hypotf(__x, __y)); }
+
+  constexpr int
+  ilogb(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_ilogbf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  lgamma(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_lgammaf(__x)); }
+
+  constexpr long long
+  llrint(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_llrintf(__x)); }
+
+  constexpr long long
+  llround(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_llroundf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  log1p(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_log1pf(__x)); }
+
+  // DR 568.
+  constexpr __gnu_cxx::__bfloat16_t
+  log2(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_log2f(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  logb(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_logbf(__x)); }
+
+  constexpr long
+  lrint(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_lrintf(__x)); }
+
+  constexpr long
+  lround(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_lroundf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  nearbyint(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_nearbyintf(__x)); }
+
+  // nextafter not implemented so far.
+
+  constexpr __gnu_cxx::__bfloat16_t
+  remainder(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __gnu_cxx::__bfloat16_t(__builtin_remainderf(__x, __y)); }
+
+  inline __gnu_cxx::__bfloat16_t
+  remquo(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y, int* __pquo)
+  { return __gnu_cxx::__bfloat16_t(__builtin_remquof(__x, __y, __pquo)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  rint(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_rintf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  round(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_roundf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  scalbln(__gnu_cxx::__bfloat16_t __x, long __ex)
+  { return __gnu_cxx::__bfloat16_t(__builtin_scalblnf(__x, __ex)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  scalbn(__gnu_cxx::__bfloat16_t __x, int __ex)
+  { return __gnu_cxx::__bfloat16_t(__builtin_scalbnf(__x, __ex)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  tgamma(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_tgammaf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  trunc(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_truncf(__x)); }
+#endif
+
+
+#endif // _GLIBCXX_USE_C99_MATH_TR1
+#endif // C++11
+
+#if __cplusplus >= 201703L
+
+  // [c.math.hypot3], three-dimensional hypotenuse
+#define __cpp_lib_hypot 201603L
+
+  template<typename _Tp>
+    inline _Tp
+    __hypot3(_Tp __x, _Tp __y, _Tp __z)
+    {
+      __x = std::abs(__x);
+      __y = std::abs(__y);
+      __z = std::abs(__z);
+      if (_Tp __a = __x < __y ? __y < __z ? __z : __y : __x < __z ? __z : __x)
+	return __a * std::sqrt((__x / __a) * (__x / __a)
+			       + (__y / __a) * (__y / __a)
+			       + (__z / __a) * (__z / __a));
+      else
+	return {};
+    }
+
+  inline float
+  hypot(float __x, float __y, float __z)
+  { return std::__hypot3<float>(__x, __y, __z); }
+
+  inline double
+  hypot(double __x, double __y, double __z)
+  { return std::__hypot3<double>(__x, __y, __z); }
 
   inline long double
   hypot(long double __x, long double __y, long double __z)
@@ -1885,6 +3504,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       using __type = __gnu_cxx::__promoted_t<_Tp, _Up, _Vp>;
       return std::__hypot3<__type>(__x, __y, __z);
     }
+
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline _Float16
+  hypot(_Float16 __x, _Float16 __y, _Float16 __z)
+  { return std::__hypot3<_Float16>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline _Float32
+  hypot(_Float32 __x, _Float32 __y, _Float32 __z)
+  { return std::__hypot3<_Float32>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  inline _Float64
+  hypot(_Float64 __x, _Float64 __y, _Float64 __z)
+  { return std::__hypot3<_Float64>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) \
+    && (defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128) \
+	|| defined(_GLIBCXX_HAVE_FLOAT128_MATH))
+  inline _Float128
+  hypot(_Float128 __x, _Float128 __y, _Float128 __z)
+  { return std::__hypot3<_Float128>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline __gnu_cxx::__bfloat16_t
+  hypot(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y, __gnu_cxx::__bfloat16_t __z)
+  { return std::__hypot3<__gnu_cxx::__bfloat16_t>(__x, __y, __z); }
+#endif
+
 #endif // C++17
 
 #if __cplusplus >= 202002L
@@ -1928,6 +3580,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       using __type = __gnu_cxx::__promoted_t<_Tp, _Up, _Vp>;
       return std::__lerp<__type>(__x, __y, __z);
     }
+
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline _Float16
+  lerp(_Float16 __x, _Float16 __y, _Float16 __z) noexcept
+  { return std::__lerp<_Float16>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline _Float32
+  lerp(_Float32 __x, _Float32 __y, _Float32 __z) noexcept
+  { return std::__lerp<_Float32>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  inline _Float64
+  lerp(_Float64 __x, _Float64 __y, _Float64 __z) noexcept
+  { return std::__lerp<_Float64>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) \
+    && (defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128) \
+	|| defined(_GLIBCXX_HAVE_FLOAT128_MATH))
+  inline _Float128
+  lerp(_Float128 __x, _Float128 __y, _Float128 __z) noexcept
+  { return std::__lerp<_Float128>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline __gnu_cxx::__bfloat16_t
+  lerp(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y, __gnu_cxx::__bfloat16_t __z) noexcept
+  { return std::__lerp<__gnu_cxx::__bfloat16_t>(__x, __y, __z); }
+#endif
+
 #endif // C++20
 
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/ext/type_traits.h b/libstdc++-v3/include/ext/type_traits.h
index 27fae823436..a6321dfc216 100644
--- a/libstdc++-v3/include/ext/type_traits.h
+++ b/libstdc++-v3/include/ext/type_traits.h
@@ -190,6 +190,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __promote<float>
     { typedef float __type; };
 
+#ifdef __STDCPP_FLOAT16_T__
+  template<>
+    struct __promote<_Float16>
+    { typedef _Float16 __type; };
+#endif
+
+#ifdef __STDCPP_FLOAT32_T__
+  template<>
+    struct __promote<_Float32>
+    { typedef _Float32 __type; };
+#endif
+
+#ifdef __STDCPP_FLOAT64_T__
+  template<>
+    struct __promote<_Float64>
+    { typedef _Float64 __type; };
+#endif
+
+#ifdef __STDCPP_FLOAT128_T__
+  template<>
+    struct __promote<_Float128>
+    { typedef _Float128 __type; };
+#endif
+
+#ifdef __STDCPP_BFLOAT16_T__
+  template<>
+    struct __promote<__gnu_cxx::__bfloat16_t>
+    { typedef __gnu_cxx::__bfloat16_t __type; };
+#endif
+
 #if __cpp_fold_expressions
 
   template<typename... _Tp>
diff --git a/libstdc++-v3/include/precompiled/stdc++.h b/libstdc++-v3/include/precompiled/stdc++.h
index bfbb1654b88..81576899473 100644
--- a/libstdc++-v3/include/precompiled/stdc++.h
+++ b/libstdc++-v3/include/precompiled/stdc++.h
@@ -228,6 +228,7 @@
 # include <stacktrace>
 #endif
 #include <stdatomic.h>
+#include <stdfloat>
 #endif
 
 #endif // HOSTED
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index b913960336d..356f1458f44 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -1625,6 +1625,91 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       using __atomic_float<long double>::operator=;
     };
 
+#ifdef __STDCPP_FLOAT16_T__
+  template<>
+    struct atomic<_Float16> : __atomic_float<_Float16>
+    {
+      atomic() noexcept = default;
+
+      constexpr
+      atomic(_Float16 __fp) noexcept : __atomic_float<_Float16>(__fp)
+      { }
+
+      atomic& operator=(const atomic&) volatile = delete;
+      atomic& operator=(const atomic&) = delete;
+
+      using __atomic_float<_Float16>::operator=;
+    };
+#endif
+
+#ifdef __STDCPP_FLOAT32_T__
+  template<>
+    struct atomic<_Float32> : __atomic_float<_Float32>
+    {
+      atomic() noexcept = default;
+
+      constexpr
+      atomic(_Float32 __fp) noexcept : __atomic_float<_Float32>(__fp)
+      { }
+
+      atomic& operator=(const atomic&) volatile = delete;
+      atomic& operator=(const atomic&) = delete;
+
+      using __atomic_float<_Float32>::operator=;
+    };
+#endif
+
+#ifdef __STDCPP_FLOAT64_T__
+  template<>
+    struct atomic<_Float64> : __atomic_float<_Float64>
+    {
+      atomic() noexcept = default;
+
+      constexpr
+      atomic(_Float64 __fp) noexcept : __atomic_float<_Float64>(__fp)
+      { }
+
+      atomic& operator=(const atomic&) volatile = delete;
+      atomic& operator=(const atomic&) = delete;
+
+      using __atomic_float<_Float64>::operator=;
+    };
+#endif
+
+#ifdef __STDCPP_FLOAT128_T__
+  template<>
+    struct atomic<_Float128> : __atomic_float<_Float128>
+    {
+      atomic() noexcept = default;
+
+      constexpr
+      atomic(_Float128 __fp) noexcept : __atomic_float<_Float128>(__fp)
+      { }
+
+      atomic& operator=(const atomic&) volatile = delete;
+      atomic& operator=(const atomic&) = delete;
+
+      using __atomic_float<_Float128>::operator=;
+    };
+#endif
+
+#ifdef __STDCPP_BFLOAT16_T__
+  template<>
+    struct atomic<__gnu_cxx::__bfloat16_t> : __atomic_float<__gnu_cxx::__bfloat16_t>
+    {
+      atomic() noexcept = default;
+
+      constexpr
+      atomic(__gnu_cxx::__bfloat16_t __fp) noexcept : __atomic_float<__gnu_cxx::__bfloat16_t>(__fp)
+      { }
+
+      atomic& operator=(const atomic&) volatile = delete;
+      atomic& operator=(const atomic&) = delete;
+
+      using __atomic_float<__gnu_cxx::__bfloat16_t>::operator=;
+    };
+#endif
+
 #define __cpp_lib_atomic_ref 201806L
 
   /// Class template to provide atomic operations on a non-atomic variable.
diff --git a/libstdc++-v3/include/std/limits b/libstdc++-v3/include/std/limits
index a60611b1b11..61b6c3b0f2d 100644
--- a/libstdc++-v3/include/std/limits
+++ b/libstdc++-v3/include/std/limits
@@ -1890,6 +1890,190 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #undef __glibcxx_long_double_traps
 #undef __glibcxx_long_double_tinyness_before
 
+#if __cplusplus > 202202L
+
+#define __glibcxx_concat3_(P,M,S) P ## M ## S
+#define __glibcxx_concat3(P,M,S) __glibcxx_concat3_ (P,M,S)
+
+#define __glibcxx_float_n(BITSIZE)					\
+  __extension__								\
+  template<>								\
+    struct numeric_limits<_Float##BITSIZE>				\
+    {									\
+      static constexpr bool is_specialized = true;			\
+									\
+      static constexpr _Float##BITSIZE					\
+      min() noexcept							\
+      { return __glibcxx_concat3 (__FLT, BITSIZE, _MIN__); }		\
+									\
+      static constexpr _Float##BITSIZE					\
+      max() noexcept							\
+      { return __glibcxx_concat3 (__FLT, BITSIZE, _MAX__); }		\
+									\
+      static constexpr _Float##BITSIZE					\
+      lowest() noexcept							\
+      { return -__glibcxx_concat3 (__FLT, BITSIZE, _MAX__); }		\
+									\
+      static constexpr int digits					\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _MANT_DIG__);		\
+      static constexpr int digits10					\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _DIG__);			\
+      static constexpr int max_digits10					\
+	= __glibcxx_max_digits10 (__glibcxx_concat3 (__FLT, BITSIZE,	\
+						     _MANT_DIG__));	\
+      static constexpr bool is_signed = true;				\
+      static constexpr bool is_integer = false;				\
+      static constexpr bool is_exact = false;				\
+      static constexpr int radix					\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _RADIX__);			\
+									\
+      static constexpr _Float##BITSIZE					\
+      epsilon() noexcept						\
+      { return __glibcxx_concat3 (__FLT, BITSIZE, _EPSILON__); }	\
+									\
+      static constexpr _Float##BITSIZE 					\
+      round_error() noexcept { return 0.5F##BITSIZE; }			\
+									\
+      static constexpr int min_exponent					\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _MIN_EXP__);		\
+      static constexpr int min_exponent10				\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _MIN_10_EXP__);		\
+      static constexpr int max_exponent					\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _MAX_EXP__);		\
+      static constexpr int max_exponent10				\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _MAX_10_EXP__);		\
+									\
+      static constexpr bool has_infinity				\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _HAS_INFINITY__);		\
+      static constexpr bool has_quiet_NaN				\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _HAS_QUIET_NAN__);		\
+      static constexpr bool has_signaling_NaN				\
+	= has_quiet_NaN;						\
+      static constexpr float_denorm_style has_denorm			\
+	= bool(__glibcxx_concat3 (__FLT, BITSIZE, _HAS_DENORM__))	\
+	  ? denorm_present : denorm_absent;				\
+      static constexpr bool has_denorm_loss = false;			\
+									\
+      static constexpr _Float##BITSIZE					\
+      infinity() noexcept						\
+      { return __builtin_huge_valf##BITSIZE(); }			\
+									\
+      static constexpr _Float##BITSIZE					\
+      quiet_NaN() noexcept						\
+      { return __builtin_nanf##BITSIZE(""); }				\
+									\
+      static constexpr _Float##BITSIZE					\
+      signaling_NaN() noexcept						\
+      { return __builtin_nansf##BITSIZE(""); }				\
+									\
+      static constexpr _Float##BITSIZE					\
+      denorm_min() noexcept						\
+      { return __glibcxx_concat3 (__FLT, BITSIZE, _DENORM_MIN__); }	\
+									\
+      static constexpr bool is_iec559					\
+	= has_infinity && has_quiet_NaN && has_denorm == denorm_present;\
+      static constexpr bool is_bounded = true; 				\
+      static constexpr bool is_modulo = false; 				\
+									\
+      static constexpr bool traps = false; 				\
+      static constexpr bool tinyness_before = false; 			\
+      static constexpr float_round_style round_style 			\
+	= round_to_nearest; 						\
+    }; 									\
+
+#ifdef __STDCPP_FLOAT16_T__
+__glibcxx_float_n(16)
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+__glibcxx_float_n(32)
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+__glibcxx_float_n(64)
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+__glibcxx_float_n(128)
+#endif
+#undef __glibcxx_float_n
+#undef __glibcxx_concat3
+#undef __glibcxx_concat3_
+
+#ifdef __STDCPP_BFLOAT16_T__
+  __extension__
+  template<>
+    struct numeric_limits<__gnu_cxx::__bfloat16_t>
+    {
+      static constexpr bool is_specialized = true;
+
+      static constexpr __gnu_cxx::__bfloat16_t
+      min() noexcept
+      { return __BFLT16_MIN__; }
+
+      static constexpr __gnu_cxx::__bfloat16_t
+      max() noexcept
+      { return __BFLT16_MAX__; }
+
+      static constexpr __gnu_cxx::__bfloat16_t
+      lowest() noexcept
+      { return -__BFLT16_MAX__; }
+
+      static constexpr int digits = __BFLT16_MANT_DIG__;
+      static constexpr int digits10 = __BFLT16_DIG__;
+      static constexpr int max_digits10
+	= __glibcxx_max_digits10 (__BFLT16_MANT_DIG__);
+      static constexpr bool is_signed = true;
+      static constexpr bool is_integer = false;
+      static constexpr bool is_exact = false;
+      static constexpr int radix = __BFLT16_RADIX__;
+
+      static constexpr __gnu_cxx::__bfloat16_t
+      epsilon() noexcept
+      { return __BFLT16_EPSILON__; }
+
+      static constexpr __gnu_cxx::__bfloat16_t
+      round_error() noexcept { return 0.5BF16; }
+
+      static constexpr int min_exponent = __BFLT16_MIN_EXP__;
+      static constexpr int min_exponent10 = __BFLT16_MIN_10_EXP__;
+      static constexpr int max_exponent = __BFLT16_MAX_EXP__;
+      static constexpr int max_exponent10 = __BFLT16_MAX_10_EXP__;
+
+      static constexpr bool has_infinity = __BFLT16_HAS_INFINITY__;
+      static constexpr bool has_quiet_NaN = __BFLT16_HAS_QUIET_NAN__;
+      static constexpr bool has_signaling_NaN = has_quiet_NaN;
+      static constexpr float_denorm_style has_denorm
+	= bool(__BFLT16_HAS_DENORM__)
+	  ? denorm_present : denorm_absent;
+      static constexpr bool has_denorm_loss = false;
+
+      static constexpr __gnu_cxx::__bfloat16_t
+      infinity() noexcept
+      { return __gnu_cxx::__bfloat16_t(__builtin_huge_valf()); }
+
+      static constexpr __gnu_cxx::__bfloat16_t
+      quiet_NaN() noexcept
+      { return __gnu_cxx::__bfloat16_t(__builtin_nanf("")); }
+
+      static constexpr __gnu_cxx::__bfloat16_t
+      signaling_NaN() noexcept
+      { return __builtin_nansf16b(""); }
+
+      static constexpr __gnu_cxx::__bfloat16_t
+      denorm_min() noexcept
+      { return __BFLT16_DENORM_MIN__; }
+
+      static constexpr bool is_iec559
+	= has_infinity && has_quiet_NaN && has_denorm == denorm_present;
+      static constexpr bool is_bounded = true;
+      static constexpr bool is_modulo = false;
+
+      static constexpr bool traps = false;
+      static constexpr bool tinyness_before = false;
+      static constexpr float_round_style round_style = round_to_nearest;
+    };
+#endif
+
+#endif
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
diff --git a/libstdc++-v3/include/std/numbers b/libstdc++-v3/include/std/numbers
index 518766558be..6d3322808a3 100644
--- a/libstdc++-v3/include/std/numbers
+++ b/libstdc++-v3/include/std/numbers
@@ -133,72 +133,98 @@ namespace numbers
   inline constexpr double egamma = egamma_v<double>;
   inline constexpr double phi = phi_v<double>;
 
-#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
-  template<>
-    inline constexpr __float128 e_v<__float128>
-      = 2.718281828459045235360287471352662498Q;
-
-  /// log_2 e
-  template<>
-    inline constexpr __float128 log2e_v<__float128>
-      = 1.442695040888963407359924681001892137Q;
-
-  /// log_10 e
-  template<>
-    inline constexpr __float128 log10e_v<__float128>
-      = 0.434294481903251827651128918916605082Q;
-
-  /// pi
-  template<>
-    inline constexpr __float128 pi_v<__float128>
-      = 3.141592653589793238462643383279502884Q;
-
-  /// 1/pi
-  template<>
-    inline constexpr __float128 inv_pi_v<__float128>
-      = 0.318309886183790671537767526745028724Q;
-
-  /// 1/sqrt(pi)
-  template<>
-    inline constexpr __float128 inv_sqrtpi_v<__float128>
-      = 0.564189583547756286948079451560772586Q;
-
-  /// log_e 2
-  template<>
-    inline constexpr __float128 ln2_v<__float128>
-      = 0.693147180559945309417232121458176568Q;
+#define __glibcxx_numbers(TYPE, SUFFIX) \
+  /* e */						\
+  template<>						\
+    inline constexpr TYPE e_v<TYPE>			\
+      = 2.718281828459045235360287471352662498##SUFFIX;	\
+							\
+  /* log_2 e */						\
+  template<>						\
+    inline constexpr TYPE log2e_v<TYPE>			\
+      = 1.442695040888963407359924681001892137##SUFFIX;	\
+							\
+  /* log_10 e */					\
+  template<>						\
+    inline constexpr TYPE log10e_v<TYPE>		\
+      = 0.434294481903251827651128918916605082##SUFFIX;	\
+							\
+  /* pi */						\
+  template<>						\
+    inline constexpr TYPE pi_v<TYPE>			\
+      = 3.141592653589793238462643383279502884##SUFFIX;	\
+							\
+  /* 1/pi */						\
+  template<>						\
+    inline constexpr TYPE inv_pi_v<TYPE>		\
+      = 0.318309886183790671537767526745028724##SUFFIX;	\
+							\
+  /* 1/sqrt(pi) */					\
+  template<>						\
+    inline constexpr TYPE inv_sqrtpi_v<TYPE>		\
+      = 0.564189583547756286948079451560772586##SUFFIX;	\
+							\
+  /* log_e 2 */						\
+  template<>						\
+    inline constexpr TYPE ln2_v<TYPE>			\
+      = 0.693147180559945309417232121458176568##SUFFIX;	\
+							\
+  /* log_e 10 */					\
+  template<>						\
+    inline constexpr TYPE ln10_v<TYPE>			\
+      = 2.302585092994045684017991454684364208##SUFFIX;	\
+							\
+  /* sqrt(2) */						\
+  template<>						\
+    inline constexpr TYPE sqrt2_v<TYPE>			\
+      = 1.414213562373095048801688724209698079##SUFFIX;	\
+							\
+  /* sqrt(3) */						\
+  template<>						\
+    inline constexpr TYPE sqrt3_v<TYPE>			\
+      = 1.732050807568877293527446341505872367##SUFFIX;	\
+							\
+  /* 1/sqrt(3) */					\
+  template<>						\
+    inline constexpr TYPE inv_sqrt3_v<TYPE>		\
+      = 0.577350269189625764509148780501957456##SUFFIX;	\
+							\
+  /* The Euler-Mascheroni constant */			\
+  template<>						\
+    inline constexpr TYPE egamma_v<TYPE>		\
+      = 0.577215664901532860606512090082402431##SUFFIX;	\
+							\
+  /* The golden ratio, (1+sqrt(5))/2 */			\
+  template<>						\
+    inline constexpr TYPE phi_v<TYPE>			\
+      = 1.618033988749894848204586834365638118##SUFFIX
+
+#ifdef __STDCPP_FLOAT16_T__
+__glibcxx_numbers (_Float16, F16);
+#endif
+
+#ifdef __STDCPP_FLOAT32_T__
+__glibcxx_numbers (_Float32, F32);
+#endif
+
+#ifdef __STDCPP_FLOAT64_T__
+__glibcxx_numbers (_Float64, F64);
+#endif
+
+#ifdef __STDCPP_FLOAT128_T__
+__glibcxx_numbers (_Float128, F128);
+#endif
+
+#ifdef __STDCPP_BFLOAT128_T__
+__glibcxx_numbers (__gnu_cxx::__bfloat16_t, BF16);
+#endif
 
-  /// log_e 10
-  template<>
-    inline constexpr __float128 ln10_v<__float128>
-      = 2.302585092994045684017991454684364208Q;
-
-  /// sqrt(2)
-  template<>
-    inline constexpr __float128 sqrt2_v<__float128>
-      = 1.414213562373095048801688724209698079Q;
-
-  /// sqrt(3)
-  template<>
-    inline constexpr __float128 sqrt3_v<__float128>
-      = 1.732050807568877293527446341505872367Q;
-
-  /// 1/sqrt(3)
-  template<>
-    inline constexpr __float128 inv_sqrt3_v<__float128>
-      = 0.577350269189625764509148780501957456Q;
-
-  /// The Euler-Mascheroni constant
-  template<>
-    inline constexpr __float128 egamma_v<__float128>
-      = 0.577215664901532860606512090082402431Q;
-
-  /// The golden ratio, (1+sqrt(5))/2
-  template<>
-    inline constexpr __float128 phi_v<__float128>
-      = 1.618033988749894848204586834365638118Q;
+#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
+__glibcxx_numbers (__float128, Q);
 #endif // USE_FLOAT128
 
+#undef __glibcxx_numbers
+
 } // namespace numbers
 /// @}
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/std/stdfloat b/libstdc++-v3/include/std/stdfloat
new file mode 100644
index 00000000000..5ab1fa07dbf
--- /dev/null
+++ b/libstdc++-v3/include/std/stdfloat
@@ -0,0 +1,62 @@
+// <stdfloat> -*- C++ -*-
+
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/stdfloat
+ *  This is a Standard C++ Library header.
+ */
+
+#ifndef _GLIBCXX_STDFLOAT
+#define _GLIBCXX_STDFLOAT 1
+
+#if __cplusplus > 202002L
+#include <bits/c++config.h>
+
+namespace std
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  #ifdef __STDCPP_FLOAT16_T__
+  using float16_t = _Float16;
+  #endif
+
+  #ifdef __STDCPP_FLOAT32_T__
+  using float32_t = _Float32;
+  #endif
+
+  #ifdef __STDCPP_FLOAT64_T__
+  using float64_t = _Float64;
+  #endif
+
+  #ifdef __STDCPP_FLOAT128_T__
+  using float128_t = _Float128;
+  #endif
+
+  #ifdef __STDCPP_BFLOAT16_T__
+  using bfloat16_t = __gnu_cxx::__bfloat16_t;
+  #endif
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+#endif // C++23
+#endif // _GLIBCXX_STDFLOAT
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 1d7c3b04a0e..5dc9e1b2921 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -459,6 +459,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __is_floating_point_helper<long double>
     : public true_type { };
 
+#ifdef __STDCPP_FLOAT16_T__
+  template<>
+    struct __is_floating_point_helper<_Float16>
+    : public true_type { };
+#endif
+
+#ifdef __STDCPP_FLOAT32_T__
+  template<>
+    struct __is_floating_point_helper<_Float32>
+    : public true_type { };
+#endif
+
+#ifdef __STDCPP_FLOAT64_T__
+  template<>
+    struct __is_floating_point_helper<_Float64>
+    : public true_type { };
+#endif
+
+#ifdef __STDCPP_FLOAT128_T__
+  template<>
+    struct __is_floating_point_helper<_Float128>
+    : public true_type { };
+#endif
+
+#ifdef __STDCPP_BFLOAT16_T__
+  template<>
+    struct __is_floating_point_helper<__gnu_cxx::__bfloat16_t>
+    : public true_type { };
+#endif
+
 #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
   template<>
     struct __is_floating_point_helper<__float128>
diff --git a/libstdc++-v3/testsuite/18_support/headers/limits/synopsis_cxx23.cc b/libstdc++-v3/testsuite/18_support/headers/limits/synopsis_cxx23.cc
new file mode 100644
index 00000000000..c55100563b3
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/headers/limits/synopsis_cxx23.cc
@@ -0,0 +1,43 @@
+// { dg-options "-std=gnu++2b" }
+// { dg-do compile { target c++23 } }
+// { dg-require-normal-namespace "" }
+
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <limits>
+#include <stdfloat>
+
+namespace std {
+  template<class T> class numeric_limits;
+
+#if defined(__STDCPP_FLOAT16_T__)
+  template<> class numeric_limits<float16_t>;
+#endif
+#if defined(__STDCPP_FLOAT32_T__)
+  template<> class numeric_limits<float32_t>;
+#endif
+#if defined(__STDCPP_FLOAT64_T__)
+  template<> class numeric_limits<float64_t>;
+#endif
+#if defined(__STDCPP_FLOAT128_T__)
+  template<> class numeric_limits<float128_t>;
+#endif
+#if defined(__STDCPP_BFLOAT16_T__)
+  template<> class numeric_limits<bfloat16_t>;
+#endif
+}
diff --git a/libstdc++-v3/testsuite/18_support/headers/stdfloat/types_std.cc b/libstdc++-v3/testsuite/18_support/headers/stdfloat/types_std.cc
new file mode 100644
index 00000000000..d8528012189
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/headers/stdfloat/types_std.cc
@@ -0,0 +1,40 @@
+// { dg-options "-std=gnu++2b" }
+// { dg-do compile { target c++23 } }
+
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <stdfloat>
+
+namespace gnu
+{
+#if defined(__STDCPP_FLOAT16_T__)
+  typedef std::float16_t t1;
+#endif
+#if defined(__STDCPP_FLOAT32_T__)
+  typedef std::float32_t t2;
+#endif
+#if defined(__STDCPP_FLOAT64_T__)
+  typedef std::float64_t t3;
+#endif
+#if defined(__STDCPP_FLOAT128_T__)
+  typedef std::float128_t t4;
+#endif
+#if defined(__STDCPP_BFLOAT16_T__)
+  typedef std::bfloat16_t t5;
+#endif
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c++23.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c++23.cc
new file mode 100644
index 00000000000..0fda6a7d061
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c++23.cc
@@ -0,0 +1,96 @@
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do link { target c++23 } }
+// { dg-excess-errors "" { target uclibc } }
+
+#include <cmath>
+#include <stdfloat>
+
+void fpclassify() { }
+
+void isfinite() { }
+
+void isinf() { }
+
+void isnan() { }
+
+void isnormal() { }
+
+void signbit() { }
+
+void isgreater() { }
+
+void isgreaterequal() { }
+
+void isless() { }
+
+void islessequal() { }
+
+void islessgreater() { }
+
+void isunordered() { }
+
+#if _GLIBCXX_USE_C99_MATH
+template <typename _Tp, typename _Up = _Tp>
+  void test_c99_classify()
+  {
+    typedef _Tp fp_type_one;
+    typedef _Up fp_type_two;
+    fp_type_one f1 = _Tp(1.0);
+    fp_type_two f2 = _Up(3.0);
+    int resi;
+    volatile bool res;
+
+    resi = std::fpclassify(f1);
+    res = std::isfinite(f2);
+    res = std::isinf(f1);
+    res = std::isnan(f2);
+    res = std::isnormal(f1);
+    res = std::signbit(f2);
+    res = std::isgreater(f1, f2);
+    res = std::isgreaterequal(f1, f2);
+    res = std::isless(f1, f2);
+    res = std::islessequal(f1,f2);
+    res = std::islessgreater(f1, f2);
+    res = std::isunordered(f1, f2);
+    resi = resi; // Suppress unused warning.
+    res = res;
+  }
+#endif
+
+int main()
+{
+#if _GLIBCXX_USE_C99_MATH
+#ifdef __STDCPP_FLOAT16_T__
+  test_c99_classify<std::float16_t>();
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+  test_c99_classify<std::float32_t>();
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+  test_c99_classify<std::float64_t>();
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+  test_c99_classify<std::float128_t>();
+#endif
+#ifdef __STDCPP_BFLOAT16_T__
+  test_c99_classify<std::bfloat16_t>();
+#endif
+#endif
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_std_c++23.cc b/libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_std_c++23.cc
new file mode 100644
index 00000000000..bc8866227ef
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_std_c++23.cc
@@ -0,0 +1,146 @@
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do link { target c++23 } }
+
+#include <stdfloat>
+#include <cmath>
+
+template <typename T>
+__attribute__((__noipa__)) void
+test_functions (T *p, int *q, long int *r, long long int *s)
+{
+  p[0] = std::acos (p[0]);
+  p[1] = std::asin (p[1]);
+  p[2] = std::atan (p[2]);
+  p[3] = std::cos (p[3]);
+  p[4] = std::sin (p[4]);
+  p[5] = std::tan (p[5]);
+  p[6] = std::acosh (p[6]);
+  p[7] = std::asinh (p[7]);
+  p[8] = std::atanh (p[8]);
+  p[9] = std::cosh (p[9]);
+  p[10] = std::sinh (p[10]);
+  p[11] = std::tanh (p[11]);
+  p[12] = std::exp (p[12]);
+  p[13] = std::exp2 (p[13]);
+  p[14] = std::expm1 (p[14]);
+  p[15] = std::log (p[15]);
+  p[16] = std::log10 (p[16]);
+  p[17] = std::log1p (p[17]);
+  p[18] = std::log2 (p[18]);
+  p[19] = std::logb (p[19]);
+  p[20] = std::cbrt (p[20]);
+  p[21] = std::fabs (p[21]);
+  p[22] = std::sqrt (p[22]);
+  p[23] = std::erf (p[23]);
+  p[24] = std::erfc (p[24]);
+  p[25] = std::lgamma (p[25]);
+  p[26] = std::tgamma (p[26]);
+  p[27] = std::ceil (p[27]);
+  p[28] = std::floor (p[28]);
+  p[29] = std::nearbyint (p[29]);
+  p[30] = std::rint (p[30]);
+  p[31] = std::round (p[31]);
+  p[32] = std::trunc (p[32]);
+  p[33] = std::atan2 (p[33], p[100]);
+  p[34] = std::hypot (p[34], p[101]);
+  p[35] = std::pow (p[35], p[102]);
+  p[36] = std::fmod (p[36], p[103]);
+  p[37] = std::remainder (p[37], p[104]);
+  p[38] = std::copysign (p[38], p[105]);
+//  p[39] = std::nextafter (p[39], p[106]);
+  p[40] = std::fdim (p[40], p[107]);
+  p[41] = std::fmax (p[41], p[108]);
+  p[42] = std::fmin (p[42], p[109]);
+  p[43] = std::atan2 (p[43], p[110]);
+  p[44] = std::frexp (p[44], q + 0);
+  q[1] = std::ilogb (p[45]);
+  p[46] = std::ldexp (p[46], q[2]);
+  p[47] = std::modf (p[47], p + 111);
+  p[48] = std::scalbn (p[48], q[3]);
+  p[49] = std::scalbln (p[49], r[0]);
+  p[50] = std::hypot (p[50], p[111], p[112]);
+  r[1] = std::lrint (p[51]);
+  s[0] = std::llrint (p[52]);
+  r[2] = std::lround (p[53]);
+  s[1] = std::llround (p[54]);
+  p[55] = std::remquo (p[55], p[113], q + 4);
+  p[56] = std::fma (p[56], p[114], p[115]);
+  p[57] = std::lerp (p[57], p[116], p[117]);
+  p[58] = std::assoc_laguerre (q[5], q[6], p[58]);
+  p[59] = std::assoc_legendre (q[7], q[8], p[59]);
+  p[60] = std::beta (p[60], p[118]);
+  p[61] = std::comp_ellint_1 (p[61]);
+  p[62] = std::comp_ellint_2 (p[62]);
+  p[63] = std::comp_ellint_3 (p[63], p[119]);
+  p[64] = std::cyl_bessel_i (p[64], p[120]);
+  p[65] = std::cyl_bessel_j (p[65], p[121]);
+  p[66] = std::cyl_bessel_k (p[66], p[122]);
+  p[67] = std::cyl_neumann (p[67], p[123]);
+  p[68] = std::ellint_1 (p[68], p[124]);
+  p[69] = std::ellint_2 (p[69], p[125]);
+  p[70] = std::ellint_3 (p[70], p[126], p[127]);
+  p[71] = std::expint (p[71]);
+  p[72] = std::hermite (q[9], p[72]);
+  p[73] = std::laguerre (q[10], p[73]);
+  p[74] = std::legendre (q[11], p[72]);
+  p[75] = std::riemann_zeta (p[75]);
+  p[76] = std::sph_bessel (q[12], p[76]);
+  p[77] = std::sph_legendre (q[13], q[14], p[77]);
+  p[78] = std::sph_neumann (q[15], q[16], p[78]);
+}
+
+int
+main ()
+{
+  int q[17] = {};
+  long int r[16] = {};
+  long long int s[16] = {};
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  {
+    std::float16_t p[128] = {};
+    test_functions (p, q, r, s);
+  }
+#endif
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  {
+    std::float32_t p[128] = {};
+    test_functions (p, q, r, s);
+  }
+#endif
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  {
+    std::float64_t p[128] = {};
+    test_functions (p, q, r, s);
+  }
+#endif
+#if defined(__STDCPP_FLOAT128_T__) \
+    && (defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY128) \
+	|| defined(_GLIBCXX_HAVE_FLOAT128_MATH))
+  {
+    std::float128_t p[128] = {};
+    test_functions (p, q, r, s);
+  }
+#endif
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  {
+    std::bfloat16_t p[128] = {};
+    test_functions (p, q, r, s);
+  }
+#endif
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/numbers/4.cc b/libstdc++-v3/testsuite/26_numerics/numbers/4.cc
new file mode 100644
index 00000000000..4a599887acd
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/numbers/4.cc
@@ -0,0 +1,122 @@
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2b" }
+// { dg-do compile { target c++23 } }
+
+#include <numbers>
+#include <stdfloat>
+
+#if defined(__STDCPP_FLOAT16_T__)
+void
+test01()
+{
+  const std::float16_t* d1  = &std::numbers::e_v<std::float16_t>;
+  const std::float16_t* d2  = &std::numbers::log2e_v<std::float16_t>;
+  const std::float16_t* d3  = &std::numbers::log10e_v<std::float16_t>;
+  const std::float16_t* d4  = &std::numbers::pi_v<std::float16_t>;
+  const std::float16_t* d5  = &std::numbers::inv_pi_v<std::float16_t>;
+  const std::float16_t* d6  = &std::numbers::inv_sqrtpi_v<std::float16_t>;
+  const std::float16_t* d7  = &std::numbers::ln2_v<std::float16_t>;
+  const std::float16_t* d8  = &std::numbers::ln10_v<std::float16_t>;
+  const std::float16_t* d9  = &std::numbers::sqrt2_v<std::float16_t>;
+  const std::float16_t* d10 = &std::numbers::sqrt3_v<std::float16_t>;
+  const std::float16_t* d11 = &std::numbers::inv_sqrt3_v<std::float16_t>;
+  const std::float16_t* d12 = &std::numbers::egamma_v<std::float16_t>;
+  const std::float16_t* d13 = &std::numbers::phi_v<std::float16_t>;
+}
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__)
+void
+test02()
+{
+  const std::float32_t* d1  = &std::numbers::e_v<std::float32_t>;
+  const std::float32_t* d2  = &std::numbers::log2e_v<std::float32_t>;
+  const std::float32_t* d3  = &std::numbers::log10e_v<std::float32_t>;
+  const std::float32_t* d4  = &std::numbers::pi_v<std::float32_t>;
+  const std::float32_t* d5  = &std::numbers::inv_pi_v<std::float32_t>;
+  const std::float32_t* d6  = &std::numbers::inv_sqrtpi_v<std::float32_t>;
+  const std::float32_t* d7  = &std::numbers::ln2_v<std::float32_t>;
+  const std::float32_t* d8  = &std::numbers::ln10_v<std::float32_t>;
+  const std::float32_t* d9  = &std::numbers::sqrt2_v<std::float32_t>;
+  const std::float32_t* d10 = &std::numbers::sqrt3_v<std::float32_t>;
+  const std::float32_t* d11 = &std::numbers::inv_sqrt3_v<std::float32_t>;
+  const std::float32_t* d12 = &std::numbers::egamma_v<std::float32_t>;
+  const std::float32_t* d13 = &std::numbers::phi_v<std::float32_t>;
+}
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__)
+void
+test03()
+{
+  const std::float64_t* d1  = &std::numbers::e_v<std::float64_t>;
+  const std::float64_t* d2  = &std::numbers::log2e_v<std::float64_t>;
+  const std::float64_t* d3  = &std::numbers::log10e_v<std::float64_t>;
+  const std::float64_t* d4  = &std::numbers::pi_v<std::float64_t>;
+  const std::float64_t* d5  = &std::numbers::inv_pi_v<std::float64_t>;
+  const std::float64_t* d6  = &std::numbers::inv_sqrtpi_v<std::float64_t>;
+  const std::float64_t* d7  = &std::numbers::ln2_v<std::float64_t>;
+  const std::float64_t* d8  = &std::numbers::ln10_v<std::float64_t>;
+  const std::float64_t* d9  = &std::numbers::sqrt2_v<std::float64_t>;
+  const std::float64_t* d10 = &std::numbers::sqrt3_v<std::float64_t>;
+  const std::float64_t* d11 = &std::numbers::inv_sqrt3_v<std::float64_t>;
+  const std::float64_t* d12 = &std::numbers::egamma_v<std::float64_t>;
+  const std::float64_t* d13 = &std::numbers::phi_v<std::float64_t>;
+}
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__)
+void
+test04()
+{
+  const std::float128_t* d1  = &std::numbers::e_v<std::float128_t>;
+  const std::float128_t* d2  = &std::numbers::log2e_v<std::float128_t>;
+  const std::float128_t* d3  = &std::numbers::log10e_v<std::float128_t>;
+  const std::float128_t* d4  = &std::numbers::pi_v<std::float128_t>;
+  const std::float128_t* d5  = &std::numbers::inv_pi_v<std::float128_t>;
+  const std::float128_t* d6  = &std::numbers::inv_sqrtpi_v<std::float128_t>;
+  const std::float128_t* d7  = &std::numbers::ln2_v<std::float128_t>;
+  const std::float128_t* d8  = &std::numbers::ln10_v<std::float128_t>;
+  const std::float128_t* d9  = &std::numbers::sqrt2_v<std::float128_t>;
+  const std::float128_t* d10 = &std::numbers::sqrt3_v<std::float128_t>;
+  const std::float128_t* d11 = &std::numbers::inv_sqrt3_v<std::float128_t>;
+  const std::float128_t* d12 = &std::numbers::egamma_v<std::float128_t>;
+  const std::float128_t* d13 = &std::numbers::phi_v<std::float128_t>;
+}
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__)
+void
+test05()
+{
+  const std::bfloat16_t* d1  = &std::numbers::e_v<std::bfloat16_t>;
+  const std::bfloat16_t* d2  = &std::numbers::log2e_v<std::bfloat16_t>;
+  const std::bfloat16_t* d3  = &std::numbers::log10e_v<std::bfloat16_t>;
+  const std::bfloat16_t* d4  = &std::numbers::pi_v<std::bfloat16_t>;
+  const std::bfloat16_t* d5  = &std::numbers::inv_pi_v<std::bfloat16_t>;
+  const std::bfloat16_t* d6  = &std::numbers::inv_sqrtpi_v<std::bfloat16_t>;
+  const std::bfloat16_t* d7  = &std::numbers::ln2_v<std::bfloat16_t>;
+  const std::bfloat16_t* d8  = &std::numbers::ln10_v<std::bfloat16_t>;
+  const std::bfloat16_t* d9  = &std::numbers::sqrt2_v<std::bfloat16_t>;
+  const std::bfloat16_t* d10 = &std::numbers::sqrt3_v<std::bfloat16_t>;
+  const std::bfloat16_t* d11 = &std::numbers::inv_sqrt3_v<std::bfloat16_t>;
+  const std::bfloat16_t* d12 = &std::numbers::egamma_v<std::bfloat16_t>;
+  const std::bfloat16_t* d13 = &std::numbers::phi_v<std::bfloat16_t>;
+}
+#endif
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_float/requirements_cxx23.cc b/libstdc++-v3/testsuite/29_atomics/atomic_float/requirements_cxx23.cc
new file mode 100644
index 00000000000..9c33b2597da
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_float/requirements_cxx23.cc
@@ -0,0 +1,112 @@
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2b" }
+// { dg-do compile { target c++23 } }
+
+#include <atomic>
+#include <stdfloat>
+
+#if defined(__STDCPP_FLOAT16_T__)
+void
+test01()
+{
+  using A = std::atomic<std::float16_t>;
+  static_assert( std::is_standard_layout_v<A> );
+  static_assert( !std::is_trivially_default_constructible_v<A> );
+  static_assert( std::is_trivially_destructible_v<A> );
+  static_assert( std::is_same_v<A::value_type, std::float16_t> );
+  static_assert( std::is_same_v<A::difference_type, A::value_type> );
+  static_assert( !std::is_copy_constructible_v<A> );
+  static_assert( !std::is_move_constructible_v<A> );
+  static_assert( !std::is_copy_assignable_v<A> );
+  static_assert( !std::is_move_assignable_v<A> );
+  static_assert( !std::is_assignable_v<volatile A&, const A&> );
+}
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__)
+void
+test02()
+{
+  using A = std::atomic<std::float32_t>;
+  static_assert( std::is_standard_layout_v<A> );
+  static_assert( !std::is_trivially_default_constructible_v<A> );
+  static_assert( std::is_trivially_destructible_v<A> );
+  static_assert( std::is_same_v<A::value_type, std::float32_t> );
+  static_assert( std::is_same_v<A::difference_type, A::value_type> );
+  static_assert( !std::is_copy_constructible_v<A> );
+  static_assert( !std::is_move_constructible_v<A> );
+  static_assert( !std::is_copy_assignable_v<A> );
+  static_assert( !std::is_move_assignable_v<A> );
+  static_assert( !std::is_assignable_v<volatile A&, const A&> );
+}
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__)
+void
+test03()
+{
+  using A = std::atomic<std::float64_t>;
+  static_assert( std::is_standard_layout_v<A> );
+  static_assert( !std::is_trivially_default_constructible_v<A> );
+  static_assert( std::is_trivially_destructible_v<A> );
+  static_assert( std::is_same_v<A::value_type, std::float64_t> );
+  static_assert( std::is_same_v<A::difference_type, A::value_type> );
+  static_assert( !std::is_copy_constructible_v<A> );
+  static_assert( !std::is_move_constructible_v<A> );
+  static_assert( !std::is_copy_assignable_v<A> );
+  static_assert( !std::is_move_assignable_v<A> );
+  static_assert( !std::is_assignable_v<volatile A&, const A&> );
+}
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__)
+void
+test04()
+{
+  using A = std::atomic<std::float128_t>;
+  static_assert( std::is_standard_layout_v<A> );
+  static_assert( !std::is_trivially_default_constructible_v<A> );
+  static_assert( std::is_trivially_destructible_v<A> );
+  static_assert( std::is_same_v<A::value_type, std::float128_t> );
+  static_assert( std::is_same_v<A::difference_type, A::value_type> );
+  static_assert( !std::is_copy_constructible_v<A> );
+  static_assert( !std::is_move_constructible_v<A> );
+  static_assert( !std::is_copy_assignable_v<A> );
+  static_assert( !std::is_move_assignable_v<A> );
+  static_assert( !std::is_assignable_v<volatile A&, const A&> );
+}
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__)
+void
+test05()
+{
+  using A = std::atomic<std::bfloat16_t>;
+  static_assert( std::is_standard_layout_v<A> );
+  static_assert( !std::is_trivially_default_constructible_v<A> );
+  static_assert( std::is_trivially_destructible_v<A> );
+  static_assert( std::is_same_v<A::value_type, std::bfloat16_t> );
+  static_assert( std::is_same_v<A::difference_type, A::value_type> );
+  static_assert( !std::is_copy_constructible_v<A> );
+  static_assert( !std::is_move_constructible_v<A> );
+  static_assert( !std::is_copy_assignable_v<A> );
+  static_assert( !std::is_move_assignable_v<A> );
+  static_assert( !std::is_assignable_v<volatile A&, const A&> );
+}
+#endif

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-10-18  9:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-18  9:43 [gcc r13-3354] libstdc++: Partial library support for std::float{16, 32, 64, 128}_t and std::bfloat16_t Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).