diff options
| author | Joseph Myers <josmyers@redhat.com> | 2025-11-13 00:04:21 +0000 |
|---|---|---|
| committer | Joseph Myers <josmyers@redhat.com> | 2025-11-13 00:04:21 +0000 |
| commit | 1f79bc48382cc204a9cb0eae1d3cca2515af1f3c (patch) | |
| tree | fd78b2ca98df67fd18d37041d9986b5a881863e1 /sysdeps/ieee754 | |
| parent | 989e538224de5eea508ceda6d273cb64df6cca56 (diff) | |
Change fromfp functions to return floating types following C23 (bug 28327)
As discussed in bug 28327, C23 changed the fromfp functions to return
floating types instead of intmax_t / uintmax_t. (Although the
motivation in N2548 was reducing the use of intmax_t in library
interfaces, the new version does have the advantage of being able to
specify arbitrary integer widths for e.g. assigning the result to a
_BitInt, as well as being able to indicate an error case in-band with
a NaN return.)
As with other such changes from interfaces introduced in TS 18661,
implement the new types as a replacement for the old ones, with the
old functions remaining as compat symbols but not supported as an API.
The test generator used for many of the tests is updated to handle
both versions of the functions.
Tested for x86_64 and x86, and with build-many-glibcs.py.
Also tested tgmath tests for x86_64 with GCC 7 to make sure that the
modified case for older compilers in <tgmath.h> does work.
Also tested for powerpc64le to cover the ldbl-128ibm implementation
and the other things that are handled differently for that
configuration. The new tests fail for ibm128, but all the failures
relate to incorrect signs of zero results and turn out to arise from
bugs in the underlying roundl, ceill, truncl and floorl
implementations that I've reported in bug 33623, rather than
indicating any bug in the actual new implementation of the functions
for that format. So given fixes for those functions (which shouldn't
be hard, and of course should add to the tests for those functions
rather than relying only on indirect testing via fromfp), the fromfp
tests should start passing for ibm128 as well.
Diffstat (limited to 'sysdeps/ieee754')
66 files changed, 1095 insertions, 62 deletions
diff --git a/sysdeps/ieee754/dbl-64/s_compat_fromfp.c b/sysdeps/ieee754/dbl-64/s_compat_fromfp.c index d159d62fe6..c0ed4704ea 100644 --- a/sysdeps/ieee754/dbl-64/s_compat_fromfp.c +++ b/sysdeps/ieee754/dbl-64/s_compat_fromfp.c @@ -1,5 +1,17 @@ #define UNSIGNED 0 #define INEXACT 0 -#define FUNC __fromfp +#define FUNC __compat_fromfp #include <s_compat_fromfp_main.c> -libm_alias_double (__fromfp, fromfp) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +libm_alias_double (__compat_fromfp, fromfp) +#endif diff --git a/sysdeps/ieee754/dbl-64/s_compat_fromfp_main.c b/sysdeps/ieee754/dbl-64/s_compat_fromfp_main.c index 17e8ded49e..1d76ced904 100644 --- a/sysdeps/ieee754/dbl-64/s_compat_fromfp_main.c +++ b/sysdeps/ieee754/dbl-64/s_compat_fromfp_main.c @@ -1,4 +1,4 @@ -/* Round to integer type. dbl-64 version. +/* Round to integer type (pre-C23 compat version). dbl-64 version. Copyright (C) 2016-2025 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -23,6 +23,8 @@ #include <libm-alias-double.h> #include <stdbool.h> #include <stdint.h> +#include <shlib-compat.h> +#include <first-versions.h> #define BIAS 0x3ff #define MANT_DIG 53 @@ -33,9 +35,11 @@ # define RET_TYPE intmax_t #endif -#include <compat_fromfp.h> +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# include <compat_fromfp.h> RET_TYPE +attribute_compat_text_section FUNC (double x, int round, unsigned int width) { if (width > INTMAX_WIDTH) @@ -81,3 +85,4 @@ FUNC (double x, int round, unsigned int width) return fromfp_round_and_return (negative, uret, half_bit, more_bits, round, exponent, max_exponent, width); } +#endif diff --git a/sysdeps/ieee754/dbl-64/s_compat_fromfpx.c b/sysdeps/ieee754/dbl-64/s_compat_fromfpx.c index b90fdea351..90cac5519c 100644 --- a/sysdeps/ieee754/dbl-64/s_compat_fromfpx.c +++ b/sysdeps/ieee754/dbl-64/s_compat_fromfpx.c @@ -1,5 +1,17 @@ #define UNSIGNED 0 #define INEXACT 1 -#define FUNC __fromfpx +#define FUNC __compat_fromfpx #include <s_compat_fromfp_main.c> -libm_alias_double (__fromfpx, fromfpx) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +libm_alias_double (__compat_fromfpx, fromfpx) +#endif diff --git a/sysdeps/ieee754/dbl-64/s_compat_ufromfp.c b/sysdeps/ieee754/dbl-64/s_compat_ufromfp.c index 4a8312b881..ec49e0701d 100644 --- a/sysdeps/ieee754/dbl-64/s_compat_ufromfp.c +++ b/sysdeps/ieee754/dbl-64/s_compat_ufromfp.c @@ -1,5 +1,17 @@ #define UNSIGNED 1 #define INEXACT 0 -#define FUNC __ufromfp +#define FUNC __compat_ufromfp #include <s_compat_fromfp_main.c> -libm_alias_double (__ufromfp, ufromfp) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +libm_alias_double (__compat_ufromfp, ufromfp) +#endif diff --git a/sysdeps/ieee754/dbl-64/s_compat_ufromfpx.c b/sysdeps/ieee754/dbl-64/s_compat_ufromfpx.c index 50de6de29c..e6be9883fd 100644 --- a/sysdeps/ieee754/dbl-64/s_compat_ufromfpx.c +++ b/sysdeps/ieee754/dbl-64/s_compat_ufromfpx.c @@ -1,5 +1,17 @@ #define UNSIGNED 1 #define INEXACT 1 -#define FUNC __ufromfpx +#define FUNC __compat_ufromfpx #include <s_compat_fromfp_main.c> -libm_alias_double (__ufromfpx, ufromfpx) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +libm_alias_double (__compat_ufromfpx, ufromfpx) +#endif diff --git a/sysdeps/ieee754/dbl-64/s_fromfp.c b/sysdeps/ieee754/dbl-64/s_fromfp.c new file mode 100644 index 0000000000..e8b1a7587e --- /dev/null +++ b/sysdeps/ieee754/dbl-64/s_fromfp.c @@ -0,0 +1,16 @@ +#define UNSIGNED 0 +#define INEXACT 0 +#define FUNC __fromfp +#include <s_fromfp_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +libm_alias_double (__fromfp, fromfp) diff --git a/sysdeps/ieee754/dbl-64/s_fromfp_main.c b/sysdeps/ieee754/dbl-64/s_fromfp_main.c new file mode 100644 index 0000000000..a7bf305af5 --- /dev/null +++ b/sysdeps/ieee754/dbl-64/s_fromfp_main.c @@ -0,0 +1,55 @@ +/* Round to integer type (C23 version). dbl-64 version. + Copyright (C) 2016-2025 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/>. */ + +#include <errno.h> +#include <fenv.h> +#include <math.h> +#include <math_private.h> +#include <libm-alias-double.h> +#include <stdbool.h> +#include <stdint.h> +#include <shlib-compat.h> + +#define FLOAT double +#define PREFIX DBL_ +#define SUFFIX +#define BIAS 0x3ff +#define MANT_DIG 53 + +#include <fromfp.h> + +double +FUNC (double x, int round, unsigned int width) +{ + width = fromfp_adjust_width (width); + double rx = fromfp_round (x, round); + if (width == 0 || !isfinite (rx)) + return fromfp_domain_error (); + uint64_t ix; + EXTRACT_WORDS64 (ix, rx); + bool negative = (ix & 0x8000000000000000ULL) != 0; + ix &= 0x7fffffffffffffffULL; + int exponent = ix >> (MANT_DIG - 1); + exponent -= BIAS; + int max_exponent = fromfp_max_exponent (negative, width); + ix &= ((1ULL << (MANT_DIG - 1)) - 1); + if (exponent > max_exponent + || (!UNSIGNED && negative && exponent == max_exponent && ix != 0)) + return fromfp_domain_error (); + return fromfp_return (x, rx); +} diff --git a/sysdeps/ieee754/dbl-64/s_fromfpx.c b/sysdeps/ieee754/dbl-64/s_fromfpx.c new file mode 100644 index 0000000000..eed5d78a7d --- /dev/null +++ b/sysdeps/ieee754/dbl-64/s_fromfpx.c @@ -0,0 +1,16 @@ +#define UNSIGNED 0 +#define INEXACT 1 +#define FUNC __fromfpx +#include <s_fromfp_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +libm_alias_double (__fromfpx, fromfpx) diff --git a/sysdeps/ieee754/dbl-64/s_ufromfp.c b/sysdeps/ieee754/dbl-64/s_ufromfp.c new file mode 100644 index 0000000000..cfa1fe0172 --- /dev/null +++ b/sysdeps/ieee754/dbl-64/s_ufromfp.c @@ -0,0 +1,16 @@ +#define UNSIGNED 1 +#define INEXACT 0 +#define FUNC __ufromfp +#include <s_fromfp_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +libm_alias_double (__ufromfp, ufromfp) diff --git a/sysdeps/ieee754/dbl-64/s_ufromfpx.c b/sysdeps/ieee754/dbl-64/s_ufromfpx.c new file mode 100644 index 0000000000..beac250532 --- /dev/null +++ b/sysdeps/ieee754/dbl-64/s_ufromfpx.c @@ -0,0 +1,16 @@ +#define UNSIGNED 1 +#define INEXACT 1 +#define FUNC __ufromfpx +#include <s_fromfp_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +libm_alias_double (__ufromfpx, ufromfpx) diff --git a/sysdeps/ieee754/float128/s_compat_fromfpf128.c b/sysdeps/ieee754/float128/s_compat_fromfpf128.c index 3cb1bfe6fb..6b84e95d7e 100644 --- a/sysdeps/ieee754/float128/s_compat_fromfpf128.c +++ b/sysdeps/ieee754/float128/s_compat_fromfpf128.c @@ -1,6 +1,21 @@ #define UNSIGNED 0 #define INEXACT 0 -#define FUNC __fromfpf128 +#define FUNC __compat_fromfpf128 #include <float128_private.h> #include "../ldbl-128/s_compat_fromfpl_main.c" -libm_alias_float128 (__fromfp, fromfp) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +# undef libm_alias_float128_other_r_ldbl +# define libm_alias_float128_other_r_ldbl(from, to, r) \ + weak_alias (from ## f128 ## r, __ ## to ## ieee128 ## r) +libm_alias_float128 (__compat_fromfp, fromfp) +#endif diff --git a/sysdeps/ieee754/float128/s_compat_fromfpxf128.c b/sysdeps/ieee754/float128/s_compat_fromfpxf128.c index dc58fccd3e..d45bad2b1e 100644 --- a/sysdeps/ieee754/float128/s_compat_fromfpxf128.c +++ b/sysdeps/ieee754/float128/s_compat_fromfpxf128.c @@ -1,6 +1,21 @@ #define UNSIGNED 0 #define INEXACT 1 -#define FUNC __fromfpxf128 +#define FUNC __compat_fromfpxf128 #include <float128_private.h> #include "../ldbl-128/s_compat_fromfpl_main.c" -libm_alias_float128 (__fromfpx, fromfpx) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +# undef libm_alias_float128_other_r_ldbl +# define libm_alias_float128_other_r_ldbl(from, to, r) \ + weak_alias (from ## f128 ## r, __ ## to ## ieee128 ## r) +libm_alias_float128 (__compat_fromfpx, fromfpx) +#endif diff --git a/sysdeps/ieee754/float128/s_compat_ufromfpf128.c b/sysdeps/ieee754/float128/s_compat_ufromfpf128.c index c9e3fb02d5..6d38335308 100644 --- a/sysdeps/ieee754/float128/s_compat_ufromfpf128.c +++ b/sysdeps/ieee754/float128/s_compat_ufromfpf128.c @@ -1,6 +1,21 @@ #define UNSIGNED 1 #define INEXACT 0 -#define FUNC __ufromfpf128 +#define FUNC __compat_ufromfpf128 #include <float128_private.h> #include "../ldbl-128/s_compat_fromfpl_main.c" -libm_alias_float128 (__ufromfp, ufromfp) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +# undef libm_alias_float128_other_r_ldbl +# define libm_alias_float128_other_r_ldbl(from, to, r) \ + weak_alias (from ## f128 ## r, __ ## to ## ieee128 ## r) +libm_alias_float128 (__compat_ufromfp, ufromfp) +#endif diff --git a/sysdeps/ieee754/float128/s_compat_ufromfpxf128.c b/sysdeps/ieee754/float128/s_compat_ufromfpxf128.c index ffda04d5e3..216fa6835f 100644 --- a/sysdeps/ieee754/float128/s_compat_ufromfpxf128.c +++ b/sysdeps/ieee754/float128/s_compat_ufromfpxf128.c @@ -1,6 +1,21 @@ #define UNSIGNED 1 #define INEXACT 1 -#define FUNC __ufromfpxf128 +#define FUNC __compat_ufromfpxf128 #include <float128_private.h> #include "../ldbl-128/s_compat_fromfpl_main.c" -libm_alias_float128 (__ufromfpx, ufromfpx) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +# undef libm_alias_float128_other_r_ldbl +# define libm_alias_float128_other_r_ldbl(from, to, r) \ + weak_alias (from ## f128 ## r, __ ## to ## ieee128 ## r) +libm_alias_float128 (__compat_ufromfpx, ufromfpx) +#endif diff --git a/sysdeps/ieee754/float128/s_fromfpf128.c b/sysdeps/ieee754/float128/s_fromfpf128.c new file mode 100644 index 0000000000..5fe8c534f9 --- /dev/null +++ b/sysdeps/ieee754/float128/s_fromfpf128.c @@ -0,0 +1,20 @@ +#define UNSIGNED 0 +#define INEXACT 0 +#define FUNC __fromfpf128 +#include <float128_private.h> +#include "../ldbl-128/s_fromfpl_main.c" +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +# undef libm_alias_float128_other_r_ldbl +# define libm_alias_float128_other_r_ldbl(from, to, r) \ + weak_alias (from ## f128 ## r, __ ## to ## ieee128 ## r) +#endif +libm_alias_float128 (__fromfp, fromfp) diff --git a/sysdeps/ieee754/float128/s_fromfpxf128.c b/sysdeps/ieee754/float128/s_fromfpxf128.c new file mode 100644 index 0000000000..57d68ad55c --- /dev/null +++ b/sysdeps/ieee754/float128/s_fromfpxf128.c @@ -0,0 +1,20 @@ +#define UNSIGNED 0 +#define INEXACT 1 +#define FUNC __fromfpxf128 +#include <float128_private.h> +#include "../ldbl-128/s_fromfpl_main.c" +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +# undef libm_alias_float128_other_r_ldbl +# define libm_alias_float128_other_r_ldbl(from, to, r) \ + weak_alias (from ## f128 ## r, __ ## to ## ieee128 ## r) +#endif +libm_alias_float128 (__fromfpx, fromfpx) diff --git a/sysdeps/ieee754/float128/s_ufromfpf128.c b/sysdeps/ieee754/float128/s_ufromfpf128.c new file mode 100644 index 0000000000..1361fd1827 --- /dev/null +++ b/sysdeps/ieee754/float128/s_ufromfpf128.c @@ -0,0 +1,20 @@ +#define UNSIGNED 1 +#define INEXACT 0 +#define FUNC __ufromfpf128 +#include <float128_private.h> +#include "../ldbl-128/s_fromfpl_main.c" +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +# undef libm_alias_float128_other_r_ldbl +# define libm_alias_float128_other_r_ldbl(from, to, r) \ + weak_alias (from ## f128 ## r, __ ## to ## ieee128 ## r) +#endif +libm_alias_float128 (__ufromfp, ufromfp) diff --git a/sysdeps/ieee754/float128/s_ufromfpxf128.c b/sysdeps/ieee754/float128/s_ufromfpxf128.c new file mode 100644 index 0000000000..bc911df291 --- /dev/null +++ b/sysdeps/ieee754/float128/s_ufromfpxf128.c @@ -0,0 +1,20 @@ +#define UNSIGNED 1 +#define INEXACT 1 +#define FUNC __ufromfpxf128 +#include <float128_private.h> +#include "../ldbl-128/s_fromfpl_main.c" +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +# undef libm_alias_float128_other_r_ldbl +# define libm_alias_float128_other_r_ldbl(from, to, r) \ + weak_alias (from ## f128 ## r, __ ## to ## ieee128 ## r) +#endif +libm_alias_float128 (__ufromfpx, ufromfpx) diff --git a/sysdeps/ieee754/flt-32/s_compat_fromfpf.c b/sysdeps/ieee754/flt-32/s_compat_fromfpf.c index 666422ea61..fad1fc6358 100644 --- a/sysdeps/ieee754/flt-32/s_compat_fromfpf.c +++ b/sysdeps/ieee754/flt-32/s_compat_fromfpf.c @@ -1,5 +1,17 @@ #define UNSIGNED 0 #define INEXACT 0 -#define FUNC __fromfpf +#define FUNC __compat_fromfpf #include <s_compat_fromfpf_main.c> -libm_alias_float (__fromfp, fromfp) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +libm_alias_float (__compat_fromfp, fromfp) +#endif diff --git a/sysdeps/ieee754/flt-32/s_compat_fromfpf_main.c b/sysdeps/ieee754/flt-32/s_compat_fromfpf_main.c index 968d8837a1..6e5cc7c5d5 100644 --- a/sysdeps/ieee754/flt-32/s_compat_fromfpf_main.c +++ b/sysdeps/ieee754/flt-32/s_compat_fromfpf_main.c @@ -1,4 +1,4 @@ -/* Round to integer type. flt-32 version. +/* Round to integer type (pre-C23 compat version). flt-32 version. Copyright (C) 2016-2025 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -23,6 +23,8 @@ #include <libm-alias-float.h> #include <stdbool.h> #include <stdint.h> +#include <shlib-compat.h> +#include <first-versions.h> #define BIAS 0x7f #define MANT_DIG 24 @@ -33,9 +35,11 @@ # define RET_TYPE intmax_t #endif -#include <compat_fromfp.h> +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# include <compat_fromfp.h> RET_TYPE +attribute_compat_text_section FUNC (float x, int round, unsigned int width) { if (width > INTMAX_WIDTH) @@ -81,3 +85,4 @@ FUNC (float x, int round, unsigned int width) return fromfp_round_and_return (negative, uret, half_bit, more_bits, round, exponent, max_exponent, width); } +#endif diff --git a/sysdeps/ieee754/flt-32/s_compat_fromfpxf.c b/sysdeps/ieee754/flt-32/s_compat_fromfpxf.c index 0be126723b..9f0c4f9dc1 100644 --- a/sysdeps/ieee754/flt-32/s_compat_fromfpxf.c +++ b/sysdeps/ieee754/flt-32/s_compat_fromfpxf.c @@ -1,5 +1,17 @@ #define UNSIGNED 0 #define INEXACT 1 -#define FUNC __fromfpxf +#define FUNC __compat_fromfpxf #include <s_compat_fromfpf_main.c> -libm_alias_float (__fromfpx, fromfpx) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +libm_alias_float (__compat_fromfpx, fromfpx) +#endif diff --git a/sysdeps/ieee754/flt-32/s_compat_ufromfpf.c b/sysdeps/ieee754/flt-32/s_compat_ufromfpf.c index 5a4c59d28c..1c14400a16 100644 --- a/sysdeps/ieee754/flt-32/s_compat_ufromfpf.c +++ b/sysdeps/ieee754/flt-32/s_compat_ufromfpf.c @@ -1,5 +1,17 @@ #define UNSIGNED 1 #define INEXACT 0 -#define FUNC __ufromfpf +#define FUNC __compat_ufromfpf #include <s_compat_fromfpf_main.c> -libm_alias_float (__ufromfp, ufromfp) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +libm_alias_float (__compat_ufromfp, ufromfp) +#endif diff --git a/sysdeps/ieee754/flt-32/s_compat_ufromfpxf.c b/sysdeps/ieee754/flt-32/s_compat_ufromfpxf.c index 1e7310ea87..3045bffabb 100644 --- a/sysdeps/ieee754/flt-32/s_compat_ufromfpxf.c +++ b/sysdeps/ieee754/flt-32/s_compat_ufromfpxf.c @@ -1,5 +1,17 @@ #define UNSIGNED 1 #define INEXACT 1 -#define FUNC __ufromfpxf +#define FUNC __compat_ufromfpxf #include <s_compat_fromfpf_main.c> -libm_alias_float (__ufromfpx, ufromfpx) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +libm_alias_float (__compat_ufromfpx, ufromfpx) +#endif diff --git a/sysdeps/ieee754/flt-32/s_fromfpf.c b/sysdeps/ieee754/flt-32/s_fromfpf.c new file mode 100644 index 0000000000..36074c85f4 --- /dev/null +++ b/sysdeps/ieee754/flt-32/s_fromfpf.c @@ -0,0 +1,16 @@ +#define UNSIGNED 0 +#define INEXACT 0 +#define FUNC __fromfpf +#include <s_fromfpf_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +libm_alias_float (__fromfp, fromfp) diff --git a/sysdeps/ieee754/flt-32/s_fromfpf_main.c b/sysdeps/ieee754/flt-32/s_fromfpf_main.c new file mode 100644 index 0000000000..c6af9678a8 --- /dev/null +++ b/sysdeps/ieee754/flt-32/s_fromfpf_main.c @@ -0,0 +1,55 @@ +/* Round to integer type (C23 version). flt-32 version. + Copyright (C) 2016-2025 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/>. */ + +#include <errno.h> +#include <fenv.h> +#include <math.h> +#include <math_private.h> +#include <libm-alias-float.h> +#include <stdbool.h> +#include <stdint.h> +#include <shlib-compat.h> + +#define FLOAT float +#define PREFIX FLT_ +#define SUFFIX f +#define BIAS 0x7f +#define MANT_DIG 24 + +#include <fromfp.h> + +float +FUNC (float x, int round, unsigned int width) +{ + width = fromfp_adjust_width (width); + float rx = fromfp_round (x, round); + if (width == 0 || !isfinite (rx)) + return fromfp_domain_error (); + uint32_t ix; + GET_FLOAT_WORD (ix, rx); + bool negative = (ix & 0x80000000) != 0; + ix &= 0x7fffffff; + int exponent = ix >> (MANT_DIG - 1); + exponent -= BIAS; + int max_exponent = fromfp_max_exponent (negative, width); + ix &= ((1U << (MANT_DIG - 1)) - 1); + if (exponent > max_exponent + || (!UNSIGNED && negative && exponent == max_exponent && ix != 0)) + return fromfp_domain_error (); + return fromfp_return (x, rx); +} diff --git a/sysdeps/ieee754/flt-32/s_fromfpxf.c b/sysdeps/ieee754/flt-32/s_fromfpxf.c new file mode 100644 index 0000000000..e77fdab387 --- /dev/null +++ b/sysdeps/ieee754/flt-32/s_fromfpxf.c @@ -0,0 +1,16 @@ +#define UNSIGNED 0 +#define INEXACT 1 +#define FUNC __fromfpxf +#include <s_fromfpf_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +libm_alias_float (__fromfpx, fromfpx) diff --git a/sysdeps/ieee754/flt-32/s_ufromfpf.c b/sysdeps/ieee754/flt-32/s_ufromfpf.c new file mode 100644 index 0000000000..bf235698bc --- /dev/null +++ b/sysdeps/ieee754/flt-32/s_ufromfpf.c @@ -0,0 +1,16 @@ +#define UNSIGNED 1 +#define INEXACT 0 +#define FUNC __ufromfpf +#include <s_fromfpf_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +libm_alias_float (__ufromfp, ufromfp) diff --git a/sysdeps/ieee754/flt-32/s_ufromfpxf.c b/sysdeps/ieee754/flt-32/s_ufromfpxf.c new file mode 100644 index 0000000000..5010865e49 --- /dev/null +++ b/sysdeps/ieee754/flt-32/s_ufromfpxf.c @@ -0,0 +1,16 @@ +#define UNSIGNED 1 +#define INEXACT 1 +#define FUNC __ufromfpxf +#include <s_fromfpf_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +libm_alias_float (__ufromfpx, ufromfpx) diff --git a/sysdeps/ieee754/ldbl-128/Makefile b/sysdeps/ieee754/ldbl-128/Makefile index e0f1a6730c..c11ad5ec25 100644 --- a/sysdeps/ieee754/ldbl-128/Makefile +++ b/sysdeps/ieee754/ldbl-128/Makefile @@ -73,6 +73,8 @@ CFLAGS-s_fmull.c += -fno-builtin-f32mulf64x -fno-builtin-f32mulf128 CFLAGS-s_frexpl.c += -fno-builtin-frexpf64x -fno-builtin-frexpf128 CFLAGS-s_compat_fromfpl.c += -fno-builtin-fromfpf64x -fno-builtin-fromfpf128 CFLAGS-s_compat_fromfpxl.c += -fno-builtin-fromfpxf64x -fno-builtin-fromfpxf128 +CFLAGS-s_fromfpl.c += -fno-builtin-fromfpf64x -fno-builtin-fromfpf128 +CFLAGS-s_fromfpxl.c += -fno-builtin-fromfpxf64x -fno-builtin-fromfpxf128 CFLAGS-s_fsqrtl.c += -fno-builtin-f32sqrtf64x -fno-builtin-f32sqrtf128 CFLAGS-s_fsubl.c += -fno-builtin-f32subf64x -fno-builtin-f32subf128 CFLAGS-s_getpayloadl.c += -fno-builtin-getpayloadf64x -fno-builtin-getpayloadf128 @@ -122,6 +124,8 @@ CFLAGS-s_totalordermagl.c += -fno-builtin-totalordermagf64x -fno-builtin-totalor CFLAGS-s_truncl.c += -fno-builtin-truncf64x -fno-builtin-truncf128 CFLAGS-s_compat_ufromfpl.c += -fno-builtin-ufromfpf64x -fno-builtin-ufromfpf128 CFLAGS-s_compat_ufromfpxl.c += -fno-builtin-ufromfpxf64x -fno-builtin-ufromfpxf128 +CFLAGS-s_ufromfpl.c += -fno-builtin-ufromfpf64x -fno-builtin-ufromfpf128 +CFLAGS-s_ufromfpxl.c += -fno-builtin-ufromfpxf64x -fno-builtin-ufromfpxf128 CFLAGS-s_y0l.c += -fno-builtin-y0f64x -fno-builtin-y0f128 CFLAGS-s_y1l.c += -fno-builtin-y1f64x -fno-builtin-y1f128 CFLAGS-s_ynl.c += -fno-builtin-ynf64x -fno-builtin-ynf128 diff --git a/sysdeps/ieee754/ldbl-128/s_compat_fromfpl.c b/sysdeps/ieee754/ldbl-128/s_compat_fromfpl.c index c1cc75138f..ff4dc7e829 100644 --- a/sysdeps/ieee754/ldbl-128/s_compat_fromfpl.c +++ b/sysdeps/ieee754/ldbl-128/s_compat_fromfpl.c @@ -1,5 +1,17 @@ #define UNSIGNED 0 #define INEXACT 0 -#define FUNC __fromfpl +#define FUNC __compat_fromfpl #include <s_compat_fromfpl_main.c> -libm_alias_ldouble (__fromfp, fromfp) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +libm_alias_ldouble (__compat_fromfp, fromfp) +#endif diff --git a/sysdeps/ieee754/ldbl-128/s_compat_fromfpl_main.c b/sysdeps/ieee754/ldbl-128/s_compat_fromfpl_main.c index 529839449b..3f2e7d44f7 100644 --- a/sysdeps/ieee754/ldbl-128/s_compat_fromfpl_main.c +++ b/sysdeps/ieee754/ldbl-128/s_compat_fromfpl_main.c @@ -1,4 +1,4 @@ -/* Round to integer type. ldbl-128 version. +/* Round to integer type (pre-C23 compat version). ldbl-128 version. Copyright (C) 2016-2025 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -23,6 +23,8 @@ #include <libm-alias-ldouble.h> #include <stdbool.h> #include <stdint.h> +#include <shlib-compat.h> +#include <first-versions.h> #define BIAS 0x3fff #define MANT_DIG 113 @@ -33,9 +35,11 @@ # define RET_TYPE intmax_t #endif -#include <compat_fromfp.h> +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# include <compat_fromfp.h> RET_TYPE +attribute_compat_text_section FUNC (_Float128 x, int round, unsigned int width) { if (width > INTMAX_WIDTH) @@ -89,3 +93,4 @@ FUNC (_Float128 x, int round, unsigned int width) return fromfp_round_and_return (negative, uret, half_bit, more_bits, round, exponent, max_exponent, width); } +#endif diff --git a/sysdeps/ieee754/ldbl-128/s_compat_fromfpxl.c b/sysdeps/ieee754/ldbl-128/s_compat_fromfpxl.c index c10f6a3f5a..4ab233b43f 100644 --- a/sysdeps/ieee754/ldbl-128/s_compat_fromfpxl.c +++ b/sysdeps/ieee754/ldbl-128/s_compat_fromfpxl.c @@ -1,5 +1,17 @@ #define UNSIGNED 0 #define INEXACT 1 -#define FUNC __fromfpxl +#define FUNC __compat_fromfpxl #include <s_compat_fromfpl_main.c> -libm_alias_ldouble (__fromfpx, fromfpx) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +libm_alias_ldouble (__compat_fromfpx, fromfpx) +#endif diff --git a/sysdeps/ieee754/ldbl-128/s_compat_ufromfpl.c b/sysdeps/ieee754/ldbl-128/s_compat_ufromfpl.c index 27e9aca9df..8b05ab872f 100644 --- a/sysdeps/ieee754/ldbl-128/s_compat_ufromfpl.c +++ b/sysdeps/ieee754/ldbl-128/s_compat_ufromfpl.c @@ -1,5 +1,17 @@ #define UNSIGNED 1 #define INEXACT 0 -#define FUNC __ufromfpl +#define FUNC __compat_ufromfpl #include <s_compat_fromfpl_main.c> -libm_alias_ldouble (__ufromfp, ufromfp) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +libm_alias_ldouble (__compat_ufromfp, ufromfp) +#endif diff --git a/sysdeps/ieee754/ldbl-128/s_compat_ufromfpxl.c b/sysdeps/ieee754/ldbl-128/s_compat_ufromfpxl.c index f5222fed1a..9a9219dc15 100644 --- a/sysdeps/ieee754/ldbl-128/s_compat_ufromfpxl.c +++ b/sysdeps/ieee754/ldbl-128/s_compat_ufromfpxl.c @@ -1,5 +1,17 @@ #define UNSIGNED 1 #define INEXACT 1 -#define FUNC __ufromfpxl +#define FUNC __compat_ufromfpxl #include <s_compat_fromfpl_main.c> -libm_alias_ldouble (__ufromfpx, ufromfpx) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +libm_alias_ldouble (__compat_ufromfpx, ufromfpx) +#endif diff --git a/sysdeps/ieee754/ldbl-128/s_fromfpl.c b/sysdeps/ieee754/ldbl-128/s_fromfpl.c new file mode 100644 index 0000000000..479da91b2b --- /dev/null +++ b/sysdeps/ieee754/ldbl-128/s_fromfpl.c @@ -0,0 +1,16 @@ +#define UNSIGNED 0 +#define INEXACT 0 +#define FUNC __fromfpl +#include <s_fromfpl_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +libm_alias_ldouble (__fromfp, fromfp) diff --git a/sysdeps/ieee754/ldbl-128/s_fromfpl_main.c b/sysdeps/ieee754/ldbl-128/s_fromfpl_main.c new file mode 100644 index 0000000000..e029fadb99 --- /dev/null +++ b/sysdeps/ieee754/ldbl-128/s_fromfpl_main.c @@ -0,0 +1,55 @@ +/* Round to integer type (C23 version). ldbl-128 version. + Copyright (C) 2016-2025 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/>. */ + +#include <errno.h> +#include <fenv.h> +#include <math.h> +#include <math_private.h> +#include <libm-alias-ldouble.h> +#include <stdbool.h> +#include <stdint.h> +#include <shlib-compat.h> + +#define FLOAT _Float128 +#define PREFIX LDBL_ +#define SUFFIX l +#define BIAS 0x3fff +#define MANT_DIG 113 + +#include <fromfp.h> + +_Float128 +FUNC (_Float128 x, int round, unsigned int width) +{ + width = fromfp_adjust_width (width); + _Float128 rx = fromfp_round (x, round); + if (width == 0 || !isfinite (rx)) + return fromfp_domain_error (); + uint64_t hx, lx; + GET_LDOUBLE_WORDS64 (hx, lx, rx); + bool negative = (hx & 0x8000000000000000ULL) != 0; + hx &= 0x7fffffffffffffffULL; + int exponent = hx >> (MANT_DIG - 1 - 64); + exponent -= BIAS; + int max_exponent = fromfp_max_exponent (negative, width); + hx &= ((1ULL << (MANT_DIG - 1 - 64)) - 1); + if (exponent > max_exponent + || (!UNSIGNED && negative && exponent == max_exponent && (hx | lx) != 0)) + return fromfp_domain_error (); + return fromfp_return (x, rx); +} diff --git a/sysdeps/ieee754/ldbl-128/s_fromfpxl.c b/sysdeps/ieee754/ldbl-128/s_fromfpxl.c new file mode 100644 index 0000000000..a730345ec2 --- /dev/null +++ b/sysdeps/ieee754/ldbl-128/s_fromfpxl.c @@ -0,0 +1,16 @@ +#define UNSIGNED 0 +#define INEXACT 1 +#define FUNC __fromfpxl +#include <s_fromfpl_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +libm_alias_ldouble (__fromfpx, fromfpx) diff --git a/sysdeps/ieee754/ldbl-128/s_ufromfpl.c b/sysdeps/ieee754/ldbl-128/s_ufromfpl.c new file mode 100644 index 0000000000..53c892f62a --- /dev/null +++ b/sysdeps/ieee754/ldbl-128/s_ufromfpl.c @@ -0,0 +1,16 @@ +#define UNSIGNED 1 +#define INEXACT 0 +#define FUNC __ufromfpl +#include <s_fromfpl_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +libm_alias_ldouble (__ufromfp, ufromfp) diff --git a/sysdeps/ieee754/ldbl-128/s_ufromfpxl.c b/sysdeps/ieee754/ldbl-128/s_ufromfpxl.c new file mode 100644 index 0000000000..394f60610d --- /dev/null +++ b/sysdeps/ieee754/ldbl-128/s_ufromfpxl.c @@ -0,0 +1,16 @@ +#define UNSIGNED 1 +#define INEXACT 1 +#define FUNC __ufromfpxl +#include <s_fromfpl_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +libm_alias_ldouble (__ufromfpx, ufromfpx) diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/Makefile b/sysdeps/ieee754/ldbl-128ibm-compat/Makefile index ef3df9dbfb..10ae73dba1 100644 --- a/sysdeps/ieee754/ldbl-128ibm-compat/Makefile +++ b/sysdeps/ieee754/ldbl-128ibm-compat/Makefile @@ -391,6 +391,15 @@ ifeq ($(subdir),math) # support. Thus, they can only correctly be used with ibm128. CFLAGS-test-ldouble-compat_totalorder.c += -mabi=ibmlongdouble CFLAGS-test-ldouble-compat_totalordermag.c += -mabi=ibmlongdouble + +# The compatibility tests for fromfp functions access particular +# versioned symbols by name, and those symbols are for the ibm128 +# format. (It would also be possible to test the *ieee128 compat +# symbols, but these tests don't do so.) +CFLAGS-test-ldouble-compat_fromfp.c += -mabi=ibmlongdouble +CFLAGS-test-ldouble-compat_fromfpx.c += -mabi=ibmlongdouble +CFLAGS-test-ldouble-compat_ufromfp.c += -mabi=ibmlongdouble +CFLAGS-test-ldouble-compat_ufromfpx.c += -mabi=ibmlongdouble endif ifeq ($(subdir), stdio-common) diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/Versions b/sysdeps/ieee754/ldbl-128ibm-compat/Versions index ae4bd5bc14..00c0b445cd 100644 --- a/sysdeps/ieee754/ldbl-128ibm-compat/Versions +++ b/sysdeps/ieee754/ldbl-128ibm-compat/Versions @@ -160,6 +160,12 @@ libm { __rootnieee128; __rsqrtieee128; } + GLIBC_2.43 { + __fromfpieee128; + __fromfpxieee128; + __ufromfpieee128; + __ufromfpxieee128; + } } libc { LDBL_IBM128_VERSION { diff --git a/sysdeps/ieee754/ldbl-128ibm/s_compat_fromfpl.c b/sysdeps/ieee754/ldbl-128ibm/s_compat_fromfpl.c index 844f86363b..d578fde6aa 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_compat_fromfpl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_compat_fromfpl.c @@ -1,5 +1,17 @@ #define UNSIGNED 0 #define INEXACT 0 -#define FUNC __fromfpl +#define FUNC __compat_fromfpl #include <s_compat_fromfpl_main.c> -weak_alias (__fromfpl, fromfpl) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +weak_alias (__compat_fromfpl, fromfpl) +#endif diff --git a/sysdeps/ieee754/ldbl-128ibm/s_compat_fromfpl_main.c b/sysdeps/ieee754/ldbl-128ibm/s_compat_fromfpl_main.c index 83178b58e7..1b01d73a4c 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_compat_fromfpl_main.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_compat_fromfpl_main.c @@ -1,4 +1,4 @@ -/* Round to integer type. ldbl-128ibm version. +/* Round to integer type (pre-C23 compat version). ldbl-128ibm version. Copyright (C) 2016-2025 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -22,6 +22,8 @@ #include <math_private.h> #include <stdbool.h> #include <stdint.h> +#include <shlib-compat.h> +#include <first-versions.h> #define BIAS 0x3ff #define MANT_DIG 53 @@ -32,9 +34,11 @@ # define RET_TYPE intmax_t #endif -#include <compat_fromfp.h> +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# include <compat_fromfp.h> RET_TYPE +attribute_compat_text_section FUNC (long double x, int round, unsigned int width) { double hi, lo; @@ -145,3 +149,4 @@ FUNC (long double x, int round, unsigned int width) return fromfp_round_and_return (negative, uret, half_bit, more_bits, round, exponent, max_exponent, width); } +#endif diff --git a/sysdeps/ieee754/ldbl-128ibm/s_compat_fromfpxl.c b/sysdeps/ieee754/ldbl-128ibm/s_compat_fromfpxl.c index 8117dce3d0..b0ac77c703 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_compat_fromfpxl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_compat_fromfpxl.c @@ -1,5 +1,17 @@ #define UNSIGNED 0 #define INEXACT 1 -#define FUNC __fromfpxl +#define FUNC __compat_fromfpxl #include <s_compat_fromfpl_main.c> -weak_alias (__fromfpxl, fromfpxl) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +weak_alias (__compat_fromfpxl, fromfpxl) +#endif diff --git a/sysdeps/ieee754/ldbl-128ibm/s_compat_ufromfpl.c b/sysdeps/ieee754/ldbl-128ibm/s_compat_ufromfpl.c index e42417744d..0d6302a4d9 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_compat_ufromfpl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_compat_ufromfpl.c @@ -1,5 +1,17 @@ #define UNSIGNED 1 #define INEXACT 0 -#define FUNC __ufromfpl +#define FUNC __compat_ufromfpl #include <s_compat_fromfpl_main.c> -weak_alias (__ufromfpl, ufromfpl) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +weak_alias (__compat_ufromfpl, ufromfpl) +#endif diff --git a/sysdeps/ieee754/ldbl-128ibm/s_compat_ufromfpxl.c b/sysdeps/ieee754/ldbl-128ibm/s_compat_ufromfpxl.c index a21f548af0..5b738a1ce2 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_compat_ufromfpxl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_compat_ufromfpxl.c @@ -1,5 +1,17 @@ #define UNSIGNED 1 #define INEXACT 1 -#define FUNC __ufromfpxl +#define FUNC __compat_ufromfpxl #include <s_compat_fromfpl_main.c> -weak_alias (__ufromfpxl, ufromfpxl) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +weak_alias (__compat_ufromfpxl, ufromfpxl) +#endif diff --git a/sysdeps/ieee754/ldbl-128ibm/s_fromfpl.c b/sysdeps/ieee754/ldbl-128ibm/s_fromfpl.c new file mode 100644 index 0000000000..860a9d5d2b --- /dev/null +++ b/sysdeps/ieee754/ldbl-128ibm/s_fromfpl.c @@ -0,0 +1,16 @@ +#define UNSIGNED 0 +#define INEXACT 0 +#define FUNC __fromfpl +#include <s_fromfpl_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +weak_alias (__fromfpl, fromfpl) diff --git a/sysdeps/ieee754/ldbl-128ibm/s_fromfpl_main.c b/sysdeps/ieee754/ldbl-128ibm/s_fromfpl_main.c new file mode 100644 index 0000000000..81ebc5e2a8 --- /dev/null +++ b/sysdeps/ieee754/ldbl-128ibm/s_fromfpl_main.c @@ -0,0 +1,62 @@ +/* Round to integer type (C23 version). ldbl-128ibm version. + Copyright (C) 2016-2025 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/>. */ + +#include <errno.h> +#include <fenv.h> +#include <math.h> +#include <math_private.h> +#include <stdbool.h> +#include <stdint.h> +#include <shlib-compat.h> + +#define FLOAT long double +#define PREFIX LDBL_ +#define SUFFIX l +#define BIAS 0x3ff +#define MANT_DIG 53 + +#include <fromfp.h> + +long double +FUNC (long double x, int round, unsigned int width) +{ + width = fromfp_adjust_width (width); + long double rx = fromfp_round (x, round); + if (width == 0 || !isfinite (rx)) + return fromfp_domain_error (); + double hi, lo; + uint64_t hx, lx; + ldbl_unpack (rx, &hi, &lo); + EXTRACT_WORDS64 (hx, hi); + EXTRACT_WORDS64 (lx, lo); + bool negative = (hx & 0x8000000000000000ULL) != 0; + bool lo_negative = (lx & 0x8000000000000000ULL) != 0; + hx &= 0x7fffffffffffffffULL; + lx &= 0x7fffffffffffffffULL; + int hi_exponent = hx >> (MANT_DIG - 1); + hi_exponent -= BIAS; + int exponent = hi_exponent; + hx &= ((1ULL << (MANT_DIG - 1)) - 1); + if (hx == 0 && lx != 0 && lo_negative != negative) + exponent--; + int max_exponent = fromfp_max_exponent (negative, width); + if (exponent > max_exponent + || (!UNSIGNED && negative && exponent == max_exponent && (hx | lx) != 0)) + return fromfp_domain_error (); + return fromfp_return (x, rx); +} diff --git a/sysdeps/ieee754/ldbl-128ibm/s_fromfpxl.c b/sysdeps/ieee754/ldbl-128ibm/s_fromfpxl.c new file mode 100644 index 0000000000..d2b836d0dd --- /dev/null +++ b/sysdeps/ieee754/ldbl-128ibm/s_fromfpxl.c @@ -0,0 +1,16 @@ +#define UNSIGNED 0 +#define INEXACT 1 +#define FUNC __fromfpxl +#include <s_fromfpl_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +weak_alias (__fromfpxl, fromfpxl) diff --git a/sysdeps/ieee754/ldbl-128ibm/s_ufromfpl.c b/sysdeps/ieee754/ldbl-128ibm/s_ufromfpl.c new file mode 100644 index 0000000000..83b80b8418 --- /dev/null +++ b/sysdeps/ieee754/ldbl-128ibm/s_ufromfpl.c @@ -0,0 +1,16 @@ +#define UNSIGNED 1 +#define INEXACT 0 +#define FUNC __ufromfpl +#include <s_fromfpl_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +weak_alias (__ufromfpl, ufromfpl) diff --git a/sysdeps/ieee754/ldbl-128ibm/s_ufromfpxl.c b/sysdeps/ieee754/ldbl-128ibm/s_ufromfpxl.c new file mode 100644 index 0000000000..0b1a4fe3c1 --- /dev/null +++ b/sysdeps/ieee754/ldbl-128ibm/s_ufromfpxl.c @@ -0,0 +1,16 @@ +#define UNSIGNED 1 +#define INEXACT 1 +#define FUNC __ufromfpxl +#include <s_fromfpl_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +weak_alias (__ufromfpxl, ufromfpxl) diff --git a/sysdeps/ieee754/ldbl-96/Makefile b/sysdeps/ieee754/ldbl-96/Makefile index 72b9322771..cd140bc707 100644 --- a/sysdeps/ieee754/ldbl-96/Makefile +++ b/sysdeps/ieee754/ldbl-96/Makefile @@ -94,6 +94,8 @@ CFLAGS-s_fmull.c += -fno-builtin-f32mulf64x CFLAGS-s_frexpl.c += -fno-builtin-frexpf64x CFLAGS-s_compat_fromfpl.c += -fno-builtin-fromfpf64x CFLAGS-s_compat_fromfpxl.c += -fno-builtin-fromfpxf64x +CFLAGS-s_fromfpl.c += -fno-builtin-fromfpf64x +CFLAGS-s_fromfpxl.c += -fno-builtin-fromfpxf64x CFLAGS-s_fsqrtl.c += -fno-builtin-f32sqrtf64x CFLAGS-s_fsubl.c += -fno-builtin-f32subf64x CFLAGS-s_getpayloadl.c += -fno-builtin-getpayloadf64x @@ -143,6 +145,8 @@ CFLAGS-s_totalordermagl.c += -fno-builtin-totalordermagf64x CFLAGS-s_truncl.c += -fno-builtin-truncf64x CFLAGS-s_compat_ufromfpl.c += -fno-builtin-ufromfpf64x CFLAGS-s_compat_ufromfpxl.c += -fno-builtin-ufromfpxf64x +CFLAGS-s_ufromfpl.c += -fno-builtin-ufromfpf64x +CFLAGS-s_ufromfpxl.c += -fno-builtin-ufromfpxf64x CFLAGS-s_y0l.c += -fno-builtin-y0f64x CFLAGS-s_y1l.c += -fno-builtin-y1f64x CFLAGS-s_ynl.c += -fno-builtin-ynf64x diff --git a/sysdeps/ieee754/ldbl-96/s_compat_fromfpl.c b/sysdeps/ieee754/ldbl-96/s_compat_fromfpl.c index c1cc75138f..ff4dc7e829 100644 --- a/sysdeps/ieee754/ldbl-96/s_compat_fromfpl.c +++ b/sysdeps/ieee754/ldbl-96/s_compat_fromfpl.c @@ -1,5 +1,17 @@ #define UNSIGNED 0 #define INEXACT 0 -#define FUNC __fromfpl +#define FUNC __compat_fromfpl #include <s_compat_fromfpl_main.c> -libm_alias_ldouble (__fromfp, fromfp) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +libm_alias_ldouble (__compat_fromfp, fromfp) +#endif diff --git a/sysdeps/ieee754/ldbl-96/s_compat_fromfpl_main.c b/sysdeps/ieee754/ldbl-96/s_compat_fromfpl_main.c index 5abac57cef..651dcb2dd7 100644 --- a/sysdeps/ieee754/ldbl-96/s_compat_fromfpl_main.c +++ b/sysdeps/ieee754/ldbl-96/s_compat_fromfpl_main.c @@ -1,4 +1,4 @@ -/* Round to integer type. ldbl-96 version. +/* Round to integer type (pre-C23 compat version). ldbl-96 version. Copyright (C) 2016-2025 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -23,6 +23,8 @@ #include <libm-alias-ldouble.h> #include <stdbool.h> #include <stdint.h> +#include <shlib-compat.h> +#include <first-versions.h> #define BIAS 0x3fff #define MANT_DIG 64 @@ -33,9 +35,11 @@ # define RET_TYPE intmax_t #endif -#include <compat_fromfp.h> +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# include <compat_fromfp.h> RET_TYPE +attribute_compat_text_section FUNC (long double x, int round, unsigned int width) { if (width > INTMAX_WIDTH) @@ -83,3 +87,4 @@ FUNC (long double x, int round, unsigned int width) return fromfp_round_and_return (negative, uret, half_bit, more_bits, round, exponent, max_exponent, width); } +#endif diff --git a/sysdeps/ieee754/ldbl-96/s_compat_fromfpxl.c b/sysdeps/ieee754/ldbl-96/s_compat_fromfpxl.c index c10f6a3f5a..4ab233b43f 100644 --- a/sysdeps/ieee754/ldbl-96/s_compat_fromfpxl.c +++ b/sysdeps/ieee754/ldbl-96/s_compat_fromfpxl.c @@ -1,5 +1,17 @@ #define UNSIGNED 0 #define INEXACT 1 -#define FUNC __fromfpxl +#define FUNC __compat_fromfpxl #include <s_compat_fromfpl_main.c> -libm_alias_ldouble (__fromfpx, fromfpx) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +libm_alias_ldouble (__compat_fromfpx, fromfpx) +#endif diff --git a/sysdeps/ieee754/ldbl-96/s_compat_ufromfpl.c b/sysdeps/ieee754/ldbl-96/s_compat_ufromfpl.c index 27e9aca9df..8b05ab872f 100644 --- a/sysdeps/ieee754/ldbl-96/s_compat_ufromfpl.c +++ b/sysdeps/ieee754/ldbl-96/s_compat_ufromfpl.c @@ -1,5 +1,17 @@ #define UNSIGNED 1 #define INEXACT 0 -#define FUNC __ufromfpl +#define FUNC __compat_ufromfpl #include <s_compat_fromfpl_main.c> -libm_alias_ldouble (__ufromfp, ufromfp) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +libm_alias_ldouble (__compat_ufromfp, ufromfp) +#endif diff --git a/sysdeps/ieee754/ldbl-96/s_compat_ufromfpxl.c b/sysdeps/ieee754/ldbl-96/s_compat_ufromfpxl.c index f5222fed1a..9a9219dc15 100644 --- a/sysdeps/ieee754/ldbl-96/s_compat_ufromfpxl.c +++ b/sysdeps/ieee754/ldbl-96/s_compat_ufromfpxl.c @@ -1,5 +1,17 @@ #define UNSIGNED 1 #define INEXACT 1 -#define FUNC __ufromfpxl +#define FUNC __compat_ufromfpxl #include <s_compat_fromfpl_main.c> -libm_alias_ldouble (__ufromfpx, ufromfpx) +#if SHLIB_COMPAT (libm, GLIBC_2_25, GLIBC_2_43) +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + compat_symbol (libm, name, aliasname, \ + CONCAT (FIRST_VERSION_libm_, aliasname)) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +libm_alias_ldouble (__compat_ufromfpx, ufromfpx) +#endif diff --git a/sysdeps/ieee754/ldbl-96/s_fromfpl.c b/sysdeps/ieee754/ldbl-96/s_fromfpl.c new file mode 100644 index 0000000000..479da91b2b --- /dev/null +++ b/sysdeps/ieee754/ldbl-96/s_fromfpl.c @@ -0,0 +1,16 @@ +#define UNSIGNED 0 +#define INEXACT 0 +#define FUNC __fromfpl +#include <s_fromfpl_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +libm_alias_ldouble (__fromfp, fromfp) diff --git a/sysdeps/ieee754/ldbl-96/s_fromfpl_main.c b/sysdeps/ieee754/ldbl-96/s_fromfpl_main.c new file mode 100644 index 0000000000..bd6e7d7c4d --- /dev/null +++ b/sysdeps/ieee754/ldbl-96/s_fromfpl_main.c @@ -0,0 +1,58 @@ +/* Round to integer type (C23 version). ldbl-96 version. + Copyright (C) 2016-2025 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/>. */ + +#include <errno.h> +#include <fenv.h> +#include <math.h> +#include <math_private.h> +#include <libm-alias-ldouble.h> +#include <stdbool.h> +#include <stdint.h> +#include <shlib-compat.h> + +#define FLOAT long double +#define PREFIX LDBL_ +#define SUFFIX l +#define BIAS 0x3fff +#define MANT_DIG 64 + +#include <fromfp.h> + +long double +FUNC (long double x, int round, unsigned int width) +{ + width = fromfp_adjust_width (width); + long double rx = fromfp_round (x, round); + if (width == 0 || !isfinite (rx)) + return fromfp_domain_error (); + uint16_t se; + uint32_t hx, lx; + GET_LDOUBLE_WORDS (se, hx, lx, rx); + bool negative = (se & 0x8000) != 0; + int exponent = se & 0x7fff; + exponent -= BIAS; + int max_exponent = fromfp_max_exponent (negative, width); + uint64_t ix = (((uint64_t) hx) << 32) | lx; + if (exponent > max_exponent + || (!UNSIGNED + && negative + && exponent == max_exponent + && ix != 0x8000000000000000ULL)) + return fromfp_domain_error (); + return fromfp_return (x, rx); +} diff --git a/sysdeps/ieee754/ldbl-96/s_fromfpxl.c b/sysdeps/ieee754/ldbl-96/s_fromfpxl.c new file mode 100644 index 0000000000..a730345ec2 --- /dev/null +++ b/sysdeps/ieee754/ldbl-96/s_fromfpxl.c @@ -0,0 +1,16 @@ +#define UNSIGNED 0 +#define INEXACT 1 +#define FUNC __fromfpxl +#include <s_fromfpl_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +libm_alias_ldouble (__fromfpx, fromfpx) diff --git a/sysdeps/ieee754/ldbl-96/s_ufromfpl.c b/sysdeps/ieee754/ldbl-96/s_ufromfpl.c new file mode 100644 index 0000000000..53c892f62a --- /dev/null +++ b/sysdeps/ieee754/ldbl-96/s_ufromfpl.c @@ -0,0 +1,16 @@ +#define UNSIGNED 1 +#define INEXACT 0 +#define FUNC __ufromfpl +#include <s_fromfpl_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +libm_alias_ldouble (__ufromfp, ufromfp) diff --git a/sysdeps/ieee754/ldbl-96/s_ufromfpxl.c b/sysdeps/ieee754/ldbl-96/s_ufromfpxl.c new file mode 100644 index 0000000000..394f60610d --- /dev/null +++ b/sysdeps/ieee754/ldbl-96/s_ufromfpxl.c @@ -0,0 +1,16 @@ +#define UNSIGNED 1 +#define INEXACT 1 +#define FUNC __ufromfpxl +#include <s_fromfpl_main.c> +#ifdef SHARED +# define CONCATX(x, y) x ## y +# define CONCAT(x, y) CONCATX (x, y) +# define UNIQUE_ALIAS(name) CONCAT (name, __COUNTER__) +# define do_symbol(orig_name, name, aliasname) \ + strong_alias (orig_name, name) \ + versioned_symbol (libm, name, aliasname, GLIBC_2_43) +# undef weak_alias +# define weak_alias(name, aliasname) \ + do_symbol (name, UNIQUE_ALIAS (name), aliasname); +#endif +libm_alias_ldouble (__ufromfpx, ufromfpx) diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-fromfp.c b/sysdeps/ieee754/ldbl-opt/nldbl-fromfp.c index 4b5143d278..0b17d9f203 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-fromfp.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-fromfp.c @@ -18,7 +18,7 @@ #include "nldbl-compat.h" -intmax_t +double attribute_hidden fromfpl (double x, int round, unsigned int width) { diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-fromfpx.c b/sysdeps/ieee754/ldbl-opt/nldbl-fromfpx.c index a3d9599e6d..c6d282e1aa 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-fromfpx.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-fromfpx.c @@ -18,7 +18,7 @@ #include "nldbl-compat.h" -intmax_t +double attribute_hidden fromfpxl (double x, int round, unsigned int width) { diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-ufromfp.c b/sysdeps/ieee754/ldbl-opt/nldbl-ufromfp.c index 10018ad456..5135fb637b 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-ufromfp.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-ufromfp.c @@ -18,7 +18,7 @@ #include "nldbl-compat.h" -uintmax_t +double attribute_hidden ufromfpl (double x, int round, unsigned int width) { diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-ufromfpx.c b/sysdeps/ieee754/ldbl-opt/nldbl-ufromfpx.c index 3016659903..335d8405e3 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-ufromfpx.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-ufromfpx.c @@ -18,7 +18,7 @@ #include "nldbl-compat.h" -uintmax_t +double attribute_hidden ufromfpxl (double x, int round, unsigned int width) { |
