diff mbox series

libstdc++-v3: Fix cmath math declarations and stub support for hppa64-*-hpux11*

Message ID ZeDo7PAxVzlhSCpt@mx3210.localdomain
State New
Headers show
Series libstdc++-v3: Fix cmath math declarations and stub support for hppa64-*-hpux11* | expand

Commit Message

John David Anglin Feb. 29, 2024, 8:28 p.m. UTC
This change fixes the C99 math function support in <cmath> on
hppa64-*-hpux11*.

Tested on hppa64-hp-hpux11.11 and x86_64-linux-gnu.  See:
https://gcc.gnu.org/pipermail/gcc-testresults/2024-February/809158.html
https://gcc.gnu.org/pipermail/gcc-testresults/2024-February/809101.html

Okay for trunk?

Dave
---

Fix cmath math declarations and stub support for hppa64-*-hpux11*

This change fixes the following issues:

1) When the target host system doesn't support the full set of C99
functions, the stub replacements are not declared by cmath.  As a
result, stub replacements do not become members of namespace std.

2) Some using statements for float and long double C99 functions
are surrounded by a _GLIBCXX_HAVE_* #ifdef.  For example,
#ifdef _GLIBCXX_HAVE_ACOSF
  using ::acosf;
#endif
As a result, missing float and long double functions never become
a member of std even though there is stub support for all of them.

3) Undefs for acosf, acosl, etc, are missing.  Adding these should
allow PR86553 to be fixed.

4) Added AC_DEFINE statements for HAVE_CBRTF, HAVE_COPYSIGNF,
HAVE_HYPOTF, HAVE_LOG2F and HAVE_NEXTAFTERF to crossconfig.m4
for hpux host.

5) Added additional checks to linkage.m4.

6) Added stubs for missing float, double and long double C99
functions.

	PR libstdc++/114101

libstdc++-v3/ChangeLog:

	* config/os/hpux/os_defines.h (_GLIBCXX_USE_C99_MATH_FUNCS): Define.
	(_GLIBCXX_USE_C99_MATH_TR1): Define.
	(_GLIBCXX_USE_BUILTIN_FMA): Define if _PA_RISC2_0 host.
	(_GLIBCXX_USE_BUILTIN_FMAF): Likewise.
	* crossconfig.m4: Add AC_DEFINE statements for HAVE_CBRTF,
	HAVE_COPYSIGNF, HAVE_HYPOTF, HAVE_LOG2F and HAVE_NEXTAFTERF.
	* include/c_global/cmath: Add #undef statements for acosf,
	acosl, etc.  Add declarations for acosf, acosl, etc.  Likewise,
	add declarations for acoshf, acoshl, etc, for C++11.
	* libstdc++-v3/include/tr1/cmath: Add declarations for acosf,
	acosl, etc.
	* linkage.m4: Add checks for fma, nexttoward, scalbln, tgamma,
	cbrtf, copysignf, expm1f, log2f, nanf, nextafterf, nexttowardf,
	expm1l, ilogbl, nanl, nextafterl, nexttowardl, scalblnl,
	scalbnl.
	* src/c++98/Makefile.am: Add math_stubs_double.cc to sources.
	* src/c++98/math_stubs_double.cc: New file.
	* src/c++98/math_stubs_float.cc (scalbnf): New stub.
	(lgammaf, tgammaf, erff, erfcf, remquof, fdimf, nearbyintf,
	exp2f, rintf, lrintf, llrintf, fmaxf, fminf, log1pf, truncf,
	asinhf, acoshf, atanhf, scalblnf, lroundf, llroundf, roundf,
	remainderf, logbf, ilogbf, expm1f, nextafterf, nexttowardf,
	nanf): Likewise.
	* src/c++98/math_stubs_long_double.cc (ilogbl): New stub.
	(lgammal, log1pl, nanl, nearbyintl, nextafterl, nexttowardl,
	scalblnl, scalbnl, tgammal): Likewise.
	* configure: Regenerate.
	* config.h.in: Regenerate.
	* src/c++98/Makefile.in: Regenerate.
diff mbox series

Patch

diff --git a/libstdc++-v3/config/os/hpux/os_defines.h b/libstdc++-v3/config/os/hpux/os_defines.h
index 38c1c38af0c..9ab1af42bda 100644
--- a/libstdc++-v3/config/os/hpux/os_defines.h
+++ b/libstdc++-v3/config/os/hpux/os_defines.h
@@ -79,6 +79,18 @@  namespace std
 
 #define _GLIBCXX_USE_LONG_LONG 1
 
+// Import C99 functions in <math.h> in <cmath> in namespace std in C++11.
+// Missing functions are handled by stubs.  The fma, nexttoward, scalbln
+// and tgamma are missing in HP-UX 11.  Many float variants are supported.
+#define _GLIBCXX_USE_C99_MATH_FUNCS 1
+#define _GLIBCXX_USE_C99_MATH_TR1 1
+
+#ifdef _PA_RISC2_0
+// Float and double fma are supported directly in hardware.
+#define _GLIBCXX_USE_BUILTIN_FMA 1
+#define _GLIBCXX_USE_BUILTIN_FMAF 1
+#endif
+
 // HPUX on IA64 requires vtable to be 64 bit aligned even at 32 bit
 // mode.  We need to pad the vtable structure to achieve this.
 #if !defined(_LP64) && defined (__ia64__)
diff --git a/libstdc++-v3/crossconfig.m4 b/libstdc++-v3/crossconfig.m4
index b3269cb88e0..c6b08be5df5 100644
--- a/libstdc++-v3/crossconfig.m4
+++ b/libstdc++-v3/crossconfig.m4
@@ -152,14 +152,10 @@  case "${host}" in
     AC_DEFINE(HAVE_ACOSF)
     AC_DEFINE(HAVE_ASINF)
     AC_DEFINE(HAVE_ATANF)
+    AC_DEFINE(HAVE_ATAN2F)
     AC_DEFINE(HAVE_COSF)
     AC_DEFINE(HAVE_COSHF)
-    AC_DEFINE(HAVE_SINF)
-    AC_DEFINE(HAVE_SINHF)
-    AC_DEFINE(HAVE_TANF)
-    AC_DEFINE(HAVE_TANHF)
     AC_DEFINE(HAVE_EXPF)
-    AC_DEFINE(HAVE_ATAN2F)
     AC_DEFINE(HAVE_FABSF)
     AC_DEFINE(HAVE_FMODF)
     AC_DEFINE(HAVE_FREXPF)
@@ -167,7 +163,16 @@  case "${host}" in
     AC_DEFINE(HAVE_LOG10F)
     AC_DEFINE(HAVE_MODF)
     AC_DEFINE(HAVE_POWF)
+    AC_DEFINE(HAVE_SINF)
+    AC_DEFINE(HAVE_SINHF)
     AC_DEFINE(HAVE_SQRTF)
+    AC_DEFINE(HAVE_TANF)
+    AC_DEFINE(HAVE_TANHF)
+    AC_DEFINE(HAVE_CBRTF)
+    AC_DEFINE(HAVE_COPYSIGNF)
+    AC_DEFINE(HAVE_HYPOTF)
+    AC_DEFINE(HAVE_LOG2F)
+    AC_DEFINE(HAVE_NEXTAFTERF)
 
     # GLIBCXX_CHECK_STDLIB_SUPPORT
     AC_DEFINE(HAVE_STRTOLD)
diff --git a/libstdc++-v3/include/c_global/cmath b/libstdc++-v3/include/c_global/cmath
index dd0174f1987..9bc7882b072 100644
--- a/libstdc++-v3/include/c_global/cmath
+++ b/libstdc++-v3/include/c_global/cmath
@@ -58,253 +58,797 @@ 
 // Get rid of those macros defined in <math.h> in lieu of real functions.
 #undef div
 #undef acos
+#undef acosf
+#undef acosl
 #undef asin
+#undef asinf
+#undef asinl
 #undef atan
+#undef atanf
+#undef atanl
 #undef atan2
+#undef atan2f
+#undef atan2l
 #undef ceil
+#undef ceilf
+#undef ceill
 #undef cos
+#undef cosf
+#undef cosl
 #undef cosh
+#undef coshf
+#undef coshl
 #undef exp
+#undef expf
+#undef expl
 #undef fabs
+#undef fabsf
+#undef fabsl
 #undef floor
+#undef floorf
+#undef floorl
 #undef fmod
+#undef fmodf
+#undef fmodl
 #undef frexp
+#undef frexpf
+#undef frexpl
 #undef ldexp
+#undef ldexpf
+#undef ldexpl
 #undef log
+#undef logf
+#undef logl
 #undef log10
+#undef log10f
+#undef log10l
 #undef modf
+#undef modff
+#undef modfl
 #undef pow
+#undef powf
+#undef powl
 #undef sin
+#undef sinf
+#undef sinl
 #undef sinh
+#undef sinhf
+#undef sinhl
 #undef sqrt
+#undef sqrtf
+#undef sqrtl
 #undef tan
+#undef tanf
+#undef tanl
 #undef tanh
+#undef tanhf
+#undef tanhl
 
-extern "C++"
-{
-namespace std _GLIBCXX_VISIBILITY(default)
+extern "C"
 {
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  using ::acos;
-
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
-  inline _GLIBCXX_CONSTEXPR float
-  acos(float __x)
-  { return __builtin_acosf(__x); }
-
-  inline _GLIBCXX_CONSTEXPR long double
-  acos(long double __x)
-  { return __builtin_acosl(__x); }
+// Provide declarations for missing C99 functions. 
+#ifndef _GLIBCXX_HAVE_ACOSF
+  float acosf(float);
 #endif
-
-  template<typename _Tp>
-    inline _GLIBCXX_CONSTEXPR
-    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
-                                    double>::__type
-    acos(_Tp __x)
-    { return __builtin_acos(__x); }
-
-  using ::asin;
-
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
-  inline _GLIBCXX_CONSTEXPR float
-  asin(float __x)
-  { return __builtin_asinf(__x); }
-
-  inline _GLIBCXX_CONSTEXPR long double
-  asin(long double __x)
-  { return __builtin_asinl(__x); }
+#ifndef _GLIBCXX_HAVE_ACOSL
+  long double acosl(long double);
 #endif
-
-  template<typename _Tp>
-    inline _GLIBCXX_CONSTEXPR
-    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
-                                    double>::__type
-    asin(_Tp __x)
-    { return __builtin_asin(__x); }
-
-  using ::atan;
-
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
-  inline _GLIBCXX_CONSTEXPR float
-  atan(float __x)
-  { return __builtin_atanf(__x); }
-
-  inline _GLIBCXX_CONSTEXPR long double
-  atan(long double __x)
-  { return __builtin_atanl(__x); }
+#ifndef _GLIBCXX_HAVE_ASINF
+  float asinf(float);
 #endif
-
-  template<typename _Tp>
-    inline _GLIBCXX_CONSTEXPR
-    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
-                                    double>::__type
-    atan(_Tp __x)
-    { return __builtin_atan(__x); }
-
-  using ::atan2;
-
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
-  inline _GLIBCXX_CONSTEXPR float
-  atan2(float __y, float __x)
-  { return __builtin_atan2f(__y, __x); }
-
-  inline _GLIBCXX_CONSTEXPR long double
-  atan2(long double __y, long double __x)
-  { return __builtin_atan2l(__y, __x); }
+#ifndef _GLIBCXX_HAVE_ASINL
+  long double asinl(long double);
 #endif
-
-  using ::ceil;
-
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
-  inline _GLIBCXX_CONSTEXPR float
-  ceil(float __x)
-  { return __builtin_ceilf(__x); }
-
-  inline _GLIBCXX_CONSTEXPR long double
-  ceil(long double __x)
-  { return __builtin_ceill(__x); }
+#ifndef _GLIBCXX_HAVE_ATANF
+  float atanf(float);
 #endif
-
-  template<typename _Tp>
-    inline _GLIBCXX_CONSTEXPR
-    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
-                                    double>::__type
-    ceil(_Tp __x)
-    { return __builtin_ceil(__x); }
-
-  using ::cos;
-
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
-  inline _GLIBCXX_CONSTEXPR float
-  cos(float __x)
-  { return __builtin_cosf(__x); }
-
-  inline _GLIBCXX_CONSTEXPR long double
-  cos(long double __x)
-  { return __builtin_cosl(__x); }
+#ifndef _GLIBCXX_HAVE_ATANL
+  long double atanl(long double);
 #endif
-
-  template<typename _Tp>
-    inline _GLIBCXX_CONSTEXPR
-    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
-                                    double>::__type
-    cos(_Tp __x)
-    { return __builtin_cos(__x); }
-
-  using ::cosh;
-
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
-  inline _GLIBCXX_CONSTEXPR float
-  cosh(float __x)
-  { return __builtin_coshf(__x); }
-
-  inline _GLIBCXX_CONSTEXPR long double
-  cosh(long double __x)
-  { return __builtin_coshl(__x); }
+#ifndef _GLIBCXX_HAVE_ATAN2F
+  float atan2f(float, float);
 #endif
-
-  template<typename _Tp>
-    inline _GLIBCXX_CONSTEXPR
-    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
-                                    double>::__type
-    cosh(_Tp __x)
-    { return __builtin_cosh(__x); }
-
-  using ::exp;
-
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
-  inline _GLIBCXX_CONSTEXPR float
-  exp(float __x)
-  { return __builtin_expf(__x); }
-
-  inline _GLIBCXX_CONSTEXPR long double
-  exp(long double __x)
-  { return __builtin_expl(__x); }
+#ifndef _GLIBCXX_HAVE_ATAN2L
+  long double atan2l(long double, long double);
 #endif
-
-  template<typename _Tp>
-    inline _GLIBCXX_CONSTEXPR
-    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
-                                    double>::__type
-    exp(_Tp __x)
-    { return __builtin_exp(__x); }
-
-  using ::fabs;
-
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
-  inline _GLIBCXX_CONSTEXPR float
-  fabs(float __x)
-  { return __builtin_fabsf(__x); }
-
-  inline _GLIBCXX_CONSTEXPR long double
-  fabs(long double __x)
-  { return __builtin_fabsl(__x); }
+#ifndef _GLIBCXX_HAVE_CEILF
+  float ceilf(float);
 #endif
-
-  template<typename _Tp>
-    inline _GLIBCXX_CONSTEXPR
-    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
-                                    double>::__type
-    fabs(_Tp __x)
-    { return __builtin_fabs(__x); }
-
-  using ::floor;
-
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
-  inline _GLIBCXX_CONSTEXPR float
-  floor(float __x)
-  { return __builtin_floorf(__x); }
-
-  inline _GLIBCXX_CONSTEXPR long double
-  floor(long double __x)
-  { return __builtin_floorl(__x); }
+#ifndef _GLIBCXX_HAVE_CEILL
+  long double ceill(long double);
 #endif
-
-  template<typename _Tp>
-    inline _GLIBCXX_CONSTEXPR
-    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
-                                    double>::__type
-    floor(_Tp __x)
-    { return __builtin_floor(__x); }
-
-  using ::fmod;
-
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
-  inline _GLIBCXX_CONSTEXPR float
-  fmod(float __x, float __y)
-  { return __builtin_fmodf(__x, __y); }
-
-  inline _GLIBCXX_CONSTEXPR long double
-  fmod(long double __x, long double __y)
-  { return __builtin_fmodl(__x, __y); }
+#ifndef _GLIBCXX_HAVE_COSF
+  float cosf(float);
 #endif
-
-  using ::frexp;
-
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
-  inline float
-  frexp(float __x, int* __exp)
-  { return __builtin_frexpf(__x, __exp); }
-
-  inline long double
-  frexp(long double __x, int* __exp)
-  { return __builtin_frexpl(__x, __exp); }
+#ifndef _GLIBCXX_HAVE_COSL
+  long double cosl(long double);
 #endif
-
-  template<typename _Tp>
-    inline _GLIBCXX_CONSTEXPR
-    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
-                                    double>::__type
-    frexp(_Tp __x, int* __exp)
-    { return __builtin_frexp(__x, __exp); }
-
-  using ::ldexp;
-
-#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
-  inline _GLIBCXX_CONSTEXPR float
-  ldexp(float __x, int __exp)
+#ifndef _GLIBCXX_HAVE_COSHF
+  float coshf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_COSHL
+  long double coshl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_EXPF
+  float expf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_EXPL
+  long double expl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_FABSF
+  float fabsf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_FABSL
+  long double fabsl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_FLOORF
+  float floorf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_FLOORL
+  long double floorl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_FMODF
+  float fmodf(float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_FMODL
+  long double fmodl(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_FREXPF
+  float frexpf(float, int *);
+#endif
+#ifndef _GLIBCXX_HAVE_FREXPL
+  long double frexpl(long double, int *);
+#endif
+#ifndef _GLIBCXX_HAVE_LDEXPF
+  float ldexpf(float, int);
+#endif
+#ifndef _GLIBCXX_HAVE_LDEXPL
+  long double ldexpl(long double, int);
+#endif
+#ifndef _GLIBCXX_HAVE_LOGF
+  float logf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LOGL
+  long double logl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LOG10F
+  float log10f(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LOG10L
+  long double log10l(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_MODFF
+  float modff(float, float *);
+#endif
+#ifndef _GLIBCXX_HAVE_MODFL
+  long double modfl(long double, long double *);
+#endif
+#ifndef _GLIBCXX_HAVE_POWF
+  float powf(float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_POWL
+  long double powl(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_SINF
+  float sinf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_SINL
+  long double sinl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_SINHF
+  float sinhf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_SINHL
+  long double sinhl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_SQRTF
+  float sqrtf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_SQRTL
+  long double sqrtl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_TANF
+  float tanf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_TANL
+  long double tanl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_TANHF
+  float tanhf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_TANHL
+  long double tanhl(long double);
+#endif
+}
+
+#ifdef _GLIBCXX_USE_C99_MATH_FUNCS
+
+#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
+#undef nearbyint
+#undef nearbyintf
+#undef nearbyintl
+#undef nextafter
+#undef nextafterf
+#undef nextafterl
+#undef nexttoward
+#undef nexttowardf
+#undef nexttowardl
+#undef remainder
+#undef remainderf
+#undef remainderl
+#undef remquo
+#undef remquof
+#undef remquol
+#undef rint
+#undef rintf
+#undef rintl
+#undef round
+#undef roundf
+#undef roundl
+#undef scalbln
+#undef scalblnf
+#undef scalblnl
+#undef scalbn
+#undef scalbnf
+#undef scalbnl
+#undef tgamma
+#undef tgammaf
+#undef tgammal
+#undef trunc
+#undef truncf
+#undef truncl
+
+extern "C"
+{
+#ifndef _GLIBCXX_HAVE_ACOSHF
+  float acoshf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_ACOSHL
+  long double acoshl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_ASINHF
+  float asinhf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_ASINHL
+  long double asinhl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_ATANHF
+  float atanhf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_ATANHL
+  long double atanhl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_CBRTF
+  float cbrtf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_CBRTL
+  long double cbrtl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_COPYSIGNF
+  float copysignf(float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_COPYSIGNL
+  long double copysignl(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_ERFF
+  float erff(float);
+#endif
+#ifndef _GLIBCXX_HAVE_ERFL
+  long double erfl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_ERFCF
+  float erfcf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_ERFCL
+  long double erfcl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_EXP2F
+  float exp2f(float);
+#endif
+#ifndef _GLIBCXX_HAVE_EXP2L
+  long double exp2l(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_EXPM1F
+  float expm1f(float);
+#endif
+#ifndef _GLIBCXX_HAVE_EXPM1L
+  long double expm1l(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_FDIMF
+  float fdimf(float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_FDIML
+  long double fdiml(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_FMA
+  double fma(double, double, double);
+#endif
+#ifndef _GLIBCXX_HAVE_FMAF
+  float fmaf(float, float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_FMAL
+  long double fmal(long double, long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_FMAXF
+  float fmaxf(float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_FMAXL
+  long double fmaxl(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_FMINF
+  float fminf(float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_FMINL
+  long double fminl(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_HYPOTF
+  float hypotf(float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_HYPOTL
+  long double hypotl(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_ILOGBF
+  int ilogbf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_ILOGBL
+  int ilogbl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LGAMMAF
+  float lgammaf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LGAMMAL
+  long double lgammal(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LLRINTF
+  long long llrintf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LLRINTL
+  long long llrintl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LLROUNDL
+  long long llroundl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LLROUNDF
+  long long llroundf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LOG1PF
+  float log1pf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LOG1PL
+  long double log1pl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LOG2F
+  float log2f(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LOG2L
+  long double log2l(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LOGBF
+  float logbf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LOGBL
+  long double logbl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LRINTF
+  long lrintf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LRINTL
+  long lrintl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LROUNDF
+  long lroundf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LROUNDL
+  long lroundl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_NANF
+  float nanf(const char *);
+#endif
+#ifndef _GLIBCXX_HAVE_NANL
+  long double nanl(const char *);
+#endif
+#ifndef _GLIBCXX_HAVE_NEARBYINTF
+  float nearbyintf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_NEARBYINTL
+  long double nearbyintl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_NEXTAFTERF
+  float nextafterf(float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_NEXTAFTERL
+  long double nextafterl(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_NEXTTOWARD
+  double nexttoward(double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_NEXTTOWARDF
+  float nexttowardf(float, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_NEXTTOWARDL
+  long double nexttowardl(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_REMAINDERF
+  float remainderf(float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_REMAINDERL
+  long double remainderl(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_REMQUOF
+  float remquof(float, float, int *);
+#endif
+#ifndef _GLIBCXX_HAVE_REMQUOL
+  long double remquol(long double, long double, int *);
+#endif
+#ifndef _GLIBCXX_HAVE_RINTF
+  float rintf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_RINTL
+  long double rintl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_ROUNDF
+  float roundf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_ROUNDL
+  long double roundl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_SCALBLN
+  double scalbln(double, long);
+#endif
+#ifndef _GLIBCXX_HAVE_SCALBLNF
+  float scalblnf(float, long);
+#endif
+#ifndef _GLIBCXX_HAVE_SCALBLNL
+  long double scalblnl(long double, long);
+#endif
+#ifndef _GLIBCXX_HAVE_SCALBNF
+  float scalbnf(float, int);
+#endif
+#ifndef _GLIBCXX_HAVE_SCALBNL
+  long double scalbnl(long double, int);
+#endif
+#ifndef _GLIBCXX_HAVE_TGAMMA
+  double tgamma(double);
+#endif
+#ifndef _GLIBCXX_HAVE_TGAMMAF
+  float tgammaf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_TGAMMAL
+  long double tgammal(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_TRUNCF
+  float truncf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_TRUNCL
+  long double truncl(long double);
+#endif
+}
+#endif
+
+extern "C++"
+{
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  using ::acos;
+  using ::acosf;
+  using ::acosl;
+
+#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
+  inline _GLIBCXX_CONSTEXPR float
+  acos(float __x)
+  { return __builtin_acosf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR long double
+  acos(long double __x)
+  { return __builtin_acosl(__x); }
+#endif
+
+  template<typename _Tp>
+    inline _GLIBCXX_CONSTEXPR
+    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
+                                    double>::__type
+    acos(_Tp __x)
+    { return __builtin_acos(__x); }
+
+  using ::asin;
+  using ::asinf;
+  using ::asinl;
+
+#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
+  inline _GLIBCXX_CONSTEXPR float
+  asin(float __x)
+  { return __builtin_asinf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR long double
+  asin(long double __x)
+  { return __builtin_asinl(__x); }
+#endif
+
+  template<typename _Tp>
+    inline _GLIBCXX_CONSTEXPR
+    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
+                                    double>::__type
+    asin(_Tp __x)
+    { return __builtin_asin(__x); }
+
+  using ::atan;
+  using ::atanf;
+  using ::atanl;
+
+#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
+  inline _GLIBCXX_CONSTEXPR float
+  atan(float __x)
+  { return __builtin_atanf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR long double
+  atan(long double __x)
+  { return __builtin_atanl(__x); }
+#endif
+
+  template<typename _Tp>
+    inline _GLIBCXX_CONSTEXPR
+    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
+                                    double>::__type
+    atan(_Tp __x)
+    { return __builtin_atan(__x); }
+
+  using ::atan2;
+  using ::atan2f;
+  using ::atan2l;
+
+#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
+  inline _GLIBCXX_CONSTEXPR float
+  atan2(float __y, float __x)
+  { return __builtin_atan2f(__y, __x); }
+
+  inline _GLIBCXX_CONSTEXPR long double
+  atan2(long double __y, long double __x)
+  { return __builtin_atan2l(__y, __x); }
+#endif
+
+  using ::ceil;
+  using ::ceilf;
+  using ::ceill;
+
+#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
+  inline _GLIBCXX_CONSTEXPR float
+  ceil(float __x)
+  { return __builtin_ceilf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR long double
+  ceil(long double __x)
+  { return __builtin_ceill(__x); }
+#endif
+
+  template<typename _Tp>
+    inline _GLIBCXX_CONSTEXPR
+    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
+                                    double>::__type
+    ceil(_Tp __x)
+    { return __builtin_ceil(__x); }
+
+  using ::cos;
+  using ::cosf;
+  using ::cosl;
+
+#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
+  inline _GLIBCXX_CONSTEXPR float
+  cos(float __x)
+  { return __builtin_cosf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR long double
+  cos(long double __x)
+  { return __builtin_cosl(__x); }
+#endif
+
+  template<typename _Tp>
+    inline _GLIBCXX_CONSTEXPR
+    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
+                                    double>::__type
+    cos(_Tp __x)
+    { return __builtin_cos(__x); }
+
+  using ::cosh;
+  using ::coshf;
+  using ::coshl;
+
+#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
+  inline _GLIBCXX_CONSTEXPR float
+  cosh(float __x)
+  { return __builtin_coshf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR long double
+  cosh(long double __x)
+  { return __builtin_coshl(__x); }
+#endif
+
+  template<typename _Tp>
+    inline _GLIBCXX_CONSTEXPR
+    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
+                                    double>::__type
+    cosh(_Tp __x)
+    { return __builtin_cosh(__x); }
+
+  using ::exp;
+  using ::expf;
+  using ::expl;
+
+#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
+  inline _GLIBCXX_CONSTEXPR float
+  exp(float __x)
+  { return __builtin_expf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR long double
+  exp(long double __x)
+  { return __builtin_expl(__x); }
+#endif
+
+  template<typename _Tp>
+    inline _GLIBCXX_CONSTEXPR
+    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
+                                    double>::__type
+    exp(_Tp __x)
+    { return __builtin_exp(__x); }
+
+  using ::fabs;
+  using ::fabsf;
+  using ::fabsl;
+
+#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
+  inline _GLIBCXX_CONSTEXPR float
+  fabs(float __x)
+  { return __builtin_fabsf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR long double
+  fabs(long double __x)
+  { return __builtin_fabsl(__x); }
+#endif
+
+  template<typename _Tp>
+    inline _GLIBCXX_CONSTEXPR
+    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
+                                    double>::__type
+    fabs(_Tp __x)
+    { return __builtin_fabs(__x); }
+
+  using ::floor;
+  using ::floorf;
+  using ::floorl;
+
+#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
+  inline _GLIBCXX_CONSTEXPR float
+  floor(float __x)
+  { return __builtin_floorf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR long double
+  floor(long double __x)
+  { return __builtin_floorl(__x); }
+#endif
+
+  template<typename _Tp>
+    inline _GLIBCXX_CONSTEXPR
+    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
+                                    double>::__type
+    floor(_Tp __x)
+    { return __builtin_floor(__x); }
+
+  using ::fmod;
+  using ::fmodf;
+  using ::fmodl;
+
+#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
+  inline _GLIBCXX_CONSTEXPR float
+  fmod(float __x, float __y)
+  { return __builtin_fmodf(__x, __y); }
+
+  inline _GLIBCXX_CONSTEXPR long double
+  fmod(long double __x, long double __y)
+  { return __builtin_fmodl(__x, __y); }
+#endif
+
+  using ::frexp;
+  using ::frexpf;
+  using ::frexpl;
+
+#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
+  inline float
+  frexp(float __x, int* __exp)
+  { return __builtin_frexpf(__x, __exp); }
+
+  inline long double
+  frexp(long double __x, int* __exp)
+  { return __builtin_frexpl(__x, __exp); }
+#endif
+
+  template<typename _Tp>
+    inline _GLIBCXX_CONSTEXPR
+    typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value, 
+                                    double>::__type
+    frexp(_Tp __x, int* __exp)
+    { return __builtin_frexp(__x, __exp); }
+
+  using ::ldexp;
+  using ::ldexpf;
+  using ::ldexpl;
+
+#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
+  inline _GLIBCXX_CONSTEXPR float
+  ldexp(float __x, int __exp)
   { return __builtin_ldexpf(__x, __exp); }
 
   inline _GLIBCXX_CONSTEXPR long double
@@ -320,6 +864,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return __builtin_ldexp(__x, __exp); }
 
   using ::log;
+  using ::logf;
+  using ::logl;
 
 #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
   inline _GLIBCXX_CONSTEXPR float
@@ -339,6 +885,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return __builtin_log(__x); }
 
   using ::log10;
+  using ::log10f;
+  using ::log10l;
 
 #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
   inline _GLIBCXX_CONSTEXPR float
@@ -358,6 +906,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return __builtin_log10(__x); }
 
   using ::modf;
+  using ::modff;
+  using ::modfl;
 
 #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
   inline float
@@ -370,6 +920,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   using ::pow;
+  using ::powf;
+  using ::powl;
 
 #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
   inline _GLIBCXX_CONSTEXPR float
@@ -398,6 +950,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
   using ::sin;
+  using ::sinf;
+  using ::sinl;
 
 #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
   inline _GLIBCXX_CONSTEXPR float
@@ -417,6 +971,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return __builtin_sin(__x); }
 
   using ::sinh;
+  using ::sinhf;
+  using ::sinhl;
 
 #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
   inline _GLIBCXX_CONSTEXPR float
@@ -436,6 +992,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return __builtin_sinh(__x); }
 
   using ::sqrt;
+  using ::sqrtf;
+  using ::sqrtl;
 
 #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
   inline _GLIBCXX_CONSTEXPR float
@@ -455,6 +1013,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return __builtin_sqrt(__x); }
 
   using ::tan;
+  using ::tanf;
+  using ::tanl;
 
 #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
   inline _GLIBCXX_CONSTEXPR float
@@ -474,6 +1034,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return __builtin_tan(__x); }
 
   using ::tanh;
+  using ::tanhf;
+  using ::tanhl;
 
 #ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
   inline _GLIBCXX_CONSTEXPR float
@@ -1680,406 +2242,98 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   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
-
-#undef acosf
-#undef acosl
-#undef asinf
-#undef asinl
-#undef atanf
-#undef atanl
-#undef atan2f
-#undef atan2l
-#undef ceilf
-#undef ceill
-#undef cosf
-#undef cosl
-#undef coshf
-#undef coshl
-#undef expf
-#undef expl
-#undef fabsf
-#undef fabsl
-#undef floorf
-#undef floorl
-#undef fmodf
-#undef fmodl
-#undef frexpf
-#undef frexpl
-#undef ldexpf
-#undef ldexpl
-#undef logf
-#undef logl
-#undef log10f
-#undef log10l
-#undef modff
-#undef modfl
-#undef powf
-#undef powl
-#undef sinf
-#undef sinl
-#undef sinhf
-#undef sinhl
-#undef sqrtf
-#undef sqrtl
-#undef tanf
-#undef tanl
-#undef tanhf
-#undef tanhl
-
-#ifdef _GLIBCXX_HAVE_ACOSF
-  using ::acosf;
-#endif
-#ifdef _GLIBCXX_HAVE_ACOSL
-  using ::acosl;
-#endif
+  { return __builtin_isnan(__x); }
 
-#ifdef _GLIBCXX_HAVE_ASINF
-  using ::asinf;
-#endif
-#ifdef _GLIBCXX_HAVE_ASINL
-  using ::asinl;
-#endif
+  constexpr bool
+  isnormal(_Float128 __x)
+  { return __builtin_isnormal(__x); }
 
-#ifdef _GLIBCXX_HAVE_ATANF
-  using ::atanf;
-#endif
-#ifdef _GLIBCXX_HAVE_ATANL
-  using ::atanl;
-#endif
+  constexpr bool
+  signbit(_Float128 __x)
+  { return __builtin_signbit(__x); }
 
-#ifdef _GLIBCXX_HAVE_ATAN2F
-  using ::atan2f;
-#endif
-#ifdef _GLIBCXX_HAVE_ATAN2L
-  using ::atan2l;
-#endif
+  constexpr bool
+  isgreater(_Float128 __x, _Float128 __y)
+  { return __builtin_isgreater(__x, __y); }
 
-#ifdef _GLIBCXX_HAVE_CEILF
-  using ::ceilf;
-#endif
-#ifdef _GLIBCXX_HAVE_CEILL
-  using ::ceill;
-#endif
+  constexpr bool
+  isgreaterequal(_Float128 __x, _Float128 __y)
+  { return __builtin_isgreaterequal(__x, __y); }
 
-#ifdef _GLIBCXX_HAVE_COSF
-  using ::cosf;
-#endif
-#ifdef _GLIBCXX_HAVE_COSL
-  using ::cosl;
-#endif
+  constexpr bool
+  isless(_Float128 __x, _Float128 __y)
+  { return __builtin_isless(__x, __y); }
 
-#ifdef _GLIBCXX_HAVE_COSHF
-  using ::coshf;
-#endif
-#ifdef _GLIBCXX_HAVE_COSHL
-  using ::coshl;
-#endif
+  constexpr bool
+  islessequal(_Float128 __x, _Float128 __y)
+  { return __builtin_islessequal(__x, __y); }
 
-#ifdef _GLIBCXX_HAVE_EXPF
-  using ::expf;
-#endif
-#ifdef _GLIBCXX_HAVE_EXPL
-  using ::expl;
-#endif
+  constexpr bool
+  islessgreater(_Float128 __x, _Float128 __y)
+  { return __builtin_islessgreater(__x, __y); }
 
-#ifdef _GLIBCXX_HAVE_FABSF
-  using ::fabsf;
-#endif
-#ifdef _GLIBCXX_HAVE_FABSL
-  using ::fabsl;
+  constexpr bool
+  isunordered(_Float128 __x, _Float128 __y)
+  { return __builtin_isunordered(__x, __y); }
 #endif
 
-#ifdef _GLIBCXX_HAVE_FLOORF
-  using ::floorf;
-#endif
-#ifdef _GLIBCXX_HAVE_FLOORL
-  using ::floorl;
-#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); }
 
-#ifdef _GLIBCXX_HAVE_FMODF
-  using ::fmodf;
-#endif
-#ifdef _GLIBCXX_HAVE_FMODL
-  using ::fmodl;
-#endif
+  constexpr bool
+  isfinite(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_isfinite(__x); }
 
-#ifdef _GLIBCXX_HAVE_FREXPF
-  using ::frexpf;
-#endif
-#ifdef _GLIBCXX_HAVE_FREXPL
-  using ::frexpl;
-#endif
+  constexpr bool
+  isinf(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_isinf(__x); }
 
-#ifdef _GLIBCXX_HAVE_LDEXPF
-  using ::ldexpf;
-#endif
-#ifdef _GLIBCXX_HAVE_LDEXPL
-  using ::ldexpl;
-#endif
+  constexpr bool
+  isnan(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_isnan(__x); }
 
-#ifdef _GLIBCXX_HAVE_LOGF
-  using ::logf;
-#endif
-#ifdef _GLIBCXX_HAVE_LOGL
-  using ::logl;
-#endif
+  constexpr bool
+  isnormal(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_isnormal(__x); }
 
-#ifdef _GLIBCXX_HAVE_LOG10F
-  using ::log10f;
-#endif
-#ifdef _GLIBCXX_HAVE_LOG10L
-  using ::log10l;
-#endif
+  constexpr bool
+  signbit(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_signbit(__x); }
 
-#ifdef _GLIBCXX_HAVE_MODFF
-  using ::modff;
-#endif
-#ifdef _GLIBCXX_HAVE_MODFL
-  using ::modfl;
-#endif
+  constexpr bool
+  isgreater(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_isgreater(__x, __y); }
 
-#ifdef _GLIBCXX_HAVE_POWF
-  using ::powf;
-#endif
-#ifdef _GLIBCXX_HAVE_POWL
-  using ::powl;
-#endif
+  constexpr bool
+  isgreaterequal(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_isgreaterequal(__x, __y); }
 
-#ifdef _GLIBCXX_HAVE_SINF
-  using ::sinf;
-#endif
-#ifdef _GLIBCXX_HAVE_SINL
-  using ::sinl;
-#endif
+  constexpr bool
+  isless(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_isless(__x, __y); }
 
-#ifdef _GLIBCXX_HAVE_SINHF
-  using ::sinhf;
-#endif
-#ifdef _GLIBCXX_HAVE_SINHL
-  using ::sinhl;
-#endif
+  constexpr bool
+  islessequal(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_islessequal(__x, __y); }
 
-#ifdef _GLIBCXX_HAVE_SQRTF
-  using ::sqrtf;
-#endif
-#ifdef _GLIBCXX_HAVE_SQRTL
-  using ::sqrtl;
-#endif
+  constexpr bool
+  islessgreater(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_islessgreater(__x, __y); }
 
-#ifdef _GLIBCXX_HAVE_TANF
-  using ::tanf;
-#endif
-#ifdef _GLIBCXX_HAVE_TANL
-  using ::tanl;
+  constexpr bool
+  isunordered(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_isunordered(__x, __y); }
 #endif
 
-#ifdef _GLIBCXX_HAVE_TANHF
-  using ::tanhf;
-#endif
-#ifdef _GLIBCXX_HAVE_TANHL
-  using ::tanhl;
-#endif
+#endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */
+#endif /* _GLIBCXX_USE_C99_MATH */
 
+#if __cplusplus >= 201103L
 #ifdef _GLIBCXX_USE_C99_MATH_FUNCS
 
-#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
-#undef nearbyint
-#undef nearbyintf
-#undef nearbyintl
-#undef nextafter
-#undef nextafterf
-#undef nextafterl
-#undef nexttoward
-#undef nexttowardf
-#undef nexttowardl
-#undef remainder
-#undef remainderf
-#undef remainderl
-#undef remquo
-#undef remquof
-#undef remquol
-#undef rint
-#undef rintf
-#undef rintl
-#undef round
-#undef roundf
-#undef roundl
-#undef scalbln
-#undef scalblnf
-#undef scalblnl
-#undef scalbn
-#undef scalbnf
-#undef scalbnl
-#undef tgamma
-#undef tgammaf
-#undef tgammal
-#undef trunc
-#undef truncf
-#undef truncl
-
 #ifdef _GLIBCXX_HAVE_C99_FLT_EVAL_TYPES
   // types
   using ::double_t;
diff --git a/libstdc++-v3/include/tr1/cmath b/libstdc++-v3/include/tr1/cmath
index 83677a4e716..6ff41ed6c21 100644
--- a/libstdc++-v3/include/tr1/cmath
+++ b/libstdc++-v3/include/tr1/cmath
@@ -143,7 +143,233 @@ 
 #undef truncf
 #undef truncl
 
+extern "C"
+{
+// Provide declarations for missing C99 functions.
+#ifndef _GLIBCXX_HAVE_ACOSHF
+  float acoshf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_ACOSHL
+  long double acoshl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_ASINHF
+  float asinhf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_ASINHL
+  long double asinhl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_ATANHF
+  float atanhf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_ATANHL
+  long double atanhl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_CBRTF
+  float cbrtf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_CBRTL
+  long double cbrtl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_COPYSIGNF
+  float copysignf(float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_COPYSIGNL
+  long double copysignl(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_ERFF
+  float erff(float);
+#endif
+#ifndef _GLIBCXX_HAVE_ERFL
+  long double erfl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_ERFCF
+  float erfcf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_ERFCL
+  long double erfcl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_EXP2F
+  float exp2f(float);
+#endif
+#ifndef _GLIBCXX_HAVE_EXP2L
+  long double exp2l(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_EXPM1F
+  float expm1f(float);
+#endif
+#ifndef _GLIBCXX_HAVE_EXPM1L
+  long double expm1l(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_FDIMF
+  float fdimf(float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_FDIML
+  long double fdiml(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_FMA
+  double fma(double, double, double);
+#endif
+#ifndef _GLIBCXX_HAVE_FMAF
+  float fmaf(float, float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_FMAL
+  long double fmal(long double, long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_FMAXF
+  float fmaxf(float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_FMAXL
+  long double fmaxl(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_FMINF
+  float fminf(float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_FMINL
+  long double fminl(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_HYPOTF
+  float hypotf(float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_HYPOTL
+  long double hypotl(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_ILOGBF
+  int ilogbf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_ILOGBL
+  int ilogbl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LGAMMAF
+  float lgammaf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LGAMMAL
+  long double lgammal(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LLRINTF
+  long long llrintf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LLRINTL
+  long long llrintl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LLROUNDL
+  long long llroundl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LLROUNDF
+  long long llroundf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LOG1PF
+  float log1pf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LOG1PL
+  long double log1pl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LOG2F
+  float log2f(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LOG2L
+  long double log2l(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LOGBF
+  float logbf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LOGBL
+  long double logbl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LRINTF
+  long lrintf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LRINTL
+  long lrintl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_LROUNDF
+  long lroundf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_LROUNDL
+  long lroundl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_NANF
+  float nanf(const char *);
+#endif
+#ifndef _GLIBCXX_HAVE_NANL
+  long double nanl(const char *);
+#endif
+#ifndef _GLIBCXX_HAVE_NEARBYINTF
+  float nearbyintf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_NEARBYINTL
+  long double nearbyintl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_NEXTAFTERF
+  float nextafterf(float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_NEXTAFTERL
+  long double nextafterl(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_NEXTTOWARD
+  double nexttoward(double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_NEXTTOWARDF
+  float nexttowardf(float, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_NEXTTOWARDL
+  long double nexttowardl(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_REMAINDERF
+  float remainderf(float, float);
+#endif
+#ifndef _GLIBCXX_HAVE_REMAINDERL
+  long double remainderl(long double, long double);
+#endif
+#ifndef _GLIBCXX_HAVE_REMQUOF
+  float remquof(float, float, int *);
+#endif
+#ifndef _GLIBCXX_HAVE_REMQUOL
+  long double remquol(long double, long double, int *);
+#endif
+#ifndef _GLIBCXX_HAVE_RINTF
+  float rintf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_RINTL
+  long double rintl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_ROUNDF
+  float roundf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_ROUNDL
+  long double roundl(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_SCALBLN
+  double scalbln(double, long);
+#endif
+#ifndef _GLIBCXX_HAVE_SCALBLNF
+  float scalblnf(float, long);
+#endif
+#ifndef _GLIBCXX_HAVE_SCALBLNL
+  long double scalblnl(long double, long);
+#endif
+#ifndef _GLIBCXX_HAVE_SCALBNF
+  float scalbnf(float, int);
+#endif
+#ifndef _GLIBCXX_HAVE_SCALBNL
+  long double scalbnl(long double, int);
+#endif
+#ifndef _GLIBCXX_HAVE_TGAMMA
+  double tgamma(double);
+#endif
+#ifndef _GLIBCXX_HAVE_TGAMMAF
+  float tgammaf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_TGAMMAL
+  long double tgammal(long double);
+#endif
+#ifndef _GLIBCXX_HAVE_TRUNCF
+  float truncf(float);
+#endif
+#ifndef _GLIBCXX_HAVE_TRUNCL
+  long double truncl(long double);
+#endif
 #endif
+}
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
diff --git a/libstdc++-v3/linkage.m4 b/libstdc++-v3/linkage.m4
index 29b31447c98..519bc6a8e88 100644
--- a/libstdc++-v3/linkage.m4
+++ b/libstdc++-v3/linkage.m4
@@ -320,6 +320,10 @@  AC_DEFUN([GLIBCXX_CHECK_MATH_SUPPORT], [
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(fpclass)
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(qfpclass)
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_2(hypot)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_3(fma)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_2(nexttoward)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_2(scalbln)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(tgamma)
 
   dnl Check to see if basic C math functions have float versions.
   GLIBCXX_CHECK_MATH_DECLS_AND_LINKAGES_1(float trig,
@@ -347,6 +351,13 @@  AC_DEFUN([GLIBCXX_CHECK_MATH_SUPPORT], [
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(sqrtf)
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_3(sincosf)
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(finitef)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(cbrtf)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_2(copysignf)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(expm1f)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(log2f)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(nanf)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_2(nextafterf)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_2(nexttowardf)
 
   dnl Check to see if basic C math functions have long double versions.
   GLIBCXX_CHECK_MATH_DECLS_AND_LINKAGES_1(long double trig,
@@ -361,10 +372,12 @@  AC_DEFUN([GLIBCXX_CHECK_MATH_SUPPORT], [
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(isinfl)
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_2(atan2l)
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(expl)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(expm1l)
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(fabsl)
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_2(fmodl)
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_2(frexpl)
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_2(hypotl)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(ilogbl)
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_2(ldexpl)
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(logl)
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(log10l)
@@ -373,6 +386,11 @@  AC_DEFUN([GLIBCXX_CHECK_MATH_SUPPORT], [
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(sqrtl)
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_3(sincosl)
   GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(finitel)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_1(nanl)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_2(nextafterl)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_2(nexttowardl)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_2(scalblnl)
+  GLIBCXX_CHECK_MATH_DECL_AND_LINKAGE_2(scalbnl)
 
   LIBS="$ac_save_LIBS"
   CXXFLAGS="$ac_save_CXXFLAGS"
diff --git a/libstdc++-v3/src/c++98/Makefile.am b/libstdc++-v3/src/c++98/Makefile.am
index d12fdf0f121..128005f2c10 100644
--- a/libstdc++-v3/src/c++98/Makefile.am
+++ b/libstdc++-v3/src/c++98/Makefile.am
@@ -128,6 +128,7 @@  sources = \
 	locale.cc \
 	locale_facets.cc \
 	math_stubs_float.cc \
+	math_stubs_double.cc \
 	math_stubs_long_double.cc \
 	stdexcept.cc \
 	strstream.cc \
diff --git a/libstdc++-v3/src/c++98/math_stubs_double.cc b/libstdc++-v3/src/c++98/math_stubs_double.cc
new file mode 100644
index 00000000000..4fc802608e8
--- /dev/null
+++ b/libstdc++-v3/src/c++98/math_stubs_double.cc
@@ -0,0 +1,83 @@ 
+// Stub definitions for double math.
+
+// Copyright (C) 2001-2024 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/>.
+
+#include <float.h>
+#include <cmath>
+
+// For targets which do not have support for double versions,
+// we use the following crude approximations. We keep saying that we'll do
+// better later, but never do.
+
+extern "C"
+{
+#ifndef _GLIBCXX_HAVE_FMA
+  double
+  fma(double x, double y, double z)
+  {
+#ifdef _GLIBCXX_USE_BUILTIN_FMA
+    return __builtin_fma (x, y, z);
+#else
+    return x * y + z;
+#endif
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_NEXTTOWARD
+  double
+  nexttoward(double x, long double y)
+  {
+    if (x == y)
+      return (double)y;
+    if (isnan (x))
+      return x;
+    if (isnan (y))
+      return y;
+    return nextafter (x, y);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_SCALBLN
+  double
+  scalbln(double x, long exp)
+  {
+#if FLT_RADIX == 2
+    return x * exp2 ((double) exp);
+#else
+    return x * pow ((double) FLT_RADIX, (double) exp);
+#endif
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_TGAMMA
+  double
+  tgamma(double x)
+  {
+    int sign;
+    double g;
+
+    g = lgamma_r (x, &sign);
+    return sign ? exp (g) : exp (-g);
+  }
+#endif
+} // extern "C"
diff --git a/libstdc++-v3/src/c++98/math_stubs_float.cc b/libstdc++-v3/src/c++98/math_stubs_float.cc
index 4dbe3afab8f..05266eb1cbe 100644
--- a/libstdc++-v3/src/c++98/math_stubs_float.cc
+++ b/libstdc++-v3/src/c++98/math_stubs_float.cc
@@ -221,4 +221,244 @@  extern "C"
     return (float) tanh(x);
   }
 #endif
+
+#ifndef _GLIBCXX_HAVE_SCALBNF
+  float
+  scalbnf(float x, int exp)
+  {
+    return (float) scalbn (x, exp);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_LGAMMAF
+  float
+  lgammaf(float x)
+  {
+    return (float) lgamma (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_TGAMMAF
+  float
+  tgammaf(float x)
+  {
+    return (float) tgamma (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_ERFF
+  float
+  erff(float x)
+  {
+    return (float) erf (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_ERFCF
+  float
+  erfcf(float x)
+  {
+    return (float) erfc (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_REMQUOF
+  float
+  remquof(float x, float y, int *quo)
+  {
+    return (float) remquo (x, y, quo);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_FDIMF
+  float
+  fdimf(float x, float y)
+  {
+    return (float) fdim (x, y);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_NEARBYINTF
+  float
+  nearbyintf(float x)
+  {
+    return (float) nearbyint (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_EXP2F
+  float
+  exp2f(float x)
+  {
+    return (float) exp2 (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_RINTF
+  float
+  rintf(float x)
+  {
+    return (float) rint (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_LRINTF
+  long
+  lrintf(float x)
+  {
+    return lrint (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_LLRINTF
+  long long
+  llrintf(float x)
+  {
+    return llrint (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_FMAXF
+  float
+  fmaxf(float x, float y)
+  {
+    return (float) fmax (x, y);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_FMINF
+  float
+  fminf(float x, float y)
+  {
+    return (float) fmin (x, y);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_LOG1PF
+  float
+  log1pf(float x)
+  {
+    return (float) log1p (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_TRUNCF
+  float
+  truncf(float x)
+  {
+    return (float) trunc (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_ASINHF
+  float
+  asinhf(float x)
+  {
+    return (float) asinh (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_ACOSHF
+  float
+  acoshf(float x)
+  {
+    return (float) acosh (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_ATANHF
+  float
+  atanhf(float x)
+  {
+    return (float) atanh (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_SCALBLNF
+  float
+  scalblnf(float x, long exp)
+  {
+    return (float) scalbln (x, exp);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_LROUNDF
+  long
+  lroundf(float x)
+  {
+    return lround (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_LLROUNDF
+  long long
+  llroundf(float x)
+  {
+    return llround (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_ROUNDF
+  float
+  roundf(float x)
+  {
+    return (float) round (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_REMAINDER
+  float
+  remainderf(float x, float y)
+  {
+    return (float) remainder (x, y);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_LOGBF
+  float
+  logbf(float x)
+  {
+    return (float) logb (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_ILOGBF
+  int
+  ilogbf(float x)
+  {
+    return ilogb (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_EXPM1F
+  float
+  expm1f(float x)
+  {
+    return (float) expm1 (x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_NEXTAFTERF
+  float
+  nextafterf(float x, float y)
+  {
+    return (float) nextafter (x, y);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_NEXTTOWARDF
+  float
+  nexttowardf(float x, long double y)
+  {
+    return (float) nexttoward (x, y);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_NANF
+  float
+  nanf(const char *tagp)
+  {
+    return (float) nan (tagp);
+  }
+#endif
 } // extern "C"
diff --git a/libstdc++-v3/src/c++98/math_stubs_long_double.cc b/libstdc++-v3/src/c++98/math_stubs_long_double.cc
index 90e1717545c..de32ad01450 100644
--- a/libstdc++-v3/src/c++98/math_stubs_long_double.cc
+++ b/libstdc++-v3/src/c++98/math_stubs_long_double.cc
@@ -221,4 +221,88 @@  extern "C"
     return tanh((double) x);
   }
 #endif
+
+#ifndef _GLIBCXX_HAVE_ILOGBL
+  int
+  ilogbl(long double x)
+  {
+    return ilogb((double) x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_LGAMMAL
+  long double
+  lgammal(long double x)
+  {
+    return lgamma ((double) x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_LOG1PL
+  long double
+  log1pl(long double x)
+  {
+    return log1p ((double) x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_NANL
+  long double
+  nanl(const char *tagp)
+  {
+    return nan (tagp);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_NEARBYINTL
+  long double
+  nearbyintl(long double x)
+  {
+    return nearbyint ((double) x);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_NEXTAFTERL
+  long double
+  nextafterl(long double x, long double y)
+  {
+    if (x == y)
+      return y;
+    return nextafter ((double) x, (double) y);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_NEXTTOWARDL
+  long double
+  nexttowardl(long double x, long double y)
+  {
+    if (x == y)
+      return y;
+    return nexttoward ((double) x, (double) y);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_SCALBLNL
+  long double
+  scalblnl(long double x, long exp)
+  {
+    return scalbln ((double) x, exp);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_SCALBNL
+  long double
+  scalbnl(long double x, int exp)
+  {
+    return scalbn ((double) x, exp);
+  }
+#endif
+
+#ifndef _GLIBCXX_HAVE_TGAMMAL
+  long double
+  tgammal(long double x)
+  {
+    return tgamma ((double) x);
+  }
+#endif
 } // extern "C"