new file mode 100644
@@ -0,0 +1,85 @@
+/* Define floating-point classification macros.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _MATH_H
+# error "Never use <bits/fpclassify.h> directly; include <math.h> instead."
+#endif
+
+/* GCC bug 66462 means we cannot use the math builtins with -fsignaling-nan,
+ so disable builtins if this is enabled. When fixed in a newer GCC,
+ the __SUPPORT_SNAN__ check may be skipped for those versions. */
+
+/* Return number of classification appropriate for X. */
+#if ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
+ || __glibc_clang_prereq (2,8)) \
+ && (!defined __OPTIMIZE_SIZE__ || defined __cplusplus)
+ /* The check for __cplusplus allows the use of the builtin, even
+ when optimization for size is on. This is provided for
+ libstdc++, only to let its configure test work when it is built
+ with -Os. No further use of this definition of fpclassify is
+ expected in C++ mode, since libstdc++ provides its own version
+ of fpclassify in cmath (which undefines fpclassify). */
+# define fpclassify(x) __builtin_fpclassify (FP_NAN, FP_INFINITE, \
+ FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x)
+#else
+# define fpclassify(x) __MATH_TG ((x), __fpclassify, (x))
+#endif
+
+/* Return nonzero value if X is not +-Inf or NaN. */
+#if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
+ || __glibc_clang_prereq (2,8)
+# define isfinite(x) __builtin_isfinite (x)
+#else
+# define isfinite(x) __MATH_TG ((x), __finite, (x))
+#endif
+
+/* Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */
+#if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
+ || __glibc_clang_prereq (2,8)
+# define isnormal(x) __builtin_isnormal (x)
+#else
+# define isnormal(x) (fpclassify (x) == FP_NORMAL)
+#endif
+
+/* Return nonzero value if X is a NaN. We could use `fpclassify' but
+ we already have this functions `__isnan' and it is faster. */
+#if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
+ || __glibc_clang_prereq (2,8)
+# define isnan(x) __builtin_isnan (x)
+#else
+# define isnan(x) __MATH_TG ((x), __isnan, (x))
+#endif
+
+/* Return nonzero value if X is positive or negative infinity. */
+#if __HAVE_DISTINCT_FLOAT128 && !__GNUC_PREREQ (7,0) \
+ && !defined __SUPPORT_SNAN__ && !defined __cplusplus \
+ && !defined __clang__
+ /* Since __builtin_isinf_sign is broken for float128 before GCC 7.0,
+ use the helper function, __isinff128, with older compilers. This is
+ only provided for C mode, because in C++ mode, GCC has no support
+ for __builtin_types_compatible_p (and when in C++ mode, this macro is
+ not used anyway, because libstdc++ headers undefine it). */
+# define isinf(x) \
+ (__builtin_types_compatible_p (__typeof (x), _Float128) \
+ ? __isinff128 (x) : __builtin_isinf_sign (x))
+#elif (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
+ || __glibc_clang_prereq (3,7)
+# define isinf(x) __builtin_isinf_sign (x)
+#else
+# define isinf(x) __MATH_TG ((x), __isinf, (x))
+#endif
@@ -30,6 +30,7 @@ headers := \
bits/flt-eval-method.h \
bits/fp-fast.h \
bits/fp-logb.h \
+ bits/fpclassify.h \
bits/iscanonical.h \
bits/libm-simd-decl-stubs.h \
bits/long-double.h \
@@ -1087,26 +1087,6 @@ enum
FP_NORMAL
};
-/* GCC bug 66462 means we cannot use the math builtins with -fsignaling-nan,
- so disable builtins if this is enabled. When fixed in a newer GCC,
- the __SUPPORT_SNAN__ check may be skipped for those versions. */
-
-/* Return number of classification appropriate for X. */
-# if ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
- || __glibc_clang_prereq (2,8)) \
- && (!defined __OPTIMIZE_SIZE__ || defined __cplusplus)
- /* The check for __cplusplus allows the use of the builtin, even
- when optimization for size is on. This is provided for
- libstdc++, only to let its configure test work when it is built
- with -Os. No further use of this definition of fpclassify is
- expected in C++ mode, since libstdc++ provides its own version
- of fpclassify in cmath (which undefines fpclassify). */
-# define fpclassify(x) __builtin_fpclassify (FP_NAN, FP_INFINITE, \
- FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x)
-# else
-# define fpclassify(x) __MATH_TG ((x), __fpclassify, (x))
-# endif
-
/* Return nonzero value if sign of X is negative. */
# if __GNUC_PREREQ (6,0) || __glibc_clang_prereq (3,3)
# define signbit(x) __builtin_signbit (x)
@@ -1125,49 +1105,7 @@ enum
# define signbit(x) __MATH_TG ((x), __signbit, (x))
# endif
-/* Return nonzero value if X is not +-Inf or NaN. */
-# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
- || __glibc_clang_prereq (2,8)
-# define isfinite(x) __builtin_isfinite (x)
-# else
-# define isfinite(x) __MATH_TG ((x), __finite, (x))
-# endif
-
-/* Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */
-# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
- || __glibc_clang_prereq (2,8)
-# define isnormal(x) __builtin_isnormal (x)
-# else
-# define isnormal(x) (fpclassify (x) == FP_NORMAL)
-# endif
-
-/* Return nonzero value if X is a NaN. We could use `fpclassify' but
- we already have this functions `__isnan' and it is faster. */
-# if (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
- || __glibc_clang_prereq (2,8)
-# define isnan(x) __builtin_isnan (x)
-# else
-# define isnan(x) __MATH_TG ((x), __isnan, (x))
-# endif
-
-/* Return nonzero value if X is positive or negative infinity. */
-# if __HAVE_DISTINCT_FLOAT128 && !__GNUC_PREREQ (7,0) \
- && !defined __SUPPORT_SNAN__ && !defined __cplusplus \
- && !defined __clang__
- /* Since __builtin_isinf_sign is broken for float128 before GCC 7.0,
- use the helper function, __isinff128, with older compilers. This is
- only provided for C mode, because in C++ mode, GCC has no support
- for __builtin_types_compatible_p (and when in C++ mode, this macro is
- not used anyway, because libstdc++ headers undefine it). */
-# define isinf(x) \
- (__builtin_types_compatible_p (__typeof (x), _Float128) \
- ? __isinff128 (x) : __builtin_isinf_sign (x))
-# elif (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
- || __glibc_clang_prereq (3,7)
-# define isinf(x) __builtin_isinf_sign (x)
-# else
-# define isinf(x) __MATH_TG ((x), __isinf, (x))
-# endif
+# include <bits/fpclassify.h>
/* Bitmasks for the math_errhandling macro. */
# define MATH_ERRNO 1 /* errno set by math functions. */