projects/guix·blob python-team · refs

9653 lines · 333.4 KiB

1Updates from upstream's release/2.39/master branch, up to commit c7c3f5bf80ae86b34501f473f1a9fc545c911b7f.
2
3diff --git a/ADVISORIES b/ADVISORIES
4new file mode 100644
5index 0000000000..d4e33f2df3
6--- /dev/null
7+++ b/ADVISORIES
8@@ -0,0 +1,2 @@
9+For the GNU C Library Security Advisories, see the git master branch:
10+https://sourceware.org/git/?p=glibc.git;a=tree;f=advisories;hb=HEAD
11diff --git a/Makeconfig b/Makeconfig
12index 85e00cef94..522182abdc 100644
13--- a/Makeconfig
14+++ b/Makeconfig
15@@ -586,10 +586,13 @@ link-libc-rpath-link = -Wl,-rpath-link=$(rpath-link)
16 # before the expansion of LDLIBS-* variables).
17
18 # Tests use -Wl,-rpath instead of -Wl,-rpath-link for
19-# build-hardcoded-path-in-tests.
20+# build-hardcoded-path-in-tests. Add -Wl,--disable-new-dtags to force
21+# DT_RPATH instead of DT_RUNPATH which only applies to DT_NEEDED entries
22+# in the executable and doesn't applies to DT_NEEDED entries in shared
23+# libraries which are loaded via DT_NEEDED entries in the executable.
24 ifeq (yes,$(build-hardcoded-path-in-tests))
25-link-libc-tests-rpath-link = $(link-libc-rpath)
26-link-test-modules-rpath-link = $(link-libc-rpath)
27+link-libc-tests-rpath-link = $(link-libc-rpath) -Wl,--disable-new-dtags
28+link-test-modules-rpath-link = $(link-libc-rpath) -Wl,--disable-new-dtags
29 else
30 link-libc-tests-rpath-link = $(link-libc-rpath-link)
31 link-test-modules-rpath-link =
32diff --git a/Makefile b/Makefile
33index 7052b46df8..2e351c0321 100644
34--- a/Makefile
35+++ b/Makefile
36@@ -577,6 +577,13 @@ $(objpfx)lint-makefiles.out: scripts/lint-makefiles.sh
37 $(SHELL) $< "$(PYTHON)" `pwd` > $@ ; \
38 $(evaluate-test)
39
40+# Link libc.a as a whole to verify that it does not contain multiple
41+# definitions of any symbols.
42+tests-special += $(objpfx)link-static-libc.out
43+$(objpfx)link-static-libc.out:
44+ $(LINK.o) $(whole-archive) -r $(objpfx)libc.a -o /dev/null > $@ 2>&1; \
45+ $(evaluate-test)
46+
47 # Print test summary for tests in $1 .sum file;
48 # $2 is optional test identifier.
49 # Fail if there are unexpected failures in the test results.
50diff --git a/advisories/GLIBC-SA-2023-0001 b/advisories/GLIBC-SA-2023-0001
51deleted file mode 100644
52index 3d19c91b6a..0000000000
53--- a/advisories/GLIBC-SA-2023-0001
54+++ /dev/null
55@@ -1,14 +0,0 @@
56-printf: incorrect output for integers with thousands separator and width field
57-
58-When the printf family of functions is called with a format specifier
59-that uses an <apostrophe> (enable grouping) and a minimum width
60-specifier, the resulting output could be larger than reasonably expected
61-by a caller that computed a tight bound on the buffer size. The
62-resulting larger than expected output could result in a buffer overflow
63-in the printf family of functions.
64-
65-CVE-Id: CVE-2023-25139
66-Public-Date: 2023-02-02
67-Vulnerable-Commit: e88b9f0e5cc50cab57a299dc7efe1a4eb385161d (2.37)
68-Fix-Commit: c980549cc6a1c03c23cc2fe3e7b0fe626a0364b0 (2.38)
69-Fix-Commit: 07b9521fc6369d000216b96562ff7c0ed32a16c4 (2.37-4)
70diff --git a/advisories/GLIBC-SA-2023-0002 b/advisories/GLIBC-SA-2023-0002
71deleted file mode 100644
72index 5122669a64..0000000000
73--- a/advisories/GLIBC-SA-2023-0002
74+++ /dev/null
75@@ -1,15 +0,0 @@
76-getaddrinfo: Stack read overflow in no-aaaa mode
77-
78-If the system is configured in no-aaaa mode via /etc/resolv.conf,
79-getaddrinfo is called for the AF_UNSPEC address family, and a DNS
80-response is received over TCP that is larger than 2048 bytes,
81-getaddrinfo may potentially disclose stack contents via the returned
82-address data, or crash.
83-
84-CVE-Id: CVE-2023-4527
85-Public-Date: 2023-09-12
86-Vulnerable-Commit: f282cdbe7f436c75864e5640a409a10485e9abb2 (2.36)
87-Fix-Commit: bd77dd7e73e3530203be1c52c8a29d08270cb25d (2.39)
88-Fix-Commit: 4ea972b7edd7e36610e8cde18bf7a8149d7bac4f (2.36-113)
89-Fix-Commit: b7529346025a130fee483d42178b5c118da971bb (2.37-38)
90-Fix-Commit: b25508dd774b617f99419bdc3cf2ace4560cd2d6 (2.38-19)
91diff --git a/advisories/GLIBC-SA-2023-0003 b/advisories/GLIBC-SA-2023-0003
92deleted file mode 100644
93index d3aef80348..0000000000
94--- a/advisories/GLIBC-SA-2023-0003
95+++ /dev/null
96@@ -1,15 +0,0 @@
97-getaddrinfo: Potential use-after-free
98-
99-When an NSS plugin only implements the _gethostbyname2_r and
100-_getcanonname_r callbacks, getaddrinfo could use memory that was freed
101-during buffer resizing, potentially causing a crash or read or write to
102-arbitrary memory.
103-
104-CVE-Id: CVE-2023-4806
105-Public-Date: 2023-09-12
106-Fix-Commit: 973fe93a5675c42798b2161c6f29c01b0e243994 (2.39)
107-Fix-Commit: e09ee267c03e3150c2c9ba28625ab130705a485e (2.34-420)
108-Fix-Commit: e3ccb230a961b4797510e6a1f5f21fd9021853e7 (2.35-270)
109-Fix-Commit: a9728f798ec7f05454c95637ee6581afaa9b487d (2.36-115)
110-Fix-Commit: 6529a7466c935f36e9006b854d6f4e1d4876f942 (2.37-39)
111-Fix-Commit: 00ae4f10b504bc4564e9f22f00907093f1ab9338 (2.38-20)
112diff --git a/advisories/GLIBC-SA-2023-0004 b/advisories/GLIBC-SA-2023-0004
113deleted file mode 100644
114index 5286a7aa54..0000000000
115--- a/advisories/GLIBC-SA-2023-0004
116+++ /dev/null
117@@ -1,16 +0,0 @@
118-tunables: local privilege escalation through buffer overflow
119-
120-If a tunable of the form NAME=NAME=VAL is passed in the environment of a
121-setuid program and NAME is valid, it may result in a buffer overflow,
122-which could be exploited to achieve escalated privileges. This flaw was
123-introduced in glibc 2.34.
124-
125-CVE-Id: CVE-2023-4911
126-Public-Date: 2023-10-03
127-Vulnerable-Commit: 2ed18c5b534d9e92fc006202a5af0df6b72e7aca (2.34)
128-Fix-Commit: 1056e5b4c3f2d90ed2b4a55f96add28da2f4c8fa (2.39)
129-Fix-Commit: dcc367f148bc92e7f3778a125f7a416b093964d9 (2.34-423)
130-Fix-Commit: c84018a05aec80f5ee6f682db0da1130b0196aef (2.35-274)
131-Fix-Commit: 22955ad85186ee05834e47e665056148ca07699c (2.36-118)
132-Fix-Commit: b4e23c75aea756b4bddc4abcf27a1c6dca8b6bd3 (2.37-45)
133-Fix-Commit: 750a45a783906a19591fb8ff6b7841470f1f5701 (2.38-27)
134diff --git a/advisories/GLIBC-SA-2023-0005 b/advisories/GLIBC-SA-2023-0005
135deleted file mode 100644
136index cc4eb90b82..0000000000
137--- a/advisories/GLIBC-SA-2023-0005
138+++ /dev/null
139@@ -1,18 +0,0 @@
140-getaddrinfo: DoS due to memory leak
141-
142-The fix for CVE-2023-4806 introduced a memory leak when an application
143-calls getaddrinfo for AF_INET6 with AI_CANONNAME, AI_ALL and AI_V4MAPPED
144-flags set.
145-
146-CVE-Id: CVE-2023-5156
147-Public-Date: 2023-09-25
148-Vulnerable-Commit: e09ee267c03e3150c2c9ba28625ab130705a485e (2.34-420)
149-Vulnerable-Commit: e3ccb230a961b4797510e6a1f5f21fd9021853e7 (2.35-270)
150-Vulnerable-Commit: a9728f798ec7f05454c95637ee6581afaa9b487d (2.36-115)
151-Vulnerable-Commit: 6529a7466c935f36e9006b854d6f4e1d4876f942 (2.37-39)
152-Vulnerable-Commit: 00ae4f10b504bc4564e9f22f00907093f1ab9338 (2.38-20)
153-Fix-Commit: 8006457ab7e1cd556b919f477348a96fe88f2e49 (2.34-421)
154-Fix-Commit: 17092c0311f954e6f3c010f73ce3a78c24ac279a (2.35-272)
155-Fix-Commit: 856bac55f98dc840e7c27cfa82262b933385de90 (2.36-116)
156-Fix-Commit: 4473d1b87d04b25cdd0e0354814eeaa421328268 (2.37-42)
157-Fix-Commit: 5ee59ca371b99984232d7584fe2b1a758b4421d3 (2.38-24)
158diff --git a/advisories/GLIBC-SA-2024-0001 b/advisories/GLIBC-SA-2024-0001
159deleted file mode 100644
160index 28931c75ae..0000000000
161--- a/advisories/GLIBC-SA-2024-0001
162+++ /dev/null
163@@ -1,15 +0,0 @@
164-syslog: Heap buffer overflow in __vsyslog_internal
165-
166-__vsyslog_internal did not handle a case where printing a SYSLOG_HEADER
167-containing a long program name failed to update the required buffer
168-size, leading to the allocation and overflow of a too-small buffer on
169-the heap.
170-
171-CVE-Id: CVE-2023-6246
172-Public-Date: 2024-01-30
173-Vulnerable-Commit: 52a5be0df411ef3ff45c10c7c308cb92993d15b1 (2.37)
174-Fix-Commit: 6bd0e4efcc78f3c0115e5ea9739a1642807450da (2.39)
175-Fix-Commit: 23514c72b780f3da097ecf33a793b7ba9c2070d2 (2.38-42)
176-Fix-Commit: 97a4292aa4a2642e251472b878d0ec4c46a0e59a (2.37-57)
177-Vulnerable-Commit: b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 (2.36-16)
178-Fix-Commit: d1a83b6767f68b3cb5b4b4ea2617254acd040c82 (2.36-126)
179diff --git a/advisories/GLIBC-SA-2024-0002 b/advisories/GLIBC-SA-2024-0002
180deleted file mode 100644
181index 940bfcf2fc..0000000000
182--- a/advisories/GLIBC-SA-2024-0002
183+++ /dev/null
184@@ -1,15 +0,0 @@
185-syslog: Heap buffer overflow in __vsyslog_internal
186-
187-__vsyslog_internal used the return value of snprintf/vsnprintf to
188-calculate buffer sizes for memory allocation. If these functions (for
189-any reason) failed and returned -1, the resulting buffer would be too
190-small to hold output.
191-
192-CVE-Id: CVE-2023-6779
193-Public-Date: 2024-01-30
194-Vulnerable-Commit: 52a5be0df411ef3ff45c10c7c308cb92993d15b1 (2.37)
195-Fix-Commit: 7e5a0c286da33159d47d0122007aac016f3e02cd (2.39)
196-Fix-Commit: d0338312aace5bbfef85e03055e1212dd0e49578 (2.38-43)
197-Fix-Commit: 67062eccd9a65d7fda9976a56aeaaf6c25a80214 (2.37-58)
198-Vulnerable-Commit: b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 (2.36-16)
199-Fix-Commit: 2bc9d7c002bdac38b5c2a3f11b78e309d7765b83 (2.36-127)
200diff --git a/advisories/GLIBC-SA-2024-0003 b/advisories/GLIBC-SA-2024-0003
201deleted file mode 100644
202index b43a5150ab..0000000000
203--- a/advisories/GLIBC-SA-2024-0003
204+++ /dev/null
205@@ -1,13 +0,0 @@
206-syslog: Integer overflow in __vsyslog_internal
207-
208-__vsyslog_internal calculated a buffer size by adding two integers, but
209-did not first check if the addition would overflow.
210-
211-CVE-Id: CVE-2023-6780
212-Public-Date: 2024-01-30
213-Vulnerable-Commit: 52a5be0df411ef3ff45c10c7c308cb92993d15b1 (2.37)
214-Fix-Commit: ddf542da94caf97ff43cc2875c88749880b7259b (2.39)
215-Fix-Commit: d37c2b20a4787463d192b32041c3406c2bd91de0 (2.38-44)
216-Fix-Commit: 2b58cba076e912961ceaa5fa58588e4b10f791c0 (2.37-59)
217-Vulnerable-Commit: b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 (2.36-16)
218-Fix-Commit: b9b7d6a27aa0632f334352fa400771115b3c69b7 (2.36-128)
219diff --git a/advisories/README b/advisories/README
220deleted file mode 100644
221index 94e68b1350..0000000000
222--- a/advisories/README
223+++ /dev/null
224@@ -1,73 +0,0 @@
225-GNU C Library Security Advisory Format
226-======================================
227-
228-Security advisories in this directory follow a simple git commit log
229-format, with a heading and free-format description augmented with tags
230-to allow parsing key information. References to code changes are
231-specific to the glibc repository and follow a specific format:
232-
233- Tag-name: <commit-ref> (release-version)
234-
235-The <commit-ref> indicates a specific commit in the repository. The
236-release-version indicates the publicly consumable release in which this
237-commit is known to exist. The release-version is derived from the
238-git-describe format, (i.e. stripped out from glibc-2.34.NNN-gxxxx) and
239-is of the form 2.34-NNN. If the -NNN suffix is absent, it means that
240-the change is in that release tarball, otherwise the change is on the
241-release/2.YY/master branch and not in any released tarball.
242-
243-The following tags are currently being used:
244-
245-CVE-Id:
246-This is the CVE-Id assigned under the CVE Program
247-(https://www.cve.org/).
248-
249-Public-Date:
250-The date this issue became publicly known.
251-
252-Vulnerable-Commit:
253-The commit that introduced this vulnerability. There could be multiple
254-entries, one for each release branch in the glibc repository; the
255-release-version portion of this tag should tell you which branch this is
256-on.
257-
258-Fix-Commit:
259-The commit that fixed this vulnerability. There could be multiple
260-entries for each release branch in the glibc repository, indicating that
261-all of those commits contributed to fixing that issue in each of those
262-branches.
263-
264-Adding an Advisory
265-------------------
266-
267-An advisory for a CVE needs to be added on the master branch in two steps:
268-
269-1. Add the text of the advisory without any Fix-Commit tags along with
270- the fix for the CVE. Add the Vulnerable-Commit tag, if applicable.
271- The advisories directory does not exist in release branches, so keep
272- the advisory text commit distinct from the code changes, to ease
273- backports. Ask for the GLIBC-SA advisory number from the security
274- team.
275-
276-2. Finish all backports on release branches and then back on the msater
277- branch, add all commit refs to the advisory using the Fix-Commit
278- tags. Don't bother adding the release-version subscript since the
279- next step will overwrite it.
280-
281-3. Run the process-advisories.sh script in the scripts directory on the
282- advisory:
283-
284- scripts/process-advisories.sh update GLIBC-SA-YYYY-NNNN
285-
286- (replace YYYY-NNNN with the actual advisory number).
287-
288-4. Verify the updated advisory and push the result.
289-
290-Getting a NEWS snippet from advisories
291---------------------------------------
292-
293-Run:
294-
295- scripts/process-advisories.sh news
296-
297-and copy the content into the NEWS file.
298diff --git a/bits/wordsize.h b/bits/wordsize.h
299index 14edae3a11..53013a9275 100644
300--- a/bits/wordsize.h
301+++ b/bits/wordsize.h
302@@ -21,7 +21,9 @@
303 #define __WORDSIZE32_PTRDIFF_LONG
304
305 /* Set to 1 in order to force time types to be 32 bits instead of 64 bits in
306- struct lastlog and struct utmp{,x} on 64-bit ports. This may be done in
307+ struct lastlog and struct utmp{,x}. This may be done in
308 order to make 64-bit ports compatible with 32-bit ports. Set to 0 for
309- 64-bit ports where the time types are 64-bits or for any 32-bit ports. */
310+ 64-bit ports where the time types are 64-bits and new 32-bit ports
311+ where time_t is 64 bits, and there is no companion architecture with
312+ 32-bit time_t. */
313 #define __WORDSIZE_TIME64_COMPAT32
314diff --git a/config.h.in b/config.h.in
315index 44a34072a4..1e647de585 100644
316--- a/config.h.in
317+++ b/config.h.in
318@@ -141,6 +141,9 @@
319 /* LOONGARCH floating-point ABI for ld.so. */
320 #undef LOONGARCH_ABI_FRLEN
321
322+/* Define whether ARM used hard-float and support VFPvX-D32. */
323+#undef HAVE_ARM_PCS_VFP_D32
324+
325 /* Linux specific: minimum supported kernel version. */
326 #undef __LINUX_KERNEL_VERSION
327
328@@ -283,6 +286,9 @@
329 /* Define if x86 ISA level should be included in shared libraries. */
330 #undef INCLUDE_X86_ISA_LEVEL
331
332+/* The x86 ISA level. 1 for baseline. Undefined on non-x86. */
333+#undef MINIMUM_X86_ISA_LEVEL
334+
335 /* Define if -msahf is enabled by default on x86. */
336 #undef HAVE_X86_LAHF_SAHF
337
338diff --git a/configure b/configure
339index 59ff1e415d..432e40a592 100755
340--- a/configure
341+++ b/configure
342@@ -653,7 +653,7 @@ LIBGD
343 libc_cv_cc_loop_to_function
344 libc_cv_cc_submachine
345 libc_cv_cc_nofma
346-libc_cv_mtls_dialect_gnu2
347+libc_cv_mtls_descriptor
348 libc_cv_has_glob_dat
349 libc_cv_fpie
350 libc_cv_z_execstack
351@@ -4760,6 +4760,9 @@ libc_config_ok=no
352 # whether to use such directories.
353 with_fp_cond=1
354
355+# A preconfigure script may define another name to TLS descriptor variant
356+mtls_descriptor=gnu2
357+
358 if frags=`ls -d $srcdir/sysdeps/*/preconfigure 2> /dev/null`
359 then
360 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysdeps preconfigure fragments" >&5
361@@ -7006,9 +7009,9 @@ fi
362 printf "%s\n" "$libc_cv_has_glob_dat" >&6; }
363
364
365-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -mtls-dialect=gnu2" >&5
366-printf %s "checking for -mtls-dialect=gnu2... " >&6; }
367-if test ${libc_cv_mtls_dialect_gnu2+y}
368+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tls descriptor support" >&5
369+printf %s "checking for tls descriptor support... " >&6; }
370+if test ${libc_cv_mtls_descriptor+y}
371 then :
372 printf %s "(cached) " >&6
373 else $as_nop
374@@ -7019,25 +7022,25 @@ void foo (void)
375 i = 10;
376 }
377 EOF
378-if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fPIC -mtls-dialect=gnu2 -nostdlib -nostartfiles
379- conftest.c -o conftest 1>&5'
380+if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fPIC -mtls-dialect=$mtls_descriptor -nostdlib -nostartfiles
381+ -shared conftest.c -o conftest 1>&5'
382 { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
383 (eval $ac_try) 2>&5
384 ac_status=$?
385 printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
386 test $ac_status = 0; }; }
387 then
388- libc_cv_mtls_dialect_gnu2=yes
389+ libc_cv_mtls_descriptor=$mtls_descriptor
390 else
391- libc_cv_mtls_dialect_gnu2=no
392+ libc_cv_mtls_descriptor=no
393 fi
394 rm -f conftest*
395 fi
396-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mtls_dialect_gnu2" >&5
397-printf "%s\n" "$libc_cv_mtls_dialect_gnu2" >&6; }
398+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mtls_descriptor" >&5
399+printf "%s\n" "$libc_cv_mtls_descriptor" >&6; }
400
401 config_vars="$config_vars
402-have-mtls-dialect-gnu2 = $libc_cv_mtls_dialect_gnu2"
403+have-mtls-descriptor = $libc_cv_mtls_descriptor"
404
405 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if -Wno-ignored-attributes is required for aliases" >&5
406 printf %s "checking if -Wno-ignored-attributes is required for aliases... " >&6; }
407diff --git a/configure.ac b/configure.ac
408index 65799e5685..bdc385d03c 100644
409--- a/configure.ac
410+++ b/configure.ac
411@@ -442,6 +442,9 @@ libc_config_ok=no
412 # whether to use such directories.
413 with_fp_cond=1
414
415+# A preconfigure script may define another name to TLS descriptor variant
416+mtls_descriptor=gnu2
417+
418 dnl Let sysdeps/*/preconfigure act here.
419 LIBC_PRECONFIGURE([$srcdir], [for sysdeps])
420
421@@ -1287,7 +1290,7 @@ fi
422 rm -f conftest*])
423 AC_SUBST(libc_cv_has_glob_dat)
424
425-AC_CACHE_CHECK([for -mtls-dialect=gnu2], libc_cv_mtls_dialect_gnu2,
426+AC_CACHE_CHECK([for tls descriptor support], libc_cv_mtls_descriptor,
427 [dnl
428 cat > conftest.c <<EOF
429 __thread int i;
430@@ -1296,16 +1299,16 @@ void foo (void)
431 i = 10;
432 }
433 EOF
434-if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -fPIC -mtls-dialect=gnu2 -nostdlib -nostartfiles
435- conftest.c -o conftest 1>&AS_MESSAGE_LOG_FD])
436+if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -fPIC -mtls-dialect=$mtls_descriptor -nostdlib -nostartfiles
437+ -shared conftest.c -o conftest 1>&AS_MESSAGE_LOG_FD])
438 then
439- libc_cv_mtls_dialect_gnu2=yes
440+ libc_cv_mtls_descriptor=$mtls_descriptor
441 else
442- libc_cv_mtls_dialect_gnu2=no
443+ libc_cv_mtls_descriptor=no
444 fi
445 rm -f conftest*])
446-AC_SUBST(libc_cv_mtls_dialect_gnu2)
447-LIBC_CONFIG_VAR([have-mtls-dialect-gnu2], [$libc_cv_mtls_dialect_gnu2])
448+AC_SUBST(libc_cv_mtls_descriptor)
449+LIBC_CONFIG_VAR([have-mtls-descriptor], [$libc_cv_mtls_descriptor])
450
451 dnl clang emits an warning for a double alias redirection, to warn the
452 dnl original symbol is sed even when weak definition overrides it.
453diff --git a/elf/Makefile b/elf/Makefile
454index 5d78b659ce..a50a988e73 100644
455--- a/elf/Makefile
456+++ b/elf/Makefile
457@@ -170,6 +170,7 @@ CFLAGS-.op += $(call elide-stack-protector,.op,$(elide-routines.os))
458 CFLAGS-.os += $(call elide-stack-protector,.os,$(all-rtld-routines))
459
460 # Add the requested compiler flags to the early startup code.
461+CFLAGS-dl-misc.os += $(rtld-early-cflags)
462 CFLAGS-dl-printf.os += $(rtld-early-cflags)
463 CFLAGS-dl-setup_hash.os += $(rtld-early-cflags)
464 CFLAGS-dl-sysdep.os += $(rtld-early-cflags)
465@@ -424,6 +425,7 @@ tests += \
466 tst-glibc-hwcaps-prepend \
467 tst-global1 \
468 tst-global2 \
469+ tst-gnu2-tls2 \
470 tst-initfinilazyfail \
471 tst-initorder \
472 tst-initorder2 \
473@@ -846,6 +848,9 @@ modules-names += \
474 tst-filterobj-flt \
475 tst-finilazyfailmod \
476 tst-globalmod2 \
477+ tst-gnu2-tls2mod0 \
478+ tst-gnu2-tls2mod1 \
479+ tst-gnu2-tls2mod2 \
480 tst-initlazyfailmod \
481 tst-initorder2a \
482 tst-initorder2b \
483@@ -995,13 +1000,13 @@ modules-names-tests = $(filter-out ifuncmod% tst-tlsmod%,\
484 # For +depfiles in Makerules.
485 extra-test-objs += tst-auditmod17.os
486
487-ifeq (yes,$(have-mtls-dialect-gnu2))
488+ifneq (no,$(have-mtls-descriptor))
489 tests += tst-gnu2-tls1
490 modules-names += tst-gnu2-tls1mod
491 $(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so
492 tst-gnu2-tls1mod.so-no-z-defs = yes
493-CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2
494-endif # $(have-mtls-dialect-gnu2)
495+CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=$(have-mtls-descriptor)
496+endif # $(have-mtls-descriptor)
497
498 ifeq (yes,$(have-protected-data))
499 modules-names += tst-protected1moda tst-protected1modb
500@@ -2968,11 +2973,11 @@ $(objpfx)tst-tls-allocation-failure-static-patched.out: \
501 $(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \
502 $(objpfx)tst-audit-tlsdesc-mod2.so \
503 $(shared-thread-library)
504-ifeq (yes,$(have-mtls-dialect-gnu2))
505+ifneq (no,$(have-mtls-descriptor))
506 # The test is valid for all TLS types, but we want to exercise GNU2
507 # TLS if possible.
508-CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2
509-CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2
510+CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=$(have-mtls-descriptor)
511+CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=$(have-mtls-descriptor)
512 endif
513 $(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library)
514 $(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \
515@@ -3044,8 +3049,18 @@ $(objpfx)tst-tlsgap.out: \
516 $(objpfx)tst-tlsgap-mod0.so \
517 $(objpfx)tst-tlsgap-mod1.so \
518 $(objpfx)tst-tlsgap-mod2.so
519-ifeq (yes,$(have-mtls-dialect-gnu2))
520-CFLAGS-tst-tlsgap-mod0.c += -mtls-dialect=gnu2
521-CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=gnu2
522-CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=gnu2
523+
524+$(objpfx)tst-gnu2-tls2: $(shared-thread-library)
525+$(objpfx)tst-gnu2-tls2.out: \
526+ $(objpfx)tst-gnu2-tls2mod0.so \
527+ $(objpfx)tst-gnu2-tls2mod1.so \
528+ $(objpfx)tst-gnu2-tls2mod2.so
529+
530+ifneq (no,$(have-mtls-descriptor))
531+CFLAGS-tst-tlsgap-mod0.c += -mtls-dialect=$(have-mtls-descriptor)
532+CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=$(have-mtls-descriptor)
533+CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=$(have-mtls-descriptor)
534+CFLAGS-tst-gnu2-tls2mod0.c += -mtls-dialect=$(have-mtls-descriptor)
535+CFLAGS-tst-gnu2-tls2mod1.c += -mtls-dialect=$(have-mtls-descriptor)
536+CFLAGS-tst-gnu2-tls2mod2.c += -mtls-dialect=$(have-mtls-descriptor)
537 endif
538diff --git a/elf/dl-diagnostics.c b/elf/dl-diagnostics.c
539index 7345ebc4e5..aaf67b87e8 100644
540--- a/elf/dl-diagnostics.c
541+++ b/elf/dl-diagnostics.c
542@@ -235,6 +235,8 @@ _dl_print_diagnostics (char **environ)
543 _dl_diagnostics_print_labeled_value ("dl_hwcap", GLRO (dl_hwcap));
544 _dl_diagnostics_print_labeled_value ("dl_hwcap_important", HWCAP_IMPORTANT);
545 _dl_diagnostics_print_labeled_value ("dl_hwcap2", GLRO (dl_hwcap2));
546+ _dl_diagnostics_print_labeled_value ("dl_hwcap3", GLRO (dl_hwcap3));
547+ _dl_diagnostics_print_labeled_value ("dl_hwcap4", GLRO (dl_hwcap4));
548 _dl_diagnostics_print_labeled_string
549 ("dl_hwcaps_subdirs", _dl_hwcaps_subdirs);
550 _dl_diagnostics_print_labeled_value
551diff --git a/elf/dl-support.c b/elf/dl-support.c
552index 2f502c8b0d..451932dd03 100644
553--- a/elf/dl-support.c
554+++ b/elf/dl-support.c
555@@ -158,6 +158,8 @@ const ElfW(Phdr) *_dl_phdr;
556 size_t _dl_phnum;
557 uint64_t _dl_hwcap;
558 uint64_t _dl_hwcap2;
559+uint64_t _dl_hwcap3;
560+uint64_t _dl_hwcap4;
561
562 enum dso_sort_algorithm _dl_dso_sort_algo;
563
564diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
565index 03e1a68675..614ac9c047 100644
566--- a/elf/dl-tunables.c
567+++ b/elf/dl-tunables.c
568@@ -32,6 +32,7 @@
569 #include <ldsodefs.h>
570 #include <array_length.h>
571 #include <dl-minimal-malloc.h>
572+#include <dl-symbol-redir-ifunc.h>
573
574 #define TUNABLES_INTERNAL 1
575 #include "dl-tunables.h"
576@@ -223,6 +224,7 @@ parse_tunables_string (const char *valstring, struct tunable_toset_t *tunables)
577 {
578 tunables[ntunables++] =
579 (struct tunable_toset_t) { cur, value, p - value };
580+
581 break;
582 }
583 }
584@@ -234,23 +236,27 @@ parse_tunables_string (const char *valstring, struct tunable_toset_t *tunables)
585 static void
586 parse_tunables (const char *valstring)
587 {
588- struct tunable_toset_t tunables[tunables_list_size];
589- int ntunables = parse_tunables_string (valstring, tunables);
590- if (ntunables == -1)
591+ struct tunable_toset_t tunables[tunables_list_size] = { 0 };
592+ if (parse_tunables_string (valstring, tunables) == -1)
593 {
594 _dl_error_printf (
595 "WARNING: ld.so: invalid GLIBC_TUNABLES `%s': ignored.\n", valstring);
596 return;
597 }
598
599- for (int i = 0; i < ntunables; i++)
600- if (!tunable_initialize (tunables[i].t, tunables[i].value,
601- tunables[i].len))
602- _dl_error_printf ("WARNING: ld.so: invalid GLIBC_TUNABLES value `%.*s' "
603- "for option `%s': ignored.\n",
604- (int) tunables[i].len,
605- tunables[i].value,
606- tunables[i].t->name);
607+ for (int i = 0; i < tunables_list_size; i++)
608+ {
609+ if (tunables[i].t == NULL)
610+ continue;
611+
612+ if (!tunable_initialize (tunables[i].t, tunables[i].value,
613+ tunables[i].len))
614+ _dl_error_printf ("WARNING: ld.so: invalid GLIBC_TUNABLES value `%.*s' "
615+ "for option `%s': ignored.\n",
616+ (int) tunables[i].len,
617+ tunables[i].value,
618+ tunables[i].t->name);
619+ }
620 }
621
622 /* Initialize the tunables list from the environment. For now we only use the
623diff --git a/elf/elf.h b/elf/elf.h
624index 455731663c..1c394c64cd 100644
625--- a/elf/elf.h
626+++ b/elf/elf.h
627@@ -1234,6 +1234,10 @@ typedef struct
628 #define AT_RSEQ_FEATURE_SIZE 27 /* rseq supported feature size. */
629 #define AT_RSEQ_ALIGN 28 /* rseq allocation alignment. */
630
631+/* More machine-dependent hints about processor capabilities. */
632+#define AT_HWCAP3 29 /* extension of AT_HWCAP. */
633+#define AT_HWCAP4 30 /* extension of AT_HWCAP. */
634+
635 #define AT_EXECFN 31 /* Filename of executable. */
636
637 /* Pointer to the global system page used for system calls and other
638diff --git a/elf/tst-gnu2-tls2.c b/elf/tst-gnu2-tls2.c
639new file mode 100644
640index 0000000000..7ac04d7f33
641--- /dev/null
642+++ b/elf/tst-gnu2-tls2.c
643@@ -0,0 +1,122 @@
644+/* Test TLSDESC relocation.
645+ Copyright (C) 2024 Free Software Foundation, Inc.
646+ This file is part of the GNU C Library.
647+
648+ The GNU C Library is free software; you can redistribute it and/or
649+ modify it under the terms of the GNU Lesser General Public
650+ License as published by the Free Software Foundation; either
651+ version 2.1 of the License, or (at your option) any later version.
652+
653+ The GNU C Library is distributed in the hope that it will be useful,
654+ but WITHOUT ANY WARRANTY; without even the implied warranty of
655+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
656+ Lesser General Public License for more details.
657+
658+ You should have received a copy of the GNU Lesser General Public
659+ License along with the GNU C Library; if not, see
660+ <http://www.gnu.org/licenses/>. */
661+
662+#include <stdio.h>
663+#include <stdlib.h>
664+#include <string.h>
665+#include <dlfcn.h>
666+#include <pthread.h>
667+#include <support/xdlfcn.h>
668+#include <support/xthread.h>
669+#include <support/check.h>
670+#include <support/test-driver.h>
671+#include "tst-gnu2-tls2.h"
672+
673+#ifndef IS_SUPPORTED
674+# define IS_SUPPORTED() true
675+#endif
676+
677+/* An architecture can define it to clobber caller-saved registers in
678+ malloc below to verify that the implicit TLSDESC call won't change
679+ caller-saved registers. */
680+#ifndef PREPARE_MALLOC
681+# define PREPARE_MALLOC()
682+#endif
683+
684+extern void * __libc_malloc (size_t);
685+
686+size_t malloc_counter = 0;
687+
688+void *
689+malloc (size_t n)
690+{
691+ PREPARE_MALLOC ();
692+ malloc_counter++;
693+ return __libc_malloc (n);
694+}
695+
696+static void *mod[3];
697+#ifndef MOD
698+# define MOD(i) "tst-gnu2-tls2mod" #i ".so"
699+#endif
700+static const char *modname[3] = { MOD(0), MOD(1), MOD(2) };
701+#undef MOD
702+
703+static void
704+open_mod (int i)
705+{
706+ mod[i] = xdlopen (modname[i], RTLD_LAZY);
707+ printf ("open %s\n", modname[i]);
708+}
709+
710+static void
711+close_mod (int i)
712+{
713+ xdlclose (mod[i]);
714+ mod[i] = NULL;
715+ printf ("close %s\n", modname[i]);
716+}
717+
718+static void
719+access_mod (int i, const char *sym)
720+{
721+ struct tls var = { -1, -1, -1, -1 };
722+ struct tls *(*f) (struct tls *) = xdlsym (mod[i], sym);
723+ /* Check that our malloc is called. */
724+ malloc_counter = 0;
725+ struct tls *p = f (&var);
726+ TEST_VERIFY (malloc_counter != 0);
727+ printf ("access %s: %s() = %p\n", modname[i], sym, p);
728+ TEST_VERIFY_EXIT (memcmp (p, &var, sizeof (var)) == 0);
729+ ++(p->a);
730+}
731+
732+static void *
733+start (void *arg)
734+{
735+ /* The DTV generation is at the last dlopen of mod0 and the
736+ entry for mod1 is NULL. */
737+
738+ open_mod (1); /* Reuse modid of mod1. Uses dynamic TLS. */
739+
740+ /* Force the slow path in GNU2 TLS descriptor call. */
741+ access_mod (1, "apply_tls");
742+
743+ return arg;
744+}
745+
746+static int
747+do_test (void)
748+{
749+ if (!IS_SUPPORTED ())
750+ return EXIT_UNSUPPORTED;
751+
752+ open_mod (0);
753+ open_mod (1);
754+ open_mod (2);
755+ close_mod (0);
756+ close_mod (1); /* Create modid gap at mod1. */
757+ open_mod (0); /* Reuse modid of mod0, bump generation count. */
758+
759+ /* Create a thread where DTV of mod1 is NULL. */
760+ pthread_t t = xpthread_create (NULL, start, NULL);
761+ xpthread_join (t);
762+ return 0;
763+}
764+
765+#include <support/test-driver.c>
766diff --git a/elf/tst-gnu2-tls2.h b/elf/tst-gnu2-tls2.h
767new file mode 100644
768index 0000000000..1ade8151e2
769--- /dev/null
770+++ b/elf/tst-gnu2-tls2.h
771@@ -0,0 +1,40 @@
772+/* Test TLSDESC relocation.
773+ Copyright (C) 2024 Free Software Foundation, Inc.
774+ This file is part of the GNU C Library.
775+
776+ The GNU C Library is free software; you can redistribute it and/or
777+ modify it under the terms of the GNU Lesser General Public
778+ License as published by the Free Software Foundation; either
779+ version 2.1 of the License, or (at your option) any later version.
780+
781+ The GNU C Library is distributed in the hope that it will be useful,
782+ but WITHOUT ANY WARRANTY; without even the implied warranty of
783+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
784+ Lesser General Public License for more details.
785+
786+ You should have received a copy of the GNU Lesser General Public
787+ License along with the GNU C Library; if not, see
788+ <https://www.gnu.org/licenses/>. */
789+
790+#include <stdint.h>
791+
792+struct tls
793+{
794+ int64_t a, b, c, d;
795+};
796+
797+extern struct tls *apply_tls (struct tls *);
798+
799+/* An architecture can define them to verify that clobber caller-saved
800+ registers aren't changed by the implicit TLSDESC call. */
801+#ifndef INIT_TLSDESC_CALL
802+# define INIT_TLSDESC_CALL()
803+#endif
804+
805+#ifndef BEFORE_TLSDESC_CALL
806+# define BEFORE_TLSDESC_CALL()
807+#endif
808+
809+#ifndef AFTER_TLSDESC_CALL
810+# define AFTER_TLSDESC_CALL()
811+#endif
812diff --git a/elf/tst-gnu2-tls2mod0.c b/elf/tst-gnu2-tls2mod0.c
813new file mode 100644
814index 0000000000..3fe3c14277
815--- /dev/null
816+++ b/elf/tst-gnu2-tls2mod0.c
817@@ -0,0 +1,32 @@
818+/* DSO used by tst-gnu2-tls2.
819+ Copyright (C) 2024 Free Software Foundation, Inc.
820+ This file is part of the GNU C Library.
821+
822+ The GNU C Library is free software; you can redistribute it and/or
823+ modify it under the terms of the GNU Lesser General Public
824+ License as published by the Free Software Foundation; either
825+ version 2.1 of the License, or (at your option) any later version.
826+
827+ The GNU C Library is distributed in the hope that it will be useful,
828+ but WITHOUT ANY WARRANTY; without even the implied warranty of
829+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
830+ Lesser General Public License for more details.
831+
832+ You should have received a copy of the GNU Lesser General Public
833+ License along with the GNU C Library; if not, see
834+ <https://www.gnu.org/licenses/>. */
835+
836+#include <tst-gnu2-tls2.h>
837+
838+__thread struct tls tls_var0 __attribute__ ((visibility ("hidden")));
839+
840+struct tls *
841+apply_tls (struct tls *p)
842+{
843+ INIT_TLSDESC_CALL ();
844+ BEFORE_TLSDESC_CALL ();
845+ tls_var0 = *p;
846+ struct tls *ret = &tls_var0;
847+ AFTER_TLSDESC_CALL ();
848+ return ret;
849+}
850diff --git a/elf/tst-gnu2-tls2mod1.c b/elf/tst-gnu2-tls2mod1.c
851new file mode 100644
852index 0000000000..e210538468
853--- /dev/null
854+++ b/elf/tst-gnu2-tls2mod1.c
855@@ -0,0 +1,32 @@
856+/* DSO used by tst-gnu2-tls2.
857+ Copyright (C) 2024 Free Software Foundation, Inc.
858+ This file is part of the GNU C Library.
859+
860+ The GNU C Library is free software; you can redistribute it and/or
861+ modify it under the terms of the GNU Lesser General Public
862+ License as published by the Free Software Foundation; either
863+ version 2.1 of the License, or (at your option) any later version.
864+
865+ The GNU C Library is distributed in the hope that it will be useful,
866+ but WITHOUT ANY WARRANTY; without even the implied warranty of
867+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
868+ Lesser General Public License for more details.
869+
870+ You should have received a copy of the GNU Lesser General Public
871+ License along with the GNU C Library; if not, see
872+ <https://www.gnu.org/licenses/>. */
873+
874+#include <tst-gnu2-tls2.h>
875+
876+__thread struct tls tls_var1[100] __attribute__ ((visibility ("hidden")));
877+
878+struct tls *
879+apply_tls (struct tls *p)
880+{
881+ INIT_TLSDESC_CALL ();
882+ BEFORE_TLSDESC_CALL ();
883+ tls_var1[1] = *p;
884+ struct tls *ret = &tls_var1[1];
885+ AFTER_TLSDESC_CALL ();
886+ return ret;
887+}
888diff --git a/elf/tst-gnu2-tls2mod2.c b/elf/tst-gnu2-tls2mod2.c
889new file mode 100644
890index 0000000000..6d3031dc5f
891--- /dev/null
892+++ b/elf/tst-gnu2-tls2mod2.c
893@@ -0,0 +1,32 @@
894+/* DSO used by tst-gnu2-tls2.
895+ Copyright (C) 2024 Free Software Foundation, Inc.
896+ This file is part of the GNU C Library.
897+
898+ The GNU C Library is free software; you can redistribute it and/or
899+ modify it under the terms of the GNU Lesser General Public
900+ License as published by the Free Software Foundation; either
901+ version 2.1 of the License, or (at your option) any later version.
902+
903+ The GNU C Library is distributed in the hope that it will be useful,
904+ but WITHOUT ANY WARRANTY; without even the implied warranty of
905+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
906+ Lesser General Public License for more details.
907+
908+ You should have received a copy of the GNU Lesser General Public
909+ License along with the GNU C Library; if not, see
910+ <https://www.gnu.org/licenses/>. */
911+
912+#include <tst-gnu2-tls2.h>
913+
914+__thread struct tls tls_var2 __attribute__ ((visibility ("hidden")));
915+
916+struct tls *
917+apply_tls (struct tls *p)
918+{
919+ INIT_TLSDESC_CALL ();
920+ BEFORE_TLSDESC_CALL ();
921+ tls_var2 = *p;
922+ struct tls *ret = &tls_var2;
923+ AFTER_TLSDESC_CALL ();
924+ return ret;
925+}
926diff --git a/elf/tst-tunables.c b/elf/tst-tunables.c
927index 095b5c81d9..dff34ed748 100644
928--- a/elf/tst-tunables.c
929+++ b/elf/tst-tunables.c
930@@ -17,6 +17,10 @@
931 <https://www.gnu.org/licenses/>. */
932
933 #include <array_length.h>
934+/* The test uses the tunable_list size, which is only exported for
935+ ld.so. This will result in a copy of tunable_list, which is ununsed by
936+ the test itself. */
937+#define TUNABLES_INTERNAL 1
938 #include <dl-tunables.h>
939 #include <getopt.h>
940 #include <intprops.h>
941@@ -24,12 +28,13 @@
942 #include <stdlib.h>
943 #include <support/capture_subprocess.h>
944 #include <support/check.h>
945+#include <support/support.h>
946
947 static int restart;
948 #define CMDLINE_OPTIONS \
949 { "restart", no_argument, &restart, 1 },
950
951-static const struct test_t
952+static struct test_t
953 {
954 const char *name;
955 const char *value;
956@@ -284,6 +289,29 @@ static const struct test_t
957 0,
958 0,
959 },
960+ /* Also check for repeated tunables with a count larger than the total number
961+ of tunables. */
962+ {
963+ "GLIBC_TUNABLES",
964+ NULL,
965+ 2,
966+ 0,
967+ 0,
968+ },
969+ {
970+ "GLIBC_TUNABLES",
971+ NULL,
972+ 1,
973+ 0,
974+ 0,
975+ },
976+ {
977+ "GLIBC_TUNABLES",
978+ NULL,
979+ 0,
980+ 0,
981+ 0,
982+ },
983 };
984
985 static int
986@@ -327,6 +355,37 @@ do_test (int argc, char *argv[])
987 spargv[i] = NULL;
988 }
989
990+ /* Create a tunable line with the duplicate values with a total number
991+ larger than the different number of tunables. */
992+ {
993+ enum { tunables_list_size = array_length (tunable_list) };
994+ const char *value = "";
995+ for (int i = 0; i < tunables_list_size; i++)
996+ value = xasprintf ("%sglibc.malloc.check=2%c",
997+ value,
998+ i == (tunables_list_size - 1) ? '\0' : ':');
999+ tests[33].value = value;
1000+ }
1001+ /* Same as before, but the last tunable values is differen than the
1002+ rest. */
1003+ {
1004+ enum { tunables_list_size = array_length (tunable_list) };
1005+ const char *value = "";
1006+ for (int i = 0; i < tunables_list_size - 1; i++)
1007+ value = xasprintf ("%sglibc.malloc.check=2:", value);
1008+ value = xasprintf ("%sglibc.malloc.check=1", value);
1009+ tests[34].value = value;
1010+ }
1011+ /* Same as before, but with an invalid last entry. */
1012+ {
1013+ enum { tunables_list_size = array_length (tunable_list) };
1014+ const char *value = "";
1015+ for (int i = 0; i < tunables_list_size - 1; i++)
1016+ value = xasprintf ("%sglibc.malloc.check=2:", value);
1017+ value = xasprintf ("%sglibc.malloc.check=1=1", value);
1018+ tests[35].value = value;
1019+ }
1020+
1021 for (int i = 0; i < array_length (tests); i++)
1022 {
1023 snprintf (nteststr, sizeof nteststr, "%d", i);
1024diff --git a/iconvdata/Makefile b/iconvdata/Makefile
1025index ea019ce5c0..7196a8744b 100644
1026--- a/iconvdata/Makefile
1027+++ b/iconvdata/Makefile
1028@@ -75,7 +75,8 @@ ifeq (yes,$(build-shared))
1029 tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
1030 tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
1031 bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-big5-hkscs-to-2ucs4 \
1032- bug-iconv13 bug-iconv14 bug-iconv15
1033+ bug-iconv13 bug-iconv14 bug-iconv15 \
1034+ tst-iconv-iso-2022-cn-ext
1035 ifeq ($(have-thread-library),yes)
1036 tests += bug-iconv3
1037 endif
1038@@ -330,6 +331,8 @@ $(objpfx)bug-iconv14.out: $(addprefix $(objpfx), $(gconv-modules)) \
1039 $(addprefix $(objpfx),$(modules.so))
1040 $(objpfx)bug-iconv15.out: $(addprefix $(objpfx), $(gconv-modules)) \
1041 $(addprefix $(objpfx),$(modules.so))
1042+$(objpfx)tst-iconv-iso-2022-cn-ext.out: $(addprefix $(objpfx), $(gconv-modules)) \
1043+ $(addprefix $(objpfx),$(modules.so))
1044
1045 $(objpfx)iconv-test.out: run-iconv-test.sh \
1046 $(addprefix $(objpfx), $(gconv-modules)) \
1047diff --git a/iconvdata/iso-2022-cn-ext.c b/iconvdata/iso-2022-cn-ext.c
1048index b34c8a36f4..cce29b1969 100644
1049--- a/iconvdata/iso-2022-cn-ext.c
1050+++ b/iconvdata/iso-2022-cn-ext.c
1051@@ -574,6 +574,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
1052 { \
1053 const char *escseq; \
1054 \
1055+ if (outptr + 4 > outend) \
1056+ { \
1057+ result = __GCONV_FULL_OUTPUT; \
1058+ break; \
1059+ } \
1060+ \
1061 assert (used == CNS11643_2_set); /* XXX */ \
1062 escseq = "*H"; \
1063 *outptr++ = ESC; \
1064@@ -587,6 +593,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
1065 { \
1066 const char *escseq; \
1067 \
1068+ if (outptr + 4 > outend) \
1069+ { \
1070+ result = __GCONV_FULL_OUTPUT; \
1071+ break; \
1072+ } \
1073+ \
1074 assert ((used >> 5) >= 3 && (used >> 5) <= 7); \
1075 escseq = "+I+J+K+L+M" + ((used >> 5) - 3) * 2; \
1076 *outptr++ = ESC; \
1077diff --git a/iconvdata/tst-iconv-iso-2022-cn-ext.c b/iconvdata/tst-iconv-iso-2022-cn-ext.c
1078new file mode 100644
1079index 0000000000..96a8765fd5
1080--- /dev/null
1081+++ b/iconvdata/tst-iconv-iso-2022-cn-ext.c
1082@@ -0,0 +1,128 @@
1083+/* Verify ISO-2022-CN-EXT does not write out of the bounds.
1084+ Copyright (C) 2024 Free Software Foundation, Inc.
1085+ This file is part of the GNU C Library.
1086+
1087+ The GNU C Library is free software; you can redistribute it and/or
1088+ modify it under the terms of the GNU Lesser General Public
1089+ License as published by the Free Software Foundation; either
1090+ version 2.1 of the License, or (at your option) any later version.
1091+
1092+ The GNU C Library is distributed in the hope that it will be useful,
1093+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1094+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1095+ Lesser General Public License for more details.
1096+
1097+ You should have received a copy of the GNU Lesser General Public
1098+ License along with the GNU C Library; if not, see
1099+ <https://www.gnu.org/licenses/>. */
1100+
1101+#include <stdio.h>
1102+#include <string.h>
1103+
1104+#include <errno.h>
1105+#include <iconv.h>
1106+#include <sys/mman.h>
1107+
1108+#include <support/xunistd.h>
1109+#include <support/check.h>
1110+#include <support/support.h>
1111+
1112+/* The test sets up a two memory page buffer with the second page marked
1113+ PROT_NONE to trigger a fault if the conversion writes beyond the exact
1114+ expected amount. Then we carry out various conversions and precisely
1115+ place the start of the output buffer in order to trigger a SIGSEGV if the
1116+ process writes anywhere between 1 and page sized bytes more (only one
1117+ PROT_NONE page is setup as a canary) than expected. These tests exercise
1118+ all three of the cases in ISO-2022-CN-EXT where the converter must switch
1119+ character sets and may run out of buffer space while doing the
1120+ operation. */
1121+
1122+static int
1123+do_test (void)
1124+{
1125+ iconv_t cd = iconv_open ("ISO-2022-CN-EXT", "UTF-8");
1126+ TEST_VERIFY_EXIT (cd != (iconv_t) -1);
1127+
1128+ char *ntf;
1129+ size_t ntfsize;
1130+ char *outbufbase;
1131+ {
1132+ int pgz = getpagesize ();
1133+ TEST_VERIFY_EXIT (pgz > 0);
1134+ ntfsize = 2 * pgz;
1135+
1136+ ntf = xmmap (NULL, ntfsize, PROT_READ | PROT_WRITE, MAP_PRIVATE
1137+ | MAP_ANONYMOUS, -1);
1138+ xmprotect (ntf + pgz, pgz, PROT_NONE);
1139+
1140+ outbufbase = ntf + pgz;
1141+ }
1142+
1143+ /* Check if SOdesignation escape sequence does not trigger an OOB write. */
1144+ {
1145+ char inbuf[] = "\xe4\xba\xa4\xe6\x8d\xa2";
1146+
1147+ for (int i = 0; i < 9; i++)
1148+ {
1149+ char *inp = inbuf;
1150+ size_t inleft = sizeof (inbuf) - 1;
1151+
1152+ char *outp = outbufbase - i;
1153+ size_t outleft = i;
1154+
1155+ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
1156+ == (size_t) -1);
1157+ TEST_COMPARE (errno, E2BIG);
1158+
1159+ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
1160+ }
1161+ }
1162+
1163+ /* Same as before for SS2designation. */
1164+ {
1165+ char inbuf[] = "㴽 \xe3\xb4\xbd";
1166+
1167+ for (int i = 0; i < 14; i++)
1168+ {
1169+ char *inp = inbuf;
1170+ size_t inleft = sizeof (inbuf) - 1;
1171+
1172+ char *outp = outbufbase - i;
1173+ size_t outleft = i;
1174+
1175+ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
1176+ == (size_t) -1);
1177+ TEST_COMPARE (errno, E2BIG);
1178+
1179+ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
1180+ }
1181+ }
1182+
1183+ /* Same as before for SS3designation. */
1184+ {
1185+ char inbuf[] = "劄 \xe5\x8a\x84";
1186+
1187+ for (int i = 0; i < 14; i++)
1188+ {
1189+ char *inp = inbuf;
1190+ size_t inleft = sizeof (inbuf) - 1;
1191+
1192+ char *outp = outbufbase - i;
1193+ size_t outleft = i;
1194+
1195+ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
1196+ == (size_t) -1);
1197+ TEST_COMPARE (errno, E2BIG);
1198+
1199+ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
1200+ }
1201+ }
1202+
1203+ TEST_VERIFY_EXIT (iconv_close (cd) != -1);
1204+
1205+ xmunmap (ntf, ntfsize);
1206+
1207+ return 0;
1208+}
1209+
1210+#include <support/test-driver.c>
1211diff --git a/login/Makefile b/login/Makefile
1212index 1e22008a61..f91190e3dc 100644
1213--- a/login/Makefile
1214+++ b/login/Makefile
1215@@ -44,7 +44,9 @@ subdir-dirs = programs
1216 vpath %.c programs
1217
1218 tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \
1219- tst-pututxline-lockfail tst-pututxline-cache
1220+ tst-pututxline-lockfail tst-pututxline-cache tst-utmp-size tst-utmp-size-64
1221+
1222+CFLAGS-tst-utmp-size-64.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
1223
1224 # Empty compatibility library for old binaries.
1225 extra-libs := libutil
1226diff --git a/login/tst-utmp-size-64.c b/login/tst-utmp-size-64.c
1227new file mode 100644
1228index 0000000000..7a581a4c12
1229--- /dev/null
1230+++ b/login/tst-utmp-size-64.c
1231@@ -0,0 +1,2 @@
1232+/* The on-disk layout must not change in time64 mode. */
1233+#include "tst-utmp-size.c"
1234diff --git a/login/tst-utmp-size.c b/login/tst-utmp-size.c
1235new file mode 100644
1236index 0000000000..1b7f7ff042
1237--- /dev/null
1238+++ b/login/tst-utmp-size.c
1239@@ -0,0 +1,33 @@
1240+/* Check expected sizes of struct utmp, struct utmpx, struct lastlog.
1241+ Copyright (C) 2024 Free Software Foundation, Inc.
1242+ This file is part of the GNU C Library.
1243+
1244+ The GNU C Library is free software; you can redistribute it and/or
1245+ modify it under the terms of the GNU Lesser General Public
1246+ License as published by the Free Software Foundation; either
1247+ version 2.1 of the License, or (at your option) any later version.
1248+
1249+ The GNU C Library is distributed in the hope that it will be useful,
1250+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1251+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1252+ Lesser General Public License for more details.
1253+
1254+ You should have received a copy of the GNU Lesser General Public
1255+ License along with the GNU C Library; if not, see
1256+ <https://www.gnu.org/licenses/>. */
1257+
1258+#include <utmp.h>
1259+#include <utmpx.h>
1260+#include <utmp-size.h>
1261+
1262+static int
1263+do_test (void)
1264+{
1265+ _Static_assert (sizeof (struct utmp) == UTMP_SIZE, "struct utmp size");
1266+ _Static_assert (sizeof (struct utmpx) == UTMP_SIZE, "struct utmpx size");
1267+ _Static_assert (sizeof (struct lastlog) == LASTLOG_SIZE,
1268+ "struct lastlog size");
1269+ return 0;
1270+}
1271+
1272+#include <support/test-driver.c>
1273diff --git a/manual/stdbit.texi b/manual/stdbit.texi
1274index fe41c671d8..6c75ed9a20 100644
1275--- a/manual/stdbit.texi
1276+++ b/manual/stdbit.texi
1277@@ -32,7 +32,13 @@ and @code{unsigned long long int}. In addition, there is a
1278 corresponding type-generic macro (not listed below), named the same as
1279 the functions but without any suffix such as @samp{_uc}. The
1280 type-generic macro can only be used with an argument of an unsigned
1281-integer type with a width of 8, 16, 32 or 64 bits.
1282+integer type with a width of 8, 16, 32 or 64 bits, or when using
1283+a compiler with support for
1284+@uref{https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html,@code{__builtin_stdc_bit_ceil}},
1285+etc.@:, built-in functions such as GCC 14.1 or later
1286+any unsigned integer type those built-in functions support.
1287+In GCC 14.1 that includes support for @code{unsigned __int128} and
1288+@code{unsigned _BitInt(@var{n})} if supported by the target.
1289
1290 @deftypefun {unsigned int} stdc_leading_zeros_uc (unsigned char @var{x})
1291 @deftypefunx {unsigned int} stdc_leading_zeros_us (unsigned short @var{x})
1292diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
1293index 0c6e46f15c..01d554af9c 100644
1294--- a/nscd/netgroupcache.c
1295+++ b/nscd/netgroupcache.c
1296@@ -23,6 +23,7 @@
1297 #include <stdlib.h>
1298 #include <unistd.h>
1299 #include <sys/mman.h>
1300+#include <scratch_buffer.h>
1301
1302 #include "../nss/netgroup.h"
1303 #include "nscd.h"
1304@@ -65,6 +66,16 @@ struct dataset
1305 char strdata[0];
1306 };
1307
1308+/* Send a notfound response to FD. Always returns -1 to indicate an
1309+ ephemeral error. */
1310+static time_t
1311+send_notfound (int fd)
1312+{
1313+ if (fd != -1)
1314+ TEMP_FAILURE_RETRY (send (fd, &notfound, sizeof (notfound), MSG_NOSIGNAL));
1315+ return -1;
1316+}
1317+
1318 /* Sends a notfound message and prepares a notfound dataset to write to the
1319 cache. Returns true if there was enough memory to allocate the dataset and
1320 returns the dataset in DATASETP, total bytes to write in TOTALP and the
1321@@ -83,8 +94,7 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
1322 total = sizeof (notfound);
1323 timeout = time (NULL) + db->negtimeout;
1324
1325- if (fd != -1)
1326- TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));
1327+ send_notfound (fd);
1328
1329 dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1);
1330 /* If we cannot permanently store the result, so be it. */
1331@@ -109,11 +119,78 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
1332 return cacheable;
1333 }
1334
1335+struct addgetnetgrentX_scratch
1336+{
1337+ /* This is the result that the caller should use. It can be NULL,
1338+ point into buffer, or it can be in the cache. */
1339+ struct dataset *dataset;
1340+
1341+ struct scratch_buffer buffer;
1342+
1343+ /* Used internally in addgetnetgrentX as a staging area. */
1344+ struct scratch_buffer tmp;
1345+
1346+ /* Number of bytes in buffer that are actually used. */
1347+ size_t buffer_used;
1348+};
1349+
1350+static void
1351+addgetnetgrentX_scratch_init (struct addgetnetgrentX_scratch *scratch)
1352+{
1353+ scratch->dataset = NULL;
1354+ scratch_buffer_init (&scratch->buffer);
1355+ scratch_buffer_init (&scratch->tmp);
1356+
1357+ /* Reserve space for the header. */
1358+ scratch->buffer_used = sizeof (struct dataset);
1359+ static_assert (sizeof (struct dataset) < sizeof (scratch->tmp.__space),
1360+ "initial buffer space");
1361+ memset (scratch->tmp.data, 0, sizeof (struct dataset));
1362+}
1363+
1364+static void
1365+addgetnetgrentX_scratch_free (struct addgetnetgrentX_scratch *scratch)
1366+{
1367+ scratch_buffer_free (&scratch->buffer);
1368+ scratch_buffer_free (&scratch->tmp);
1369+}
1370+
1371+/* Copy LENGTH bytes from S into SCRATCH. Returns NULL if SCRATCH
1372+ could not be resized, otherwise a pointer to the copy. */
1373+static char *
1374+addgetnetgrentX_append_n (struct addgetnetgrentX_scratch *scratch,
1375+ const char *s, size_t length)
1376+{
1377+ while (true)
1378+ {
1379+ size_t remaining = scratch->buffer.length - scratch->buffer_used;
1380+ if (remaining >= length)
1381+ break;
1382+ if (!scratch_buffer_grow_preserve (&scratch->buffer))
1383+ return NULL;
1384+ }
1385+ char *copy = scratch->buffer.data + scratch->buffer_used;
1386+ memcpy (copy, s, length);
1387+ scratch->buffer_used += length;
1388+ return copy;
1389+}
1390+
1391+/* Copy S into SCRATCH, including its null terminator. Returns false
1392+ if SCRATCH could not be resized. */
1393+static bool
1394+addgetnetgrentX_append (struct addgetnetgrentX_scratch *scratch, const char *s)
1395+{
1396+ if (s == NULL)
1397+ s = "";
1398+ return addgetnetgrentX_append_n (scratch, s, strlen (s) + 1) != NULL;
1399+}
1400+
1401+/* Caller must initialize and free *SCRATCH. If the return value is
1402+ negative, this function has sent a notfound response. */
1403 static time_t
1404 addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
1405 const char *key, uid_t uid, struct hashentry *he,
1406- struct datahead *dh, struct dataset **resultp,
1407- void **tofreep)
1408+ struct datahead *dh, struct addgetnetgrentX_scratch *scratch)
1409 {
1410 if (__glibc_unlikely (debug_level > 0))
1411 {
1412@@ -132,14 +209,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
1413
1414 char *key_copy = NULL;
1415 struct __netgrent data;
1416- size_t buflen = MAX (1024, sizeof (*dataset) + req->key_len);
1417- size_t buffilled = sizeof (*dataset);
1418- char *buffer = NULL;
1419 size_t nentries = 0;
1420 size_t group_len = strlen (key) + 1;
1421 struct name_list *first_needed
1422 = alloca (sizeof (struct name_list) + group_len);
1423- *tofreep = NULL;
1424
1425 if (netgroup_database == NULL
1426 && !__nss_database_get (nss_database_netgroup, &netgroup_database))
1427@@ -147,12 +220,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
1428 /* No such service. */
1429 cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
1430 &key_copy);
1431- goto writeout;
1432+ goto maybe_cache_add;
1433 }
1434
1435 memset (&data, '\0', sizeof (data));
1436- buffer = xmalloc (buflen);
1437- *tofreep = buffer;
1438 first_needed->next = first_needed;
1439 memcpy (first_needed->name, key, group_len);
1440 data.needed_groups = first_needed;
1441@@ -195,8 +266,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
1442 while (1)
1443 {
1444 int e;
1445- status = getfct.f (&data, buffer + buffilled,
1446- buflen - buffilled - req->key_len, &e);
1447+ status = getfct.f (&data, scratch->tmp.data,
1448+ scratch->tmp.length, &e);
1449 if (status == NSS_STATUS_SUCCESS)
1450 {
1451 if (data.type == triple_val)
1452@@ -204,68 +275,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
1453 const char *nhost = data.val.triple.host;
1454 const char *nuser = data.val.triple.user;
1455 const char *ndomain = data.val.triple.domain;
1456-
1457- size_t hostlen = strlen (nhost ?: "") + 1;
1458- size_t userlen = strlen (nuser ?: "") + 1;
1459- size_t domainlen = strlen (ndomain ?: "") + 1;
1460-
1461- if (nhost == NULL || nuser == NULL || ndomain == NULL
1462- || nhost > nuser || nuser > ndomain)
1463- {
1464- const char *last = nhost;
1465- if (last == NULL
1466- || (nuser != NULL && nuser > last))
1467- last = nuser;
1468- if (last == NULL
1469- || (ndomain != NULL && ndomain > last))
1470- last = ndomain;
1471-
1472- size_t bufused
1473- = (last == NULL
1474- ? buffilled
1475- : last + strlen (last) + 1 - buffer);
1476-
1477- /* We have to make temporary copies. */
1478- size_t needed = hostlen + userlen + domainlen;
1479-
1480- if (buflen - req->key_len - bufused < needed)
1481- {
1482- buflen += MAX (buflen, 2 * needed);
1483- /* Save offset in the old buffer. We don't
1484- bother with the NULL check here since
1485- we'll do that later anyway. */
1486- size_t nhostdiff = nhost - buffer;
1487- size_t nuserdiff = nuser - buffer;
1488- size_t ndomaindiff = ndomain - buffer;
1489-
1490- char *newbuf = xrealloc (buffer, buflen);
1491- /* Fix up the triplet pointers into the new
1492- buffer. */
1493- nhost = (nhost ? newbuf + nhostdiff
1494- : NULL);
1495- nuser = (nuser ? newbuf + nuserdiff
1496- : NULL);
1497- ndomain = (ndomain ? newbuf + ndomaindiff
1498- : NULL);
1499- *tofreep = buffer = newbuf;
1500- }
1501-
1502- nhost = memcpy (buffer + bufused,
1503- nhost ?: "", hostlen);
1504- nuser = memcpy ((char *) nhost + hostlen,
1505- nuser ?: "", userlen);
1506- ndomain = memcpy ((char *) nuser + userlen,
1507- ndomain ?: "", domainlen);
1508- }
1509-
1510- char *wp = buffer + buffilled;
1511- wp = memmove (wp, nhost ?: "", hostlen);
1512- wp += hostlen;
1513- wp = memmove (wp, nuser ?: "", userlen);
1514- wp += userlen;
1515- wp = memmove (wp, ndomain ?: "", domainlen);
1516- wp += domainlen;
1517- buffilled = wp - buffer;
1518+ if (!(addgetnetgrentX_append (scratch, nhost)
1519+ && addgetnetgrentX_append (scratch, nuser)
1520+ && addgetnetgrentX_append (scratch, ndomain)))
1521+ return send_notfound (fd);
1522 ++nentries;
1523 }
1524 else
1525@@ -317,8 +330,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
1526 }
1527 else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
1528 {
1529- buflen *= 2;
1530- *tofreep = buffer = xrealloc (buffer, buflen);
1531+ if (!scratch_buffer_grow (&scratch->tmp))
1532+ return send_notfound (fd);
1533 }
1534 else if (status == NSS_STATUS_RETURN
1535 || status == NSS_STATUS_NOTFOUND
1536@@ -348,13 +361,20 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
1537 {
1538 cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
1539 &key_copy);
1540- goto writeout;
1541+ goto maybe_cache_add;
1542 }
1543
1544- total = buffilled;
1545+ /* Capture the result size without the key appended. */
1546+ total = scratch->buffer_used;
1547+
1548+ /* Make a copy of the key. The scratch buffer must not move after
1549+ this point. */
1550+ key_copy = addgetnetgrentX_append_n (scratch, key, req->key_len);
1551+ if (key_copy == NULL)
1552+ return send_notfound (fd);
1553
1554 /* Fill in the dataset. */
1555- dataset = (struct dataset *) buffer;
1556+ dataset = scratch->buffer.data;
1557 timeout = datahead_init_pos (&dataset->head, total + req->key_len,
1558 total - offsetof (struct dataset, resp),
1559 he == NULL ? 0 : dh->nreloads + 1,
1560@@ -363,11 +383,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
1561 dataset->resp.version = NSCD_VERSION;
1562 dataset->resp.found = 1;
1563 dataset->resp.nresults = nentries;
1564- dataset->resp.result_len = buffilled - sizeof (*dataset);
1565-
1566- assert (buflen - buffilled >= req->key_len);
1567- key_copy = memcpy (buffer + buffilled, key, req->key_len);
1568- buffilled += req->key_len;
1569+ dataset->resp.result_len = total - sizeof (*dataset);
1570
1571 /* Now we can determine whether on refill we have to create a new
1572 record or not. */
1573@@ -398,7 +414,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
1574 if (__glibc_likely (newp != NULL))
1575 {
1576 /* Adjust pointer into the memory block. */
1577- key_copy = (char *) newp + (key_copy - buffer);
1578+ key_copy = (char *) newp + (key_copy - (char *) dataset);
1579
1580 dataset = memcpy (newp, dataset, total + req->key_len);
1581 cacheable = true;
1582@@ -410,14 +426,12 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
1583 }
1584
1585 if (he == NULL && fd != -1)
1586- {
1587- /* We write the dataset before inserting it to the database
1588- since while inserting this thread might block and so would
1589- unnecessarily let the receiver wait. */
1590- writeout:
1591+ /* We write the dataset before inserting it to the database since
1592+ while inserting this thread might block and so would
1593+ unnecessarily let the receiver wait. */
1594 writeall (fd, &dataset->resp, dataset->head.recsize);
1595- }
1596
1597+ maybe_cache_add:
1598 if (cacheable)
1599 {
1600 /* If necessary, we also propagate the data to disk. */
1601@@ -441,7 +455,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
1602 }
1603
1604 out:
1605- *resultp = dataset;
1606+ scratch->dataset = dataset;
1607
1608 return timeout;
1609 }
1610@@ -462,6 +476,9 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
1611 if (user != NULL)
1612 key = strchr (key, '\0') + 1;
1613 const char *domain = *key++ ? key : NULL;
1614+ struct addgetnetgrentX_scratch scratch;
1615+
1616+ addgetnetgrentX_scratch_init (&scratch);
1617
1618 if (__glibc_unlikely (debug_level > 0))
1619 {
1620@@ -477,12 +494,8 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
1621 group, group_len,
1622 db, uid);
1623 time_t timeout;
1624- void *tofree;
1625 if (result != NULL)
1626- {
1627- timeout = result->head.timeout;
1628- tofree = NULL;
1629- }
1630+ timeout = result->head.timeout;
1631 else
1632 {
1633 request_header req_get =
1634@@ -491,7 +504,10 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
1635 .key_len = group_len
1636 };
1637 timeout = addgetnetgrentX (db, -1, &req_get, group, uid, NULL, NULL,
1638- &result, &tofree);
1639+ &scratch);
1640+ result = scratch.dataset;
1641+ if (timeout < 0)
1642+ goto out;
1643 }
1644
1645 struct indataset
1646@@ -502,24 +518,26 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
1647 = (struct indataset *) mempool_alloc (db,
1648 sizeof (*dataset) + req->key_len,
1649 1);
1650- struct indataset dataset_mem;
1651 bool cacheable = true;
1652 if (__glibc_unlikely (dataset == NULL))
1653 {
1654 cacheable = false;
1655- dataset = &dataset_mem;
1656+ /* The alloca is safe because nscd_run_worker verfies that
1657+ key_len is not larger than MAXKEYLEN. */
1658+ dataset = alloca (sizeof (*dataset) + req->key_len);
1659 }
1660
1661 datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len,
1662 sizeof (innetgroup_response_header),
1663- he == NULL ? 0 : dh->nreloads + 1, result->head.ttl);
1664+ he == NULL ? 0 : dh->nreloads + 1,
1665+ result == NULL ? db->negtimeout : result->head.ttl);
1666 /* Set the notfound status and timeout based on the result from
1667 getnetgrent. */
1668- dataset->head.notfound = result->head.notfound;
1669+ dataset->head.notfound = result == NULL || result->head.notfound;
1670 dataset->head.timeout = timeout;
1671
1672 dataset->resp.version = NSCD_VERSION;
1673- dataset->resp.found = result->resp.found;
1674+ dataset->resp.found = result != NULL && result->resp.found;
1675 /* Until we find a matching entry the result is 0. */
1676 dataset->resp.result = 0;
1677
1678@@ -567,7 +585,9 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
1679 goto out;
1680 }
1681
1682- if (he == NULL)
1683+ /* addgetnetgrentX may have already sent a notfound response. Do
1684+ not send another one. */
1685+ if (he == NULL && dataset->resp.found)
1686 {
1687 /* We write the dataset before inserting it to the database
1688 since while inserting this thread might block and so would
1689@@ -601,7 +621,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
1690 }
1691
1692 out:
1693- free (tofree);
1694+ addgetnetgrentX_scratch_free (&scratch);
1695 return timeout;
1696 }
1697
1698@@ -611,11 +631,12 @@ addgetnetgrentX_ignore (struct database_dyn *db, int fd, request_header *req,
1699 const char *key, uid_t uid, struct hashentry *he,
1700 struct datahead *dh)
1701 {
1702- struct dataset *ignore;
1703- void *tofree;
1704- time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh,
1705- &ignore, &tofree);
1706- free (tofree);
1707+ struct addgetnetgrentX_scratch scratch;
1708+ addgetnetgrentX_scratch_init (&scratch);
1709+ time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh, &scratch);
1710+ addgetnetgrentX_scratch_free (&scratch);
1711+ if (timeout < 0)
1712+ timeout = 0;
1713 return timeout;
1714 }
1715
1716@@ -659,5 +680,9 @@ readdinnetgr (struct database_dyn *db, struct hashentry *he,
1717 .key_len = he->len
1718 };
1719
1720- return addinnetgrX (db, -1, &req, db->data + he->key, he->owner, he, dh);
1721+ time_t timeout = addinnetgrX (db, -1, &req, db->data + he->key, he->owner,
1722+ he, dh);
1723+ if (timeout < 0)
1724+ timeout = 0;
1725+ return timeout;
1726 }
1727diff --git a/socket/Makefile b/socket/Makefile
1728index 74ca5b8452..fc1bd0a260 100644
1729--- a/socket/Makefile
1730+++ b/socket/Makefile
1731@@ -70,6 +70,7 @@ tests := \
1732 tst-accept4 \
1733 tst-cmsg_cloexec \
1734 tst-cmsghdr \
1735+ tst-connect \
1736 tst-sockopt \
1737 # tests
1738
1739diff --git a/socket/tst-connect.c b/socket/tst-connect.c
1740new file mode 100644
1741index 0000000000..ec2fdd92c0
1742--- /dev/null
1743+++ b/socket/tst-connect.c
1744@@ -0,0 +1,113 @@
1745+/* Test the connect function.
1746+ Copyright (C) 2024 Free Software Foundation, Inc.
1747+ This file is part of the GNU C Library.
1748+
1749+ The GNU C Library is free software; you can redistribute it and/or
1750+ modify it under the terms of the GNU Lesser General Public
1751+ License as published by the Free Software Foundation; either
1752+ version 2.1 of the License, or (at your option) any later version.
1753+
1754+ The GNU C Library is distributed in the hope that it will be useful,
1755+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1756+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1757+ Lesser General Public License for more details.
1758+
1759+ You should have received a copy of the GNU Lesser General Public
1760+ License along with the GNU C Library; if not, see
1761+ <https://www.gnu.org/licenses/>. */
1762+
1763+#include <arpa/inet.h>
1764+#include <errno.h>
1765+#include <fcntl.h>
1766+#include <signal.h>
1767+#include <stdbool.h>
1768+#include <support/check.h>
1769+#include <support/xsocket.h>
1770+#include <support/xunistd.h>
1771+#include <sys/socket.h>
1772+#include <stdio.h>
1773+
1774+static struct sockaddr_in server_address;
1775+
1776+int
1777+open_socket_inet_tcp (void)
1778+{
1779+ int fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
1780+ if (fd < 0)
1781+ {
1782+ if (errno == EAFNOSUPPORT)
1783+ FAIL_UNSUPPORTED ("The host does not support IPv4");
1784+ else
1785+ FAIL_EXIT1 ("socket (AF_INET, SOCK_STREAM, IPPROTO_TCP): %m\n");
1786+ }
1787+ return fd;
1788+}
1789+
1790+static pid_t
1791+start_server (void)
1792+{
1793+ server_address.sin_family = AF_INET;
1794+ server_address.sin_port = 0;
1795+ server_address.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1796+
1797+ int server_sock = open_socket_inet_tcp ();
1798+
1799+ xbind (server_sock, (struct sockaddr *) &server_address,
1800+ sizeof (server_address));
1801+
1802+ socklen_t sa_len = sizeof (server_address);
1803+ xgetsockname (server_sock, (struct sockaddr *) &server_address, &sa_len);
1804+ xlisten (server_sock, 5);
1805+
1806+ pid_t my_pid = xfork ();
1807+ if (my_pid > 0)
1808+ {
1809+ xclose (server_sock);
1810+ return my_pid;
1811+ }
1812+
1813+ struct sockaddr_in client_address;
1814+ socklen_t ca_len = sizeof (server_address);
1815+ int client_sock = xaccept (server_sock, (struct sockaddr *) &client_address,
1816+ &ca_len);
1817+ printf ("socket accepted %d\n", client_sock);
1818+
1819+ _exit (0);
1820+}
1821+
1822+static int
1823+do_test (void)
1824+{
1825+ pid_t serv_pid;
1826+ struct sockaddr_in peer;
1827+ socklen_t peer_len;
1828+
1829+ serv_pid = start_server ();
1830+ int client_sock = open_socket_inet_tcp ();
1831+ xconnect (client_sock, (const struct sockaddr *) &server_address,
1832+ sizeof (server_address));
1833+
1834+ /* A second connect with same arguments should fail with EISCONN. */
1835+ int result = connect (client_sock,
1836+ (const struct sockaddr *) &server_address,
1837+ sizeof (server_address));
1838+ if (result == 0 || errno != EISCONN)
1839+ FAIL_EXIT1 ("Second connect (%d), should fail with EISCONN: %m",
1840+ client_sock);
1841+
1842+ peer_len = sizeof (peer);
1843+ xgetpeername (client_sock, (struct sockaddr *) &peer, &peer_len);
1844+ TEST_COMPARE (peer_len, sizeof (peer));
1845+ TEST_COMPARE (peer.sin_port, server_address.sin_port);
1846+ TEST_COMPARE_BLOB (&peer.sin_addr, sizeof (peer.sin_addr),
1847+ &server_address.sin_addr,
1848+ sizeof (server_address.sin_addr));
1849+
1850+ int status;
1851+ xwaitpid (serv_pid, &status, 0);
1852+ TEST_COMPARE (status, 0);
1853+
1854+ return 0;
1855+}
1856+
1857+#include <support/test-driver.c>
1858diff --git a/stdlib/Makefile b/stdlib/Makefile
1859index d587f054d1..9898cc5d8a 100644
1860--- a/stdlib/Makefile
1861+++ b/stdlib/Makefile
1862@@ -308,6 +308,7 @@ tests := \
1863 tst-setcontext10 \
1864 tst-setcontext11 \
1865 tst-stdbit-Wconversion \
1866+ tst-stdbit-builtins \
1867 tst-stdc_bit_ceil \
1868 tst-stdc_bit_floor \
1869 tst-stdc_bit_width \
1870diff --git a/stdlib/stdbit.h b/stdlib/stdbit.h
1871index f334eb174d..2801590c63 100644
1872--- a/stdlib/stdbit.h
1873+++ b/stdlib/stdbit.h
1874@@ -64,9 +64,13 @@ extern unsigned int stdc_leading_zeros_ul (unsigned long int __x)
1875 __extension__
1876 extern unsigned int stdc_leading_zeros_ull (unsigned long long int __x)
1877 __THROW __attribute_const__;
1878-#define stdc_leading_zeros(x) \
1879+#if __glibc_has_builtin (__builtin_stdc_leading_zeros)
1880+# define stdc_leading_zeros(x) (__builtin_stdc_leading_zeros (x))
1881+#else
1882+# define stdc_leading_zeros(x) \
1883 (stdc_leading_zeros_ull (x) \
1884 - (unsigned int) (8 * (sizeof (0ULL) - sizeof (x))))
1885+#endif
1886
1887 #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll)
1888 static __always_inline unsigned int
1889@@ -116,9 +120,13 @@ extern unsigned int stdc_leading_ones_ul (unsigned long int __x)
1890 __extension__
1891 extern unsigned int stdc_leading_ones_ull (unsigned long long int __x)
1892 __THROW __attribute_const__;
1893-#define stdc_leading_ones(x) \
1894+#if __glibc_has_builtin (__builtin_stdc_leading_ones)
1895+# define stdc_leading_ones(x) (__builtin_stdc_leading_ones (x))
1896+#else
1897+# define stdc_leading_ones(x) \
1898 (stdc_leading_ones_ull ((unsigned long long int) (x) \
1899 << 8 * (sizeof (0ULL) - sizeof (x))))
1900+#endif
1901
1902 #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll)
1903 static __always_inline unsigned int
1904@@ -168,11 +176,15 @@ extern unsigned int stdc_trailing_zeros_ul (unsigned long int __x)
1905 __extension__
1906 extern unsigned int stdc_trailing_zeros_ull (unsigned long long int __x)
1907 __THROW __attribute_const__;
1908-#define stdc_trailing_zeros(x) \
1909+#if __glibc_has_builtin (__builtin_stdc_trailing_zeros)
1910+# define stdc_trailing_zeros(x) (__builtin_stdc_trailing_zeros (x))
1911+#else
1912+# define stdc_trailing_zeros(x) \
1913 (sizeof (x) == 8 ? stdc_trailing_zeros_ull (x) \
1914 : sizeof (x) == 4 ? stdc_trailing_zeros_ui (x) \
1915 : sizeof (x) == 2 ? stdc_trailing_zeros_us (__pacify_uint16 (x)) \
1916 : stdc_trailing_zeros_uc (__pacify_uint8 (x)))
1917+#endif
1918
1919 #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_ctzll)
1920 static __always_inline unsigned int
1921@@ -222,7 +234,11 @@ extern unsigned int stdc_trailing_ones_ul (unsigned long int __x)
1922 __extension__
1923 extern unsigned int stdc_trailing_ones_ull (unsigned long long int __x)
1924 __THROW __attribute_const__;
1925-#define stdc_trailing_ones(x) (stdc_trailing_ones_ull (x))
1926+#if __glibc_has_builtin (__builtin_stdc_trailing_ones)
1927+# define stdc_trailing_ones(x) (__builtin_stdc_trailing_ones (x))
1928+#else
1929+# define stdc_trailing_ones(x) (stdc_trailing_ones_ull (x))
1930+#endif
1931
1932 #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_ctzll)
1933 static __always_inline unsigned int
1934@@ -272,11 +288,15 @@ extern unsigned int stdc_first_leading_zero_ul (unsigned long int __x)
1935 __extension__
1936 extern unsigned int stdc_first_leading_zero_ull (unsigned long long int __x)
1937 __THROW __attribute_const__;
1938-#define stdc_first_leading_zero(x) \
1939+#if __glibc_has_builtin (__builtin_stdc_first_leading_zero)
1940+# define stdc_first_leading_zero(x) (__builtin_stdc_first_leading_zero (x))
1941+#else
1942+# define stdc_first_leading_zero(x) \
1943 (sizeof (x) == 8 ? stdc_first_leading_zero_ull (x) \
1944 : sizeof (x) == 4 ? stdc_first_leading_zero_ui (x) \
1945 : sizeof (x) == 2 ? stdc_first_leading_zero_us (__pacify_uint16 (x)) \
1946 : stdc_first_leading_zero_uc (__pacify_uint8 (x)))
1947+#endif
1948
1949 #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll)
1950 static __always_inline unsigned int
1951@@ -326,11 +346,15 @@ extern unsigned int stdc_first_leading_one_ul (unsigned long int __x)
1952 __extension__
1953 extern unsigned int stdc_first_leading_one_ull (unsigned long long int __x)
1954 __THROW __attribute_const__;
1955-#define stdc_first_leading_one(x) \
1956+#if __glibc_has_builtin (__builtin_stdc_first_leading_one)
1957+# define stdc_first_leading_one(x) (__builtin_stdc_first_leading_one (x))
1958+#else
1959+# define stdc_first_leading_one(x) \
1960 (sizeof (x) == 8 ? stdc_first_leading_one_ull (x) \
1961 : sizeof (x) == 4 ? stdc_first_leading_one_ui (x) \
1962 : sizeof (x) == 2 ? stdc_first_leading_one_us (__pacify_uint16 (x)) \
1963 : stdc_first_leading_one_uc (__pacify_uint8 (x)))
1964+#endif
1965
1966 #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll)
1967 static __always_inline unsigned int
1968@@ -380,11 +404,15 @@ extern unsigned int stdc_first_trailing_zero_ul (unsigned long int __x)
1969 __extension__
1970 extern unsigned int stdc_first_trailing_zero_ull (unsigned long long int __x)
1971 __THROW __attribute_const__;
1972-#define stdc_first_trailing_zero(x) \
1973+#if __glibc_has_builtin (__builtin_stdc_first_trailing_zero)
1974+# define stdc_first_trailing_zero(x) (__builtin_stdc_first_trailing_zero (x))
1975+#else
1976+# define stdc_first_trailing_zero(x) \
1977 (sizeof (x) == 8 ? stdc_first_trailing_zero_ull (x) \
1978 : sizeof (x) == 4 ? stdc_first_trailing_zero_ui (x) \
1979 : sizeof (x) == 2 ? stdc_first_trailing_zero_us (__pacify_uint16 (x)) \
1980 : stdc_first_trailing_zero_uc (__pacify_uint8 (x)))
1981+#endif
1982
1983 #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_ctzll)
1984 static __always_inline unsigned int
1985@@ -434,11 +462,15 @@ extern unsigned int stdc_first_trailing_one_ul (unsigned long int __x)
1986 __extension__
1987 extern unsigned int stdc_first_trailing_one_ull (unsigned long long int __x)
1988 __THROW __attribute_const__;
1989-#define stdc_first_trailing_one(x) \
1990+#if __glibc_has_builtin (__builtin_stdc_first_trailing_one)
1991+# define stdc_first_trailing_one(x) (__builtin_stdc_first_trailing_one (x))
1992+#else
1993+# define stdc_first_trailing_one(x) \
1994 (sizeof (x) == 8 ? stdc_first_trailing_one_ull (x) \
1995 : sizeof (x) == 4 ? stdc_first_trailing_one_ui (x) \
1996 : sizeof (x) == 2 ? stdc_first_trailing_one_us (__pacify_uint16 (x)) \
1997 : stdc_first_trailing_one_uc (__pacify_uint8 (x)))
1998+#endif
1999
2000 #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_ctzll)
2001 static __always_inline unsigned int
2002@@ -488,9 +520,13 @@ extern unsigned int stdc_count_zeros_ul (unsigned long int __x)
2003 __extension__
2004 extern unsigned int stdc_count_zeros_ull (unsigned long long int __x)
2005 __THROW __attribute_const__;
2006-#define stdc_count_zeros(x) \
2007+#if __glibc_has_builtin (__builtin_stdc_count_zeros)
2008+# define stdc_count_zeros(x) (__builtin_stdc_count_zeros (x))
2009+#else
2010+# define stdc_count_zeros(x) \
2011 (stdc_count_zeros_ull (x) \
2012 - (unsigned int) (8 * (sizeof (0ULL) - sizeof (x))))
2013+#endif
2014
2015 #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_popcountll)
2016 static __always_inline unsigned int
2017@@ -540,7 +576,11 @@ extern unsigned int stdc_count_ones_ul (unsigned long int __x)
2018 __extension__
2019 extern unsigned int stdc_count_ones_ull (unsigned long long int __x)
2020 __THROW __attribute_const__;
2021-#define stdc_count_ones(x) (stdc_count_ones_ull (x))
2022+#if __glibc_has_builtin (__builtin_stdc_count_ones)
2023+# define stdc_count_ones(x) (__builtin_stdc_count_ones (x))
2024+#else
2025+# define stdc_count_ones(x) (stdc_count_ones_ull (x))
2026+#endif
2027
2028 #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_popcountll)
2029 static __always_inline unsigned int
2030@@ -590,10 +630,14 @@ extern bool stdc_has_single_bit_ul (unsigned long int __x)
2031 __extension__
2032 extern bool stdc_has_single_bit_ull (unsigned long long int __x)
2033 __THROW __attribute_const__;
2034-#define stdc_has_single_bit(x) \
2035+#if __glibc_has_builtin (__builtin_stdc_has_single_bit)
2036+# define stdc_has_single_bit(x) (__builtin_stdc_has_single_bit (x))
2037+#else
2038+# define stdc_has_single_bit(x) \
2039 ((bool) (sizeof (x) <= sizeof (unsigned int) \
2040 ? stdc_has_single_bit_ui (x) \
2041 : stdc_has_single_bit_ull (x)))
2042+#endif
2043
2044 static __always_inline bool
2045 __hsb64_inline (uint64_t __x)
2046@@ -641,7 +685,11 @@ extern unsigned int stdc_bit_width_ul (unsigned long int __x)
2047 __extension__
2048 extern unsigned int stdc_bit_width_ull (unsigned long long int __x)
2049 __THROW __attribute_const__;
2050-#define stdc_bit_width(x) (stdc_bit_width_ull (x))
2051+#if __glibc_has_builtin (__builtin_stdc_bit_width)
2052+# define stdc_bit_width(x) (__builtin_stdc_bit_width (x))
2053+#else
2054+# define stdc_bit_width(x) (stdc_bit_width_ull (x))
2055+#endif
2056
2057 #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll)
2058 static __always_inline unsigned int
2059@@ -691,7 +739,11 @@ extern unsigned long int stdc_bit_floor_ul (unsigned long int __x)
2060 __extension__
2061 extern unsigned long long int stdc_bit_floor_ull (unsigned long long int __x)
2062 __THROW __attribute_const__;
2063-#define stdc_bit_floor(x) ((__typeof (x)) stdc_bit_floor_ull (x))
2064+#if __glibc_has_builtin (__builtin_stdc_bit_floor)
2065+# define stdc_bit_floor(x) (__builtin_stdc_bit_floor (x))
2066+#else
2067+# define stdc_bit_floor(x) ((__typeof (x)) stdc_bit_floor_ull (x))
2068+#endif
2069
2070 #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll)
2071 static __always_inline uint64_t
2072@@ -743,7 +795,11 @@ extern unsigned long int stdc_bit_ceil_ul (unsigned long int __x)
2073 __extension__
2074 extern unsigned long long int stdc_bit_ceil_ull (unsigned long long int __x)
2075 __THROW __attribute_const__;
2076-#define stdc_bit_ceil(x) ((__typeof (x)) stdc_bit_ceil_ull (x))
2077+#if __glibc_has_builtin (__builtin_stdc_bit_ceil)
2078+# define stdc_bit_ceil(x) (__builtin_stdc_bit_ceil (x))
2079+#else
2080+# define stdc_bit_ceil(x) ((__typeof (x)) stdc_bit_ceil_ull (x))
2081+#endif
2082
2083 #if __GNUC_PREREQ (3, 4) || __glibc_has_builtin (__builtin_clzll)
2084 static __always_inline uint64_t
2085diff --git a/stdlib/tst-stdbit-builtins.c b/stdlib/tst-stdbit-builtins.c
2086new file mode 100644
2087index 0000000000..536841ca8a
2088--- /dev/null
2089+++ b/stdlib/tst-stdbit-builtins.c
2090@@ -0,0 +1,778 @@
2091+/* Test <stdbit.h> type-generic macros with compiler __builtin_stdc_* support.
2092+ Copyright (C) 2024 Free Software Foundation, Inc.
2093+ This file is part of the GNU C Library.
2094+
2095+ The GNU C Library is free software; you can redistribute it and/or
2096+ modify it under the terms of the GNU Lesser General Public
2097+ License as published by the Free Software Foundation; either
2098+ version 2.1 of the License, or (at your option) any later version.
2099+
2100+ The GNU C Library is distributed in the hope that it will be useful,
2101+ but WITHOUT ANY WARRANTY; without even the implied warranty of
2102+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2103+ Lesser General Public License for more details.
2104+
2105+ You should have received a copy of the GNU Lesser General Public
2106+ License along with the GNU C Library; if not, see
2107+ <https://www.gnu.org/licenses/>. */
2108+
2109+#include <stdbit.h>
2110+#include <limits.h>
2111+#include <support/check.h>
2112+
2113+#if __glibc_has_builtin (__builtin_stdc_leading_zeros) \
2114+ && __glibc_has_builtin (__builtin_stdc_leading_ones) \
2115+ && __glibc_has_builtin (__builtin_stdc_trailing_zeros) \
2116+ && __glibc_has_builtin (__builtin_stdc_trailing_ones) \
2117+ && __glibc_has_builtin (__builtin_stdc_first_leading_zero) \
2118+ && __glibc_has_builtin (__builtin_stdc_first_leading_one) \
2119+ && __glibc_has_builtin (__builtin_stdc_first_trailing_zero) \
2120+ && __glibc_has_builtin (__builtin_stdc_first_trailing_one) \
2121+ && __glibc_has_builtin (__builtin_stdc_count_zeros) \
2122+ && __glibc_has_builtin (__builtin_stdc_count_ones) \
2123+ && __glibc_has_builtin (__builtin_stdc_has_single_bit) \
2124+ && __glibc_has_builtin (__builtin_stdc_bit_width) \
2125+ && __glibc_has_builtin (__builtin_stdc_bit_floor) \
2126+ && __glibc_has_builtin (__builtin_stdc_bit_ceil)
2127+
2128+# if !defined (BITINT_MAXWIDTH) && defined (__BITINT_MAXWIDTH__)
2129+# define BITINT_MAXWIDTH __BITINT_MAXWIDTH__
2130+# endif
2131+
2132+typedef unsigned char uc;
2133+typedef unsigned short us;
2134+typedef unsigned int ui;
2135+typedef unsigned long int ul;
2136+typedef unsigned long long int ull;
2137+
2138+# define expr_has_type(e, t) _Generic (e, default : 0, t : 1)
2139+
2140+static int
2141+do_test (void)
2142+{
2143+ TEST_COMPARE (stdc_leading_zeros ((uc) 0), CHAR_BIT);
2144+ TEST_COMPARE (expr_has_type (stdc_leading_zeros ((uc) 0), ui), 1);
2145+ TEST_COMPARE (stdc_leading_zeros ((us) 0), sizeof (short) * CHAR_BIT);
2146+ TEST_COMPARE (expr_has_type (stdc_leading_zeros ((us) 0), ui), 1);
2147+ TEST_COMPARE (stdc_leading_zeros (0U), sizeof (int) * CHAR_BIT);
2148+ TEST_COMPARE (expr_has_type (stdc_leading_zeros (0U), ui), 1);
2149+ TEST_COMPARE (stdc_leading_zeros (0UL), sizeof (long int) * CHAR_BIT);
2150+ TEST_COMPARE (expr_has_type (stdc_leading_zeros (0UL), ui), 1);
2151+ TEST_COMPARE (stdc_leading_zeros (0ULL), sizeof (long long int) * CHAR_BIT);
2152+ TEST_COMPARE (expr_has_type (stdc_leading_zeros (0ULL), ui), 1);
2153+ TEST_COMPARE (stdc_leading_zeros ((uc) ~0U), 0);
2154+ TEST_COMPARE (stdc_leading_zeros ((us) ~0U), 0);
2155+ TEST_COMPARE (stdc_leading_zeros (~0U), 0);
2156+ TEST_COMPARE (stdc_leading_zeros (~0UL), 0);
2157+ TEST_COMPARE (stdc_leading_zeros (~0ULL), 0);
2158+ TEST_COMPARE (stdc_leading_zeros ((uc) 3), CHAR_BIT - 2);
2159+ TEST_COMPARE (stdc_leading_zeros ((us) 9), sizeof (short) * CHAR_BIT - 4);
2160+ TEST_COMPARE (stdc_leading_zeros (34U), sizeof (int) * CHAR_BIT - 6);
2161+ TEST_COMPARE (stdc_leading_zeros (130UL), sizeof (long int) * CHAR_BIT - 8);
2162+ TEST_COMPARE (stdc_leading_zeros (512ULL),
2163+ sizeof (long long int) * CHAR_BIT - 10);
2164+ TEST_COMPARE (stdc_leading_ones ((uc) 0), 0);
2165+ TEST_COMPARE (expr_has_type (stdc_leading_ones ((uc) 0), ui), 1);
2166+ TEST_COMPARE (stdc_leading_ones ((us) 0), 0);
2167+ TEST_COMPARE (expr_has_type (stdc_leading_ones ((us) 0), ui), 1);
2168+ TEST_COMPARE (stdc_leading_ones (0U), 0);
2169+ TEST_COMPARE (expr_has_type (stdc_leading_ones (0U), ui), 1);
2170+ TEST_COMPARE (stdc_leading_ones (0UL), 0);
2171+ TEST_COMPARE (expr_has_type (stdc_leading_ones (0UL), ui), 1);
2172+ TEST_COMPARE (stdc_leading_ones (0ULL), 0);
2173+ TEST_COMPARE (expr_has_type (stdc_leading_ones (0ULL), ui), 1);
2174+ TEST_COMPARE (stdc_leading_ones ((uc) ~0U), CHAR_BIT);
2175+ TEST_COMPARE (stdc_leading_ones ((us) ~0U), sizeof (short) * CHAR_BIT);
2176+ TEST_COMPARE (stdc_leading_ones (~0U), sizeof (int) * CHAR_BIT);
2177+ TEST_COMPARE (stdc_leading_ones (~0UL), sizeof (long int) * CHAR_BIT);
2178+ TEST_COMPARE (stdc_leading_ones (~0ULL), sizeof (long long int) * CHAR_BIT);
2179+ TEST_COMPARE (stdc_leading_ones ((uc) ~3), CHAR_BIT - 2);
2180+ TEST_COMPARE (stdc_leading_ones ((us) ~9), sizeof (short) * CHAR_BIT - 4);
2181+ TEST_COMPARE (stdc_leading_ones (~34U), sizeof (int) * CHAR_BIT - 6);
2182+ TEST_COMPARE (stdc_leading_ones (~130UL), sizeof (long int) * CHAR_BIT - 8);
2183+ TEST_COMPARE (stdc_leading_ones (~512ULL),
2184+ sizeof (long long int) * CHAR_BIT - 10);
2185+ TEST_COMPARE (stdc_trailing_zeros ((uc) 0), CHAR_BIT);
2186+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros ((uc) 0), ui), 1);
2187+ TEST_COMPARE (stdc_trailing_zeros ((us) 0), sizeof (short) * CHAR_BIT);
2188+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros ((us) 0), ui), 1);
2189+ TEST_COMPARE (stdc_trailing_zeros (0U), sizeof (int) * CHAR_BIT);
2190+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros (0U), ui), 1);
2191+ TEST_COMPARE (stdc_trailing_zeros (0UL), sizeof (long int) * CHAR_BIT);
2192+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros (0UL), ui), 1);
2193+ TEST_COMPARE (stdc_trailing_zeros (0ULL), sizeof (long long int) * CHAR_BIT);
2194+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros (0ULL), ui), 1);
2195+ TEST_COMPARE (stdc_trailing_zeros ((uc) ~0U), 0);
2196+ TEST_COMPARE (stdc_trailing_zeros ((us) ~0U), 0);
2197+ TEST_COMPARE (stdc_trailing_zeros (~0U), 0);
2198+ TEST_COMPARE (stdc_trailing_zeros (~0UL), 0);
2199+ TEST_COMPARE (stdc_trailing_zeros (~0ULL), 0);
2200+ TEST_COMPARE (stdc_trailing_zeros ((uc) 2), 1);
2201+ TEST_COMPARE (stdc_trailing_zeros ((us) 24), 3);
2202+ TEST_COMPARE (stdc_trailing_zeros (32U), 5);
2203+ TEST_COMPARE (stdc_trailing_zeros (128UL), 7);
2204+ TEST_COMPARE (stdc_trailing_zeros (512ULL), 9);
2205+ TEST_COMPARE (stdc_trailing_ones ((uc) 0), 0);
2206+ TEST_COMPARE (expr_has_type (stdc_trailing_ones ((uc) 0), ui), 1);
2207+ TEST_COMPARE (stdc_trailing_ones ((us) 0), 0);
2208+ TEST_COMPARE (expr_has_type (stdc_trailing_ones ((us) 0), ui), 1);
2209+ TEST_COMPARE (stdc_trailing_ones (0U), 0);
2210+ TEST_COMPARE (expr_has_type (stdc_trailing_ones (0U), ui), 1);
2211+ TEST_COMPARE (stdc_trailing_ones (0UL), 0);
2212+ TEST_COMPARE (expr_has_type (stdc_trailing_ones (0UL), ui), 1);
2213+ TEST_COMPARE (stdc_trailing_ones (0ULL), 0);
2214+ TEST_COMPARE (expr_has_type (stdc_trailing_ones (0ULL), ui), 1);
2215+ TEST_COMPARE (stdc_trailing_ones ((uc) ~0U), CHAR_BIT);
2216+ TEST_COMPARE (stdc_trailing_ones ((us) ~0U), sizeof (short) * CHAR_BIT);
2217+ TEST_COMPARE (stdc_trailing_ones (~0U), sizeof (int) * CHAR_BIT);
2218+ TEST_COMPARE (stdc_trailing_ones (~0UL), sizeof (long int) * CHAR_BIT);
2219+ TEST_COMPARE (stdc_trailing_ones (~0ULL), sizeof (long long int) * CHAR_BIT);
2220+ TEST_COMPARE (stdc_trailing_ones ((uc) 5), 1);
2221+ TEST_COMPARE (stdc_trailing_ones ((us) 15), 4);
2222+ TEST_COMPARE (stdc_trailing_ones (127U), 7);
2223+ TEST_COMPARE (stdc_trailing_ones (511UL), 9);
2224+ TEST_COMPARE (stdc_trailing_ones (~0ULL >> 2),
2225+ sizeof (long long int) * CHAR_BIT - 2);
2226+ TEST_COMPARE (stdc_first_leading_zero ((uc) 0), 1);
2227+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero ((uc) 0), ui), 1);
2228+ TEST_COMPARE (stdc_first_leading_zero ((us) 0), 1);
2229+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero ((us) 0), ui), 1);
2230+ TEST_COMPARE (stdc_first_leading_zero (0U), 1);
2231+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero (0U), ui), 1);
2232+ TEST_COMPARE (stdc_first_leading_zero (0UL), 1);
2233+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero (0UL), ui), 1);
2234+ TEST_COMPARE (stdc_first_leading_zero (0ULL), 1);
2235+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero (0ULL), ui), 1);
2236+ TEST_COMPARE (stdc_first_leading_zero ((uc) ~0U), 0);
2237+ TEST_COMPARE (stdc_first_leading_zero ((us) ~0U), 0);
2238+ TEST_COMPARE (stdc_first_leading_zero (~0U), 0);
2239+ TEST_COMPARE (stdc_first_leading_zero (~0UL), 0);
2240+ TEST_COMPARE (stdc_first_leading_zero (~0ULL), 0);
2241+ TEST_COMPARE (stdc_first_leading_zero ((uc) ~3U), CHAR_BIT - 1);
2242+ TEST_COMPARE (stdc_first_leading_zero ((us) ~15U),
2243+ sizeof (short) * CHAR_BIT - 3);
2244+ TEST_COMPARE (stdc_first_leading_zero (~63U), sizeof (int) * CHAR_BIT - 5);
2245+ TEST_COMPARE (stdc_first_leading_zero (~255UL),
2246+ sizeof (long int) * CHAR_BIT - 7);
2247+ TEST_COMPARE (stdc_first_leading_zero (~1023ULL),
2248+ sizeof (long long int) * CHAR_BIT - 9);
2249+ TEST_COMPARE (stdc_first_leading_one ((uc) 0), 0);
2250+ TEST_COMPARE (expr_has_type (stdc_first_leading_one ((uc) 0), ui), 1);
2251+ TEST_COMPARE (stdc_first_leading_one ((us) 0), 0);
2252+ TEST_COMPARE (expr_has_type (stdc_first_leading_one ((us) 0), ui), 1);
2253+ TEST_COMPARE (stdc_first_leading_one (0U), 0);
2254+ TEST_COMPARE (expr_has_type (stdc_first_leading_one (0U), ui), 1);
2255+ TEST_COMPARE (stdc_first_leading_one (0UL), 0);
2256+ TEST_COMPARE (expr_has_type (stdc_first_leading_one (0UL), ui), 1);
2257+ TEST_COMPARE (stdc_first_leading_one (0ULL), 0);
2258+ TEST_COMPARE (expr_has_type (stdc_first_leading_one (0ULL), ui), 1);
2259+ TEST_COMPARE (stdc_first_leading_one ((uc) ~0U), 1);
2260+ TEST_COMPARE (stdc_first_leading_one ((us) ~0U), 1);
2261+ TEST_COMPARE (stdc_first_leading_one (~0U), 1);
2262+ TEST_COMPARE (stdc_first_leading_one (~0UL), 1);
2263+ TEST_COMPARE (stdc_first_leading_one (~0ULL), 1);
2264+ TEST_COMPARE (stdc_first_leading_one ((uc) 3), CHAR_BIT - 1);
2265+ TEST_COMPARE (stdc_first_leading_one ((us) 9),
2266+ sizeof (short) * CHAR_BIT - 3);
2267+ TEST_COMPARE (stdc_first_leading_one (34U), sizeof (int) * CHAR_BIT - 5);
2268+ TEST_COMPARE (stdc_first_leading_one (130UL),
2269+ sizeof (long int) * CHAR_BIT - 7);
2270+ TEST_COMPARE (stdc_first_leading_one (512ULL),
2271+ sizeof (long long int) * CHAR_BIT - 9);
2272+ TEST_COMPARE (stdc_first_trailing_zero ((uc) 0), 1);
2273+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero ((uc) 0), ui), 1);
2274+ TEST_COMPARE (stdc_first_trailing_zero ((us) 0), 1);
2275+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero ((us) 0), ui), 1);
2276+ TEST_COMPARE (stdc_first_trailing_zero (0U), 1);
2277+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero (0U), ui), 1);
2278+ TEST_COMPARE (stdc_first_trailing_zero (0UL), 1);
2279+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero (0UL), ui), 1);
2280+ TEST_COMPARE (stdc_first_trailing_zero (0ULL), 1);
2281+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero (0ULL), ui), 1);
2282+ TEST_COMPARE (stdc_first_trailing_zero ((uc) ~0U), 0);
2283+ TEST_COMPARE (stdc_first_trailing_zero ((us) ~0U), 0);
2284+ TEST_COMPARE (stdc_first_trailing_zero (~0U), 0);
2285+ TEST_COMPARE (stdc_first_trailing_zero (~0UL), 0);
2286+ TEST_COMPARE (stdc_first_trailing_zero (~0ULL), 0);
2287+ TEST_COMPARE (stdc_first_trailing_zero ((uc) 2), 1);
2288+ TEST_COMPARE (stdc_first_trailing_zero ((us) 15), 5);
2289+ TEST_COMPARE (stdc_first_trailing_zero (63U), 7);
2290+ TEST_COMPARE (stdc_first_trailing_zero (128UL), 1);
2291+ TEST_COMPARE (stdc_first_trailing_zero (511ULL), 10);
2292+ TEST_COMPARE (stdc_first_trailing_one ((uc) 0), 0);
2293+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one ((uc) 0), ui), 1);
2294+ TEST_COMPARE (stdc_first_trailing_one ((us) 0), 0);
2295+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one ((us) 0), ui), 1);
2296+ TEST_COMPARE (stdc_first_trailing_one (0U), 0);
2297+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one (0U), ui), 1);
2298+ TEST_COMPARE (stdc_first_trailing_one (0UL), 0);
2299+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one (0UL), ui), 1);
2300+ TEST_COMPARE (stdc_first_trailing_one (0ULL), 0);
2301+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one (0ULL), ui), 1);
2302+ TEST_COMPARE (stdc_first_trailing_one ((uc) ~0U), 1);
2303+ TEST_COMPARE (stdc_first_trailing_one ((us) ~0U), 1);
2304+ TEST_COMPARE (stdc_first_trailing_one (~0U), 1);
2305+ TEST_COMPARE (stdc_first_trailing_one (~0UL), 1);
2306+ TEST_COMPARE (stdc_first_trailing_one (~0ULL), 1);
2307+ TEST_COMPARE (stdc_first_trailing_one ((uc) 4), 3);
2308+ TEST_COMPARE (stdc_first_trailing_one ((us) 96), 6);
2309+ TEST_COMPARE (stdc_first_trailing_one (127U), 1);
2310+ TEST_COMPARE (stdc_first_trailing_one (511UL), 1);
2311+ TEST_COMPARE (stdc_first_trailing_one (~0ULL << 12), 13);
2312+ TEST_COMPARE (stdc_count_zeros ((uc) 0), CHAR_BIT);
2313+ TEST_COMPARE (expr_has_type (stdc_count_zeros ((uc) 0), ui), 1);
2314+ TEST_COMPARE (stdc_count_zeros ((us) 0), sizeof (short) * CHAR_BIT);
2315+ TEST_COMPARE (expr_has_type (stdc_count_zeros ((us) 0), ui), 1);
2316+ TEST_COMPARE (stdc_count_zeros (0U), sizeof (int) * CHAR_BIT);
2317+ TEST_COMPARE (expr_has_type (stdc_count_zeros (0U), ui), 1);
2318+ TEST_COMPARE (stdc_count_zeros (0UL), sizeof (long int) * CHAR_BIT);
2319+ TEST_COMPARE (expr_has_type (stdc_count_zeros (0UL), ui), 1);
2320+ TEST_COMPARE (stdc_count_zeros (0ULL), sizeof (long long int) * CHAR_BIT);
2321+ TEST_COMPARE (expr_has_type (stdc_count_zeros (0ULL), ui), 1);
2322+ TEST_COMPARE (stdc_count_zeros ((uc) ~0U), 0);
2323+ TEST_COMPARE (stdc_count_zeros ((us) ~0U), 0);
2324+ TEST_COMPARE (stdc_count_zeros (~0U), 0);
2325+ TEST_COMPARE (stdc_count_zeros (~0UL), 0);
2326+ TEST_COMPARE (stdc_count_zeros (~0ULL), 0);
2327+ TEST_COMPARE (stdc_count_zeros ((uc) 1U), CHAR_BIT - 1);
2328+ TEST_COMPARE (stdc_count_zeros ((us) 42), sizeof (short) * CHAR_BIT - 3);
2329+ TEST_COMPARE (stdc_count_zeros (291U), sizeof (int) * CHAR_BIT - 4);
2330+ TEST_COMPARE (stdc_count_zeros (~1315UL), 5);
2331+ TEST_COMPARE (stdc_count_zeros (3363ULL),
2332+ sizeof (long long int) * CHAR_BIT - 6);
2333+ TEST_COMPARE (stdc_count_ones ((uc) 0), 0);
2334+ TEST_COMPARE (expr_has_type (stdc_count_ones ((uc) 0), ui), 1);
2335+ TEST_COMPARE (stdc_count_ones ((us) 0), 0);
2336+ TEST_COMPARE (expr_has_type (stdc_count_ones ((us) 0), ui), 1);
2337+ TEST_COMPARE (stdc_count_ones (0U), 0);
2338+ TEST_COMPARE (expr_has_type (stdc_count_ones (0U), ui), 1);
2339+ TEST_COMPARE (stdc_count_ones (0UL), 0);
2340+ TEST_COMPARE (expr_has_type (stdc_count_ones (0UL), ui), 1);
2341+ TEST_COMPARE (stdc_count_ones (0ULL), 0);
2342+ TEST_COMPARE (expr_has_type (stdc_count_ones (0ULL), ui), 1);
2343+ TEST_COMPARE (stdc_count_ones ((uc) ~0U), CHAR_BIT);
2344+ TEST_COMPARE (stdc_count_ones ((us) ~0U), sizeof (short) * CHAR_BIT);
2345+ TEST_COMPARE (stdc_count_ones (~0U), sizeof (int) * CHAR_BIT);
2346+ TEST_COMPARE (stdc_count_ones (~0UL), sizeof (long int) * CHAR_BIT);
2347+ TEST_COMPARE (stdc_count_ones (~0ULL), sizeof (long long int) * CHAR_BIT);
2348+ TEST_COMPARE (stdc_count_ones ((uc) ~1U), CHAR_BIT - 1);
2349+ TEST_COMPARE (stdc_count_ones ((us) ~42), sizeof (short) * CHAR_BIT - 3);
2350+ TEST_COMPARE (stdc_count_ones (~291U), sizeof (int) * CHAR_BIT - 4);
2351+ TEST_COMPARE (stdc_count_ones (1315UL), 5);
2352+ TEST_COMPARE (stdc_count_ones (~3363ULL),
2353+ sizeof (long long int) * CHAR_BIT - 6);
2354+ TEST_COMPARE (stdc_has_single_bit ((uc) 0), 0);
2355+ TEST_COMPARE (expr_has_type (stdc_has_single_bit ((uc) 0), _Bool), 1);
2356+ TEST_COMPARE (stdc_has_single_bit ((us) 0), 0);
2357+ TEST_COMPARE (expr_has_type (stdc_has_single_bit ((us) 0), _Bool), 1);
2358+ TEST_COMPARE (stdc_has_single_bit (0U), 0);
2359+ TEST_COMPARE (expr_has_type (stdc_has_single_bit (0U), _Bool), 1);
2360+ TEST_COMPARE (stdc_has_single_bit (0UL), 0);
2361+ TEST_COMPARE (expr_has_type (stdc_has_single_bit (0UL), _Bool), 1);
2362+ TEST_COMPARE (stdc_has_single_bit (0ULL), 0);
2363+ TEST_COMPARE (expr_has_type (stdc_has_single_bit (0ULL), _Bool), 1);
2364+ TEST_COMPARE (stdc_has_single_bit ((uc) 2), 1);
2365+ TEST_COMPARE (stdc_has_single_bit ((us) 8), 1);
2366+ TEST_COMPARE (stdc_has_single_bit (32U), 1);
2367+ TEST_COMPARE (stdc_has_single_bit (128UL), 1);
2368+ TEST_COMPARE (stdc_has_single_bit (512ULL), 1);
2369+ TEST_COMPARE (stdc_has_single_bit ((uc) 7), 0);
2370+ TEST_COMPARE (stdc_has_single_bit ((us) 96), 0);
2371+ TEST_COMPARE (stdc_has_single_bit (513U), 0);
2372+ TEST_COMPARE (stdc_has_single_bit (1022UL), 0);
2373+ TEST_COMPARE (stdc_has_single_bit (12ULL), 0);
2374+ TEST_COMPARE (stdc_bit_width ((uc) 0), 0);
2375+ TEST_COMPARE (expr_has_type (stdc_bit_width ((uc) 0), ui), 1);
2376+ TEST_COMPARE (stdc_bit_width ((us) 0), 0);
2377+ TEST_COMPARE (expr_has_type (stdc_bit_width ((us) 0), ui), 1);
2378+ TEST_COMPARE (stdc_bit_width (0U), 0);
2379+ TEST_COMPARE (expr_has_type (stdc_bit_width (0U), ui), 1);
2380+ TEST_COMPARE (stdc_bit_width (0UL), 0);
2381+ TEST_COMPARE (expr_has_type (stdc_bit_width (0UL), ui), 1);
2382+ TEST_COMPARE (stdc_bit_width (0ULL), 0);
2383+ TEST_COMPARE (expr_has_type (stdc_bit_width (0ULL), ui), 1);
2384+ TEST_COMPARE (stdc_bit_width ((uc) ~0U), CHAR_BIT);
2385+ TEST_COMPARE (stdc_bit_width ((us) ~0U), sizeof (short) * CHAR_BIT);
2386+ TEST_COMPARE (stdc_bit_width (~0U), sizeof (int) * CHAR_BIT);
2387+ TEST_COMPARE (stdc_bit_width (~0UL), sizeof (long int) * CHAR_BIT);
2388+ TEST_COMPARE (stdc_bit_width (~0ULL), sizeof (long long int) * CHAR_BIT);
2389+ TEST_COMPARE (stdc_bit_width ((uc) ((uc) ~0U >> 1)), CHAR_BIT - 1);
2390+ TEST_COMPARE (stdc_bit_width ((uc) 6), 3);
2391+ TEST_COMPARE (stdc_bit_width ((us) 12U), 4);
2392+ TEST_COMPARE (stdc_bit_width ((us) ((us) ~0U >> 5)),
2393+ sizeof (short) * CHAR_BIT - 5);
2394+ TEST_COMPARE (stdc_bit_width (137U), 8);
2395+ TEST_COMPARE (stdc_bit_width (269U), 9);
2396+ TEST_COMPARE (stdc_bit_width (39UL), 6);
2397+ TEST_COMPARE (stdc_bit_width (~0UL >> 2), sizeof (long int) * CHAR_BIT - 2);
2398+ TEST_COMPARE (stdc_bit_width (1023ULL), 10);
2399+ TEST_COMPARE (stdc_bit_width (1024ULL), 11);
2400+ TEST_COMPARE (stdc_bit_floor ((uc) 0), 0);
2401+ TEST_COMPARE (expr_has_type (stdc_bit_floor ((uc) 0), uc), 1);
2402+ TEST_COMPARE (stdc_bit_floor ((us) 0), 0);
2403+ TEST_COMPARE (expr_has_type (stdc_bit_floor ((us) 0), us), 1);
2404+ TEST_COMPARE (stdc_bit_floor (0U), 0U);
2405+ TEST_COMPARE (expr_has_type (stdc_bit_floor (0U), ui), 1);
2406+ TEST_COMPARE (stdc_bit_floor (0UL), 0UL);
2407+ TEST_COMPARE (expr_has_type (stdc_bit_floor (0UL), ul), 1);
2408+ TEST_COMPARE (stdc_bit_floor (0ULL), 0ULL);
2409+ TEST_COMPARE (expr_has_type (stdc_bit_floor (0ULL), ull), 1);
2410+ TEST_COMPARE (stdc_bit_floor ((uc) ~0U), (1U << (CHAR_BIT - 1)));
2411+ TEST_COMPARE (stdc_bit_floor ((us) ~0U),
2412+ (1U << (sizeof (short) * CHAR_BIT - 1)));
2413+ TEST_COMPARE (stdc_bit_floor (~0U), (1U << (sizeof (int) * CHAR_BIT - 1)));
2414+ TEST_COMPARE (stdc_bit_floor (~0UL),
2415+ (1UL << (sizeof (long int) * CHAR_BIT - 1)));
2416+ TEST_COMPARE (stdc_bit_floor (~0ULL),
2417+ (1ULL << (sizeof (long long int) * CHAR_BIT - 1)));
2418+ TEST_COMPARE (stdc_bit_floor ((uc) 4), 4);
2419+ TEST_COMPARE (stdc_bit_floor ((uc) 7), 4);
2420+ TEST_COMPARE (stdc_bit_floor ((us) 8U), 8);
2421+ TEST_COMPARE (stdc_bit_floor ((us) 31U), 16);
2422+ TEST_COMPARE (stdc_bit_floor (137U), 128U);
2423+ TEST_COMPARE (stdc_bit_floor (269U), 256U);
2424+ TEST_COMPARE (stdc_bit_floor (511UL), 256UL);
2425+ TEST_COMPARE (stdc_bit_floor (512UL), 512UL);
2426+ TEST_COMPARE (stdc_bit_floor (513UL), 512ULL);
2427+ TEST_COMPARE (stdc_bit_floor (1024ULL), 1024ULL);
2428+ TEST_COMPARE (stdc_bit_ceil ((uc) 0), 1);
2429+ TEST_COMPARE (expr_has_type (stdc_bit_ceil ((uc) 0), uc), 1);
2430+ TEST_COMPARE (stdc_bit_ceil ((us) 0), 1);
2431+ TEST_COMPARE (expr_has_type (stdc_bit_ceil ((us) 0), us), 1);
2432+ TEST_COMPARE (stdc_bit_ceil (0U), 1U);
2433+ TEST_COMPARE (expr_has_type (stdc_bit_ceil (0U), ui), 1);
2434+ TEST_COMPARE (stdc_bit_ceil (0UL), 1UL);
2435+ TEST_COMPARE (expr_has_type (stdc_bit_ceil (0UL), ul), 1);
2436+ TEST_COMPARE (stdc_bit_ceil (0ULL), 1ULL);
2437+ TEST_COMPARE (expr_has_type (stdc_bit_ceil (0ULL), ull), 1);
2438+ TEST_COMPARE (stdc_bit_ceil ((uc) ~0U), 0);
2439+ TEST_COMPARE (stdc_bit_ceil ((us) ~0U), 0);
2440+ TEST_COMPARE (stdc_bit_ceil (~0U), 0U);
2441+ TEST_COMPARE (stdc_bit_ceil (~0UL), 0UL);
2442+ TEST_COMPARE (stdc_bit_ceil (~0ULL), 0ULL);
2443+ TEST_COMPARE (stdc_bit_ceil ((uc) ((uc) ~0U >> 1)), (1U << (CHAR_BIT - 1)));
2444+ TEST_COMPARE (stdc_bit_ceil ((uc) ((uc) ~0U >> 1)), (1U << (CHAR_BIT - 1)));
2445+ TEST_COMPARE (stdc_bit_ceil ((us) ((us) ~0U >> 1)),
2446+ (1U << (sizeof (short) * CHAR_BIT - 1)));
2447+ TEST_COMPARE (stdc_bit_ceil ((us) ((us) ~0U >> 1)),
2448+ (1U << (sizeof (short) * CHAR_BIT - 1)));
2449+ TEST_COMPARE (stdc_bit_ceil (~0U >> 1),
2450+ (1U << (sizeof (int) * CHAR_BIT - 1)));
2451+ TEST_COMPARE (stdc_bit_ceil (1U << (sizeof (int) * CHAR_BIT - 1)),
2452+ (1U << (sizeof (int) * CHAR_BIT - 1)));
2453+ TEST_COMPARE (stdc_bit_ceil (~0UL >> 1),
2454+ (1UL << (sizeof (long int) * CHAR_BIT - 1)));
2455+ TEST_COMPARE (stdc_bit_ceil (~0UL >> 1),
2456+ (1UL << (sizeof (long int) * CHAR_BIT - 1)));
2457+ TEST_COMPARE (stdc_bit_ceil (1ULL
2458+ << (sizeof (long long int) * CHAR_BIT - 1)),
2459+ (1ULL << (sizeof (long long int) * CHAR_BIT - 1)));
2460+ TEST_COMPARE (stdc_bit_ceil (~0ULL >> 1),
2461+ (1ULL << (sizeof (long long int) * CHAR_BIT - 1)));
2462+ TEST_COMPARE (stdc_bit_ceil ((uc) 1), 1);
2463+ TEST_COMPARE (stdc_bit_ceil ((uc) 2), 2);
2464+ TEST_COMPARE (stdc_bit_ceil ((us) 3U), 4);
2465+ TEST_COMPARE (stdc_bit_ceil ((us) 4U), 4);
2466+ TEST_COMPARE (stdc_bit_ceil (5U), 8U);
2467+ TEST_COMPARE (stdc_bit_ceil (269U), 512U);
2468+ TEST_COMPARE (stdc_bit_ceil (511UL), 512UL);
2469+ TEST_COMPARE (stdc_bit_ceil (512UL), 512UL);
2470+ TEST_COMPARE (stdc_bit_ceil (513ULL), 1024ULL);
2471+ TEST_COMPARE (stdc_bit_ceil (1025ULL), 2048ULL);
2472+# ifdef __SIZEOF_INT128__
2473+ TEST_COMPARE (stdc_leading_zeros ((unsigned __int128) 0),
2474+ sizeof (__int128) * CHAR_BIT);
2475+ TEST_COMPARE (expr_has_type (stdc_leading_zeros ((unsigned __int128) 0), ui),
2476+ 1);
2477+ TEST_COMPARE (stdc_leading_zeros (~(unsigned __int128) 0), 0);
2478+ TEST_COMPARE (stdc_leading_ones ((unsigned __int128) 0), 0);
2479+ TEST_COMPARE (expr_has_type (stdc_leading_ones ((unsigned __int128) 0), ui),
2480+ 1);
2481+ TEST_COMPARE (stdc_leading_ones (~(unsigned __int128) 0),
2482+ sizeof (__int128) * CHAR_BIT);
2483+ TEST_COMPARE (stdc_trailing_zeros ((unsigned __int128) 0),
2484+ sizeof (__int128) * CHAR_BIT);
2485+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros ((unsigned __int128) 0),
2486+ ui), 1);
2487+ TEST_COMPARE (stdc_trailing_zeros (~(unsigned __int128) 0), 0);
2488+ TEST_COMPARE (stdc_trailing_ones ((unsigned __int128) 0), 0);
2489+ TEST_COMPARE (expr_has_type (stdc_trailing_ones ((unsigned __int128) 0), ui),
2490+ 1);
2491+ TEST_COMPARE (stdc_trailing_ones (~(unsigned __int128) 0),
2492+ sizeof (__int128) * CHAR_BIT);
2493+ TEST_COMPARE (stdc_first_leading_zero ((unsigned __int128) 0), 1);
2494+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero ((unsigned __int128) 0),
2495+ ui), 1);
2496+ TEST_COMPARE (stdc_first_leading_zero (~(unsigned __int128) 0), 0);
2497+ TEST_COMPARE (stdc_first_leading_one ((unsigned __int128) 0), 0);
2498+ TEST_COMPARE (expr_has_type (stdc_first_leading_one ((unsigned __int128) 0),
2499+ ui), 1);
2500+ TEST_COMPARE (stdc_first_leading_one (~(unsigned __int128) 0), 1);
2501+ TEST_COMPARE (stdc_first_trailing_zero ((unsigned __int128) 0), 1);
2502+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero ((unsigned __int128)
2503+ 0), ui), 1);
2504+ TEST_COMPARE (stdc_first_trailing_zero (~(unsigned __int128) 0), 0);
2505+ TEST_COMPARE (stdc_first_trailing_one ((unsigned __int128) 0), 0);
2506+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one ((unsigned __int128) 0),
2507+ ui), 1);
2508+ TEST_COMPARE (stdc_first_trailing_one (~(unsigned __int128) 0), 1);
2509+ TEST_COMPARE (stdc_count_zeros ((unsigned __int128) 0),
2510+ sizeof (__int128) * CHAR_BIT);
2511+ TEST_COMPARE (expr_has_type (stdc_count_zeros ((unsigned __int128) 0), ui),
2512+ 1);
2513+ TEST_COMPARE (stdc_count_zeros (~(unsigned __int128) 0), 0);
2514+ TEST_COMPARE (stdc_count_ones ((unsigned __int128) 0), 0);
2515+ TEST_COMPARE (expr_has_type (stdc_count_ones ((unsigned __int128) 0), ui),
2516+ 1);
2517+ TEST_COMPARE (stdc_count_ones (~(unsigned __int128) 0),
2518+ sizeof (__int128) * CHAR_BIT);
2519+ TEST_COMPARE (stdc_has_single_bit ((unsigned __int128) 0), 0);
2520+ TEST_COMPARE (expr_has_type (stdc_has_single_bit ((unsigned __int128) 0),
2521+ _Bool), 1);
2522+ TEST_COMPARE (stdc_has_single_bit (~(unsigned __int128) 0), 0);
2523+ TEST_COMPARE (stdc_bit_width ((unsigned __int128) 0), 0);
2524+ TEST_COMPARE (expr_has_type (stdc_bit_width ((unsigned __int128) 0), ui), 1);
2525+ TEST_COMPARE (stdc_bit_width (~(unsigned __int128) 0),
2526+ sizeof (__int128) * CHAR_BIT);
2527+ TEST_COMPARE (stdc_bit_floor ((unsigned __int128) 0) != 0, 0);
2528+ TEST_COMPARE (expr_has_type (stdc_bit_floor ((unsigned __int128) 0),
2529+ unsigned __int128), 1);
2530+ TEST_COMPARE (stdc_bit_floor (~(unsigned __int128) 0)
2531+ != ((unsigned __int128) 1) << (sizeof (__int128)
2532+ * CHAR_BIT - 1), 0);
2533+ TEST_COMPARE (stdc_bit_ceil ((unsigned __int128) 0) != 1, 0);
2534+ TEST_COMPARE (expr_has_type (stdc_bit_ceil ((unsigned __int128) 0),
2535+ unsigned __int128), 1);
2536+ TEST_COMPARE (stdc_bit_ceil ((unsigned __int128) 1) != 1, 0);
2537+ TEST_COMPARE (stdc_bit_ceil ((~(unsigned __int128) 0) >> 1)
2538+ != ((unsigned __int128) 1) << (sizeof (__int128)
2539+ * CHAR_BIT - 1), 0);
2540+ TEST_COMPARE (stdc_bit_ceil (~(unsigned __int128) 0) != 0, 0);
2541+# endif
2542+ uc a = 0;
2543+ TEST_COMPARE (stdc_bit_width (a++), 0);
2544+ TEST_COMPARE (a, 1);
2545+ ull b = 0;
2546+ TEST_COMPARE (stdc_bit_width (b++), 0);
2547+ TEST_COMPARE (b, 1);
2548+ TEST_COMPARE (stdc_bit_floor (a++), 1);
2549+ TEST_COMPARE (a, 2);
2550+ TEST_COMPARE (stdc_bit_floor (b++), 1);
2551+ TEST_COMPARE (b, 2);
2552+ TEST_COMPARE (stdc_bit_ceil (a++), 2);
2553+ TEST_COMPARE (a, 3);
2554+ TEST_COMPARE (stdc_bit_ceil (b++), 2);
2555+ TEST_COMPARE (b, 3);
2556+ TEST_COMPARE (stdc_leading_zeros (a++), CHAR_BIT - 2);
2557+ TEST_COMPARE (a, 4);
2558+ TEST_COMPARE (stdc_leading_zeros (b++),
2559+ sizeof (long long int) * CHAR_BIT - 2);
2560+ TEST_COMPARE (b, 4);
2561+ TEST_COMPARE (stdc_leading_ones (a++), 0);
2562+ TEST_COMPARE (a, 5);
2563+ TEST_COMPARE (stdc_leading_ones (b++), 0);
2564+ TEST_COMPARE (b, 5);
2565+ TEST_COMPARE (stdc_trailing_zeros (a++), 0);
2566+ TEST_COMPARE (a, 6);
2567+ TEST_COMPARE (stdc_trailing_zeros (b++), 0);
2568+ TEST_COMPARE (b, 6);
2569+ TEST_COMPARE (stdc_trailing_ones (a++), 0);
2570+ TEST_COMPARE (a, 7);
2571+ TEST_COMPARE (stdc_trailing_ones (b++), 0);
2572+ TEST_COMPARE (b, 7);
2573+ TEST_COMPARE (stdc_first_leading_zero (a++), 1);
2574+ TEST_COMPARE (a, 8);
2575+ TEST_COMPARE (stdc_first_leading_zero (b++), 1);
2576+ TEST_COMPARE (b, 8);
2577+ TEST_COMPARE (stdc_first_leading_one (a++), CHAR_BIT - 3);
2578+ TEST_COMPARE (a, 9);
2579+ TEST_COMPARE (stdc_first_leading_one (b++),
2580+ sizeof (long long int) * CHAR_BIT - 3);
2581+ TEST_COMPARE (b, 9);
2582+ TEST_COMPARE (stdc_first_trailing_zero (a++), 2);
2583+ TEST_COMPARE (a, 10);
2584+ TEST_COMPARE (stdc_first_trailing_zero (b++), 2);
2585+ TEST_COMPARE (b, 10);
2586+ TEST_COMPARE (stdc_first_trailing_one (a++), 2);
2587+ TEST_COMPARE (a, 11);
2588+ TEST_COMPARE (stdc_first_trailing_one (b++), 2);
2589+ TEST_COMPARE (b, 11);
2590+ TEST_COMPARE (stdc_count_zeros (a++), CHAR_BIT - 3);
2591+ TEST_COMPARE (a, 12);
2592+ TEST_COMPARE (stdc_count_zeros (b++),
2593+ sizeof (long long int) * CHAR_BIT - 3);
2594+ TEST_COMPARE (b, 12);
2595+ TEST_COMPARE (stdc_count_ones (a++), 2);
2596+ TEST_COMPARE (a, 13);
2597+ TEST_COMPARE (stdc_count_ones (b++), 2);
2598+ TEST_COMPARE (b, 13);
2599+ TEST_COMPARE (stdc_has_single_bit (a++), 0);
2600+ TEST_COMPARE (a, 14);
2601+ TEST_COMPARE (stdc_has_single_bit (b++), 0);
2602+ TEST_COMPARE (b, 14);
2603+# ifdef BITINT_MAXWIDTH
2604+# if BITINT_MAXWIDTH >= 64
2605+ TEST_COMPARE (stdc_leading_zeros (0uwb), 1);
2606+ TEST_COMPARE (expr_has_type (stdc_leading_zeros (0uwb), ui), 1);
2607+ TEST_COMPARE (stdc_leading_zeros (1uwb), 0);
2608+ TEST_COMPARE (expr_has_type (stdc_leading_zeros (1uwb), ui), 1);
2609+ TEST_COMPARE (stdc_leading_ones (0uwb), 0);
2610+ TEST_COMPARE (expr_has_type (stdc_leading_ones (0uwb), ui), 1);
2611+ TEST_COMPARE (stdc_leading_ones (1uwb), 1);
2612+ TEST_COMPARE (expr_has_type (stdc_leading_ones (1uwb), ui), 1);
2613+ TEST_COMPARE (stdc_trailing_zeros (0uwb), 1);
2614+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros (0uwb), ui), 1);
2615+ TEST_COMPARE (stdc_trailing_zeros (1uwb), 0);
2616+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros (1uwb), ui), 1);
2617+ TEST_COMPARE (stdc_trailing_ones (0uwb), 0);
2618+ TEST_COMPARE (expr_has_type (stdc_trailing_ones (0uwb), ui), 1);
2619+ TEST_COMPARE (stdc_trailing_ones (1uwb), 1);
2620+ TEST_COMPARE (expr_has_type (stdc_trailing_ones (1uwb), ui), 1);
2621+ TEST_COMPARE (stdc_first_leading_zero (0uwb), 1);
2622+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero (0uwb), ui), 1);
2623+ TEST_COMPARE (stdc_first_leading_zero (1uwb), 0);
2624+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero (1uwb), ui), 1);
2625+ TEST_COMPARE (stdc_first_leading_one (0uwb), 0);
2626+ TEST_COMPARE (expr_has_type (stdc_first_leading_one (0uwb), ui), 1);
2627+ TEST_COMPARE (stdc_first_leading_one (1uwb), 1);
2628+ TEST_COMPARE (expr_has_type (stdc_first_leading_one (1uwb), ui), 1);
2629+ TEST_COMPARE (stdc_first_trailing_zero (0uwb), 1);
2630+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero (0uwb), ui), 1);
2631+ TEST_COMPARE (stdc_first_trailing_zero (1uwb), 0);
2632+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero (1uwb), ui), 1);
2633+ TEST_COMPARE (stdc_first_trailing_one (0uwb), 0);
2634+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one (0uwb), ui), 1);
2635+ TEST_COMPARE (stdc_first_trailing_one (1uwb), 1);
2636+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one (1uwb), ui), 1);
2637+ TEST_COMPARE (stdc_count_zeros (0uwb), 1);
2638+ TEST_COMPARE (expr_has_type (stdc_count_zeros (0uwb), ui), 1);
2639+ TEST_COMPARE (stdc_count_zeros (1uwb), 0);
2640+ TEST_COMPARE (expr_has_type (stdc_count_zeros (1uwb), ui), 1);
2641+ TEST_COMPARE (stdc_count_ones (0uwb), 0);
2642+ TEST_COMPARE (expr_has_type (stdc_count_ones (0uwb), ui), 1);
2643+ TEST_COMPARE (stdc_count_ones (1uwb), 1);
2644+ TEST_COMPARE (expr_has_type (stdc_count_ones (1uwb), ui), 1);
2645+ TEST_COMPARE (stdc_has_single_bit (0uwb), 0);
2646+ TEST_COMPARE (expr_has_type (stdc_has_single_bit (0uwb), _Bool), 1);
2647+ TEST_COMPARE (stdc_has_single_bit (1uwb), 1);
2648+ TEST_COMPARE (expr_has_type (stdc_has_single_bit (1uwb), _Bool), 1);
2649+ TEST_COMPARE (stdc_bit_width (0uwb), 0);
2650+ TEST_COMPARE (expr_has_type (stdc_bit_width (0uwb), ui), 1);
2651+ TEST_COMPARE (stdc_bit_width (1uwb), 1);
2652+ TEST_COMPARE (expr_has_type (stdc_bit_width (1uwb), ui), 1);
2653+ TEST_COMPARE (stdc_bit_floor (0uwb), 0);
2654+ TEST_COMPARE (expr_has_type (stdc_bit_floor (0uwb), unsigned _BitInt(1)), 1);
2655+ TEST_COMPARE (stdc_bit_floor (1uwb), 1);
2656+ TEST_COMPARE (expr_has_type (stdc_bit_floor (1uwb), unsigned _BitInt(1)), 1);
2657+ TEST_COMPARE (stdc_bit_ceil (0uwb), 1);
2658+ TEST_COMPARE (expr_has_type (stdc_bit_ceil (0uwb), unsigned _BitInt(1)), 1);
2659+ TEST_COMPARE (stdc_bit_ceil (1uwb), 1);
2660+ TEST_COMPARE (expr_has_type (stdc_bit_ceil (1uwb), unsigned _BitInt(1)), 1);
2661+ unsigned _BitInt(1) c = 0;
2662+ TEST_COMPARE (stdc_bit_floor (c++), 0);
2663+ TEST_COMPARE (c, 1);
2664+ TEST_COMPARE (stdc_bit_floor (c++), 1);
2665+ TEST_COMPARE (c, 0);
2666+ TEST_COMPARE (stdc_bit_ceil (c++), 1);
2667+ TEST_COMPARE (c, 1);
2668+ TEST_COMPARE (stdc_bit_ceil (c++), 1);
2669+ TEST_COMPARE (c, 0);
2670+# endif
2671+# if BITINT_MAXWIDTH >= 512
2672+ TEST_COMPARE (stdc_leading_zeros ((unsigned _BitInt(512)) 0), 512);
2673+ TEST_COMPARE (expr_has_type (stdc_leading_zeros ((unsigned _BitInt(512)) 0),
2674+ ui), 1);
2675+ TEST_COMPARE (stdc_leading_zeros ((unsigned _BitInt(373)) 0), 373);
2676+ TEST_COMPARE (expr_has_type (stdc_leading_zeros ((unsigned _BitInt(373)) 0),
2677+ ui), 1);
2678+ TEST_COMPARE (stdc_leading_zeros (~(unsigned _BitInt(512)) 0), 0);
2679+ TEST_COMPARE (stdc_leading_zeros (~(unsigned _BitInt(373)) 0), 0);
2680+ TEST_COMPARE (stdc_leading_zeros ((unsigned _BitInt(512)) 275), 512 - 9);
2681+ TEST_COMPARE (stdc_leading_zeros ((unsigned _BitInt(373)) 512), 373 - 10);
2682+ TEST_COMPARE (stdc_leading_ones ((unsigned _BitInt(512)) 0), 0);
2683+ TEST_COMPARE (expr_has_type (stdc_leading_ones ((unsigned _BitInt(512)) 0),
2684+ ui), 1);
2685+ TEST_COMPARE (stdc_leading_ones ((unsigned _BitInt(373)) 0), 0);
2686+ TEST_COMPARE (expr_has_type (stdc_leading_ones ((unsigned _BitInt(373)) 0),
2687+ ui), 1);
2688+ TEST_COMPARE (stdc_leading_ones (~(unsigned _BitInt(512)) 0), 512);
2689+ TEST_COMPARE (stdc_leading_ones (~(unsigned _BitInt(373)) 0), 373);
2690+ TEST_COMPARE (stdc_leading_ones (~(unsigned _BitInt(512)) 275), 512 - 9);
2691+ TEST_COMPARE (stdc_leading_ones (~(unsigned _BitInt(373)) 512), 373 - 10);
2692+ TEST_COMPARE (stdc_trailing_zeros ((unsigned _BitInt(512)) 0), 512);
2693+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros ((unsigned _BitInt(512)) 0),
2694+ ui), 1);
2695+ TEST_COMPARE (stdc_trailing_zeros ((unsigned _BitInt(373)) 0), 373);
2696+ TEST_COMPARE (expr_has_type (stdc_trailing_zeros ((unsigned _BitInt(373)) 0),
2697+ ui), 1);
2698+ TEST_COMPARE (stdc_trailing_zeros (~(unsigned _BitInt(512)) 0), 0);
2699+ TEST_COMPARE (stdc_trailing_zeros (~(unsigned _BitInt(373)) 0), 0);
2700+ TEST_COMPARE (stdc_trailing_zeros ((unsigned _BitInt(512)) 256), 8);
2701+ TEST_COMPARE (stdc_trailing_zeros ((unsigned _BitInt(373)) 512), 9);
2702+ TEST_COMPARE (stdc_trailing_ones ((unsigned _BitInt(512)) 0), 0);
2703+ TEST_COMPARE (expr_has_type (stdc_trailing_ones ((unsigned _BitInt(512)) 0),
2704+ ui), 1);
2705+ TEST_COMPARE (stdc_trailing_ones ((unsigned _BitInt(373)) 0), 0);
2706+ TEST_COMPARE (expr_has_type (stdc_trailing_ones ((unsigned _BitInt(373)) 0),
2707+ ui), 1);
2708+ TEST_COMPARE (stdc_trailing_ones (~(unsigned _BitInt(512)) 0), 512);
2709+ TEST_COMPARE (stdc_trailing_ones (~(unsigned _BitInt(373)) 0), 373);
2710+ TEST_COMPARE (stdc_trailing_ones ((unsigned _BitInt(512)) 255), 8);
2711+ TEST_COMPARE (stdc_trailing_ones ((~(unsigned _BitInt(373)) 0) >> 2),
2712+ 373 - 2);
2713+ TEST_COMPARE (stdc_first_leading_zero ((unsigned _BitInt(512)) 0), 1);
2714+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero ((unsigned _BitInt(512))
2715+ 0), ui), 1);
2716+ TEST_COMPARE (stdc_first_leading_zero ((unsigned _BitInt(373)) 0), 1);
2717+ TEST_COMPARE (expr_has_type (stdc_first_leading_zero ((unsigned _BitInt(373))
2718+ 0), ui), 1);
2719+ TEST_COMPARE (stdc_first_leading_zero (~(unsigned _BitInt(512)) 0), 0);
2720+ TEST_COMPARE (stdc_first_leading_zero (~(unsigned _BitInt(373)) 0), 0);
2721+ TEST_COMPARE (stdc_first_leading_zero (~(unsigned _BitInt(512)) 511),
2722+ 512 - 8);
2723+ TEST_COMPARE (stdc_first_leading_zero (~(unsigned _BitInt(373)) 1023),
2724+ 373 - 9);
2725+ TEST_COMPARE (stdc_first_leading_one ((unsigned _BitInt(512)) 0), 0);
2726+ TEST_COMPARE (expr_has_type (stdc_first_leading_one ((unsigned _BitInt(512))
2727+ 0), ui), 1);
2728+ TEST_COMPARE (stdc_first_leading_one ((unsigned _BitInt(373)) 0), 0);
2729+ TEST_COMPARE (expr_has_type (stdc_first_leading_one ((unsigned _BitInt(373))
2730+ 0), ui), 1);
2731+ TEST_COMPARE (stdc_first_leading_one (~(unsigned _BitInt(512)) 0), 1);
2732+ TEST_COMPARE (stdc_first_leading_one (~(unsigned _BitInt(373)) 0), 1);
2733+ TEST_COMPARE (stdc_first_leading_one ((unsigned _BitInt(512)) 275), 512 - 8);
2734+ TEST_COMPARE (stdc_first_leading_one ((unsigned _BitInt(373)) 512), 373 - 9);
2735+ TEST_COMPARE (stdc_first_trailing_zero ((unsigned _BitInt(512)) 0), 1);
2736+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero ((unsigned
2737+ _BitInt(512)) 0),
2738+ ui), 1);
2739+ TEST_COMPARE (stdc_first_trailing_zero ((unsigned _BitInt(373)) 0), 1);
2740+ TEST_COMPARE (expr_has_type (stdc_first_trailing_zero ((unsigned
2741+ _BitInt(373)) 0),
2742+ ui), 1);
2743+ TEST_COMPARE (stdc_first_trailing_zero (~(unsigned _BitInt(512)) 0), 0);
2744+ TEST_COMPARE (stdc_first_trailing_zero (~(unsigned _BitInt(373)) 0), 0);
2745+ TEST_COMPARE (stdc_first_trailing_zero ((unsigned _BitInt(512)) 255), 9);
2746+ TEST_COMPARE (stdc_first_trailing_zero ((unsigned _BitInt(373)) 511), 10);
2747+ TEST_COMPARE (stdc_first_trailing_one ((unsigned _BitInt(512)) 0), 0);
2748+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one ((unsigned _BitInt(512))
2749+ 0), ui), 1);
2750+ TEST_COMPARE (stdc_first_trailing_one ((unsigned _BitInt(373)) 0), 0);
2751+ TEST_COMPARE (expr_has_type (stdc_first_trailing_one ((unsigned _BitInt(373))
2752+ 0), ui), 1);
2753+ TEST_COMPARE (stdc_first_trailing_one (~(unsigned _BitInt(512)) 0), 1);
2754+ TEST_COMPARE (stdc_first_trailing_one (~(unsigned _BitInt(373)) 0), 1);
2755+ TEST_COMPARE (stdc_first_trailing_one (((unsigned _BitInt(512)) 255) << 175),
2756+ 176);
2757+ TEST_COMPARE (stdc_first_trailing_one ((~(unsigned _BitInt(373)) 0) << 311),
2758+ 312);
2759+ TEST_COMPARE (stdc_count_zeros ((unsigned _BitInt(512)) 0), 512);
2760+ TEST_COMPARE (expr_has_type (stdc_count_zeros ((unsigned _BitInt(512)) 0),
2761+ ui), 1);
2762+ TEST_COMPARE (stdc_count_zeros ((unsigned _BitInt(373)) 0), 373);
2763+ TEST_COMPARE (expr_has_type (stdc_count_zeros ((unsigned _BitInt(373)) 0),
2764+ ui), 1);
2765+ TEST_COMPARE (stdc_count_zeros (~(unsigned _BitInt(512)) 0), 0);
2766+ TEST_COMPARE (stdc_count_zeros (~(unsigned _BitInt(373)) 0), 0);
2767+ TEST_COMPARE (stdc_count_zeros ((unsigned _BitInt(512)) 1315), 512 - 5);
2768+ TEST_COMPARE (stdc_count_zeros ((unsigned _BitInt(373)) 3363), 373 - 6);
2769+ TEST_COMPARE (stdc_count_ones ((unsigned _BitInt(512)) 0), 0);
2770+ TEST_COMPARE (expr_has_type (stdc_count_ones ((unsigned _BitInt(512)) 0),
2771+ ui), 1);
2772+ TEST_COMPARE (stdc_count_ones ((unsigned _BitInt(373)) 0), 0);
2773+ TEST_COMPARE (expr_has_type (stdc_count_ones ((unsigned _BitInt(373)) 0),
2774+ ui), 1);
2775+ TEST_COMPARE (stdc_count_ones (~(unsigned _BitInt(512)) 0), 512);
2776+ TEST_COMPARE (stdc_count_ones (~(unsigned _BitInt(373)) 0), 373);
2777+ TEST_COMPARE (stdc_count_ones (~(unsigned _BitInt(512)) 1315), 512 - 5);
2778+ TEST_COMPARE (stdc_count_ones (~(unsigned _BitInt(373)) 3363), 373 - 6);
2779+ TEST_COMPARE (stdc_has_single_bit ((unsigned _BitInt(512)) 0), 0);
2780+ TEST_COMPARE (expr_has_type (stdc_has_single_bit ((unsigned _BitInt(512)) 0),
2781+ _Bool), 1);
2782+ TEST_COMPARE (stdc_has_single_bit ((unsigned _BitInt(373)) 0), 0);
2783+ TEST_COMPARE (expr_has_type (stdc_has_single_bit ((unsigned _BitInt(373)) 0),
2784+ _Bool), 1);
2785+ TEST_COMPARE (stdc_has_single_bit (~(unsigned _BitInt(512)) 0), 0);
2786+ TEST_COMPARE (stdc_has_single_bit (~(unsigned _BitInt(373)) 0), 0);
2787+ TEST_COMPARE (stdc_has_single_bit (((unsigned _BitInt(512)) 1022) << 279),
2788+ 0);
2789+ TEST_COMPARE (stdc_has_single_bit (((unsigned _BitInt(373)) 12) << 305), 0);
2790+ TEST_COMPARE (stdc_bit_width ((unsigned _BitInt(512)) 0), 0);
2791+ TEST_COMPARE (expr_has_type (stdc_bit_width ((unsigned _BitInt(512)) 0),
2792+ ui), 1);
2793+ TEST_COMPARE (stdc_bit_width ((unsigned _BitInt(373)) 0), 0);
2794+ TEST_COMPARE (expr_has_type (stdc_bit_width ((unsigned _BitInt(373)) 0),
2795+ ui), 1);
2796+ TEST_COMPARE (stdc_bit_width (~(unsigned _BitInt(512)) 0), 512);
2797+ TEST_COMPARE (stdc_bit_width (~(unsigned _BitInt(373)) 0), 373);
2798+ TEST_COMPARE (stdc_bit_width (((unsigned _BitInt(512)) 1023) << 405),
2799+ 405 + 10);
2800+ TEST_COMPARE (stdc_bit_width (((unsigned _BitInt(373)) 1024) << 242),
2801+ 242 + 11);
2802+ TEST_COMPARE (stdc_bit_floor ((unsigned _BitInt(512)) 0) != 0, 0);
2803+ TEST_COMPARE (expr_has_type (stdc_bit_floor ((unsigned _BitInt(512)) 0),
2804+ unsigned _BitInt(512)), 1);
2805+ TEST_COMPARE (stdc_bit_floor ((unsigned _BitInt(373)) 0) != 0, 0);
2806+ TEST_COMPARE (expr_has_type (stdc_bit_floor ((unsigned _BitInt(373)) 0),
2807+ unsigned _BitInt(373)), 1);
2808+ TEST_COMPARE (stdc_bit_floor (~(unsigned _BitInt(512)) 0)
2809+ != ((unsigned _BitInt(512)) 1) << (512 - 1), 0);
2810+ TEST_COMPARE (stdc_bit_floor (~(unsigned _BitInt(373)) 0)
2811+ != ((unsigned _BitInt(373)) 1) << (373 - 1), 0);
2812+ TEST_COMPARE (stdc_bit_floor (((unsigned _BitInt(512)) 511) << 405)
2813+ != (((unsigned _BitInt(512)) 256) << 405), 0);
2814+ TEST_COMPARE (stdc_bit_floor (((unsigned _BitInt(373)) 512) << 242)
2815+ != (((unsigned _BitInt(512)) 512) << 242), 0);
2816+ TEST_COMPARE (stdc_bit_ceil ((unsigned _BitInt(512)) 0) != 1, 0);
2817+ TEST_COMPARE (expr_has_type (stdc_bit_ceil ((unsigned _BitInt(512)) 0),
2818+ unsigned _BitInt(512)), 1);
2819+ TEST_COMPARE (stdc_bit_ceil ((unsigned _BitInt(373)) 0) != 1, 0);
2820+ TEST_COMPARE (expr_has_type (stdc_bit_ceil ((unsigned _BitInt(373)) 0),
2821+ unsigned _BitInt(373)), 1);
2822+ TEST_COMPARE (stdc_bit_ceil (~(unsigned _BitInt(512)) 0) != 0, 0);
2823+ TEST_COMPARE (stdc_bit_ceil (~(unsigned _BitInt(373)) 0) != 0, 0);
2824+ TEST_COMPARE (stdc_bit_ceil (((unsigned _BitInt(512)) 1) << (512 - 1))
2825+ != ((unsigned _BitInt(512)) 1) << (512 - 1), 0);
2826+ TEST_COMPARE (stdc_bit_ceil ((~(unsigned _BitInt(373)) 0) >> 1)
2827+ != ((unsigned _BitInt(373)) 1) << (373 - 1), 0);
2828+ TEST_COMPARE (stdc_bit_ceil (((unsigned _BitInt(512)) 512) << 405)
2829+ != (((unsigned _BitInt(512)) 512) << 405), 0);
2830+ TEST_COMPARE (stdc_bit_ceil (((unsigned _BitInt(373)) 513) << 242)
2831+ != (((unsigned _BitInt(512)) 1024) << 242), 0);
2832+ TEST_COMPARE (stdc_bit_floor ((unsigned _BitInt(BITINT_MAXWIDTH)) 0) != 0,
2833+ 0);
2834+ TEST_COMPARE (stdc_bit_floor (~(unsigned _BitInt(BITINT_MAXWIDTH)) 0)
2835+ != ((unsigned _BitInt(BITINT_MAXWIDTH)) 1) << (BITINT_MAXWIDTH
2836+ - 1), 0);
2837+ TEST_COMPARE (stdc_bit_floor (((unsigned _BitInt(BITINT_MAXWIDTH)) 511)
2838+ << 405)
2839+ != (((unsigned _BitInt(BITINT_MAXWIDTH)) 256) << 405), 0);
2840+ TEST_COMPARE (stdc_bit_floor (((unsigned _BitInt(BITINT_MAXWIDTH)) 512)
2841+ << 405)
2842+ != (((unsigned _BitInt(BITINT_MAXWIDTH)) 512) << 405), 0);
2843+ TEST_COMPARE (stdc_bit_ceil ((unsigned _BitInt(BITINT_MAXWIDTH)) 0) != 1, 0);
2844+ TEST_COMPARE (stdc_bit_ceil (~(unsigned _BitInt(BITINT_MAXWIDTH)) 0) != 0,
2845+ 0);
2846+ TEST_COMPARE (stdc_bit_ceil (((unsigned _BitInt(BITINT_MAXWIDTH)) 1)
2847+ << (BITINT_MAXWIDTH - 1))
2848+ != ((unsigned _BitInt(BITINT_MAXWIDTH)) 1) << (BITINT_MAXWIDTH
2849+ - 1), 0);
2850+ TEST_COMPARE (stdc_bit_ceil (((unsigned _BitInt(BITINT_MAXWIDTH)) 512)
2851+ << 405)
2852+ != (((unsigned _BitInt(BITINT_MAXWIDTH)) 512) << 405), 0);
2853+ TEST_COMPARE (stdc_bit_ceil (((unsigned _BitInt(BITINT_MAXWIDTH)) 513)
2854+ << 405)
2855+ != (((unsigned _BitInt(BITINT_MAXWIDTH)) 1024) << 405), 0);
2856+# endif
2857+# endif
2858+ return 0;
2859+}
2860+#else
2861+static int
2862+do_test (void)
2863+{
2864+ return 0;
2865+}
2866+#endif
2867+
2868+#include <support/test-driver.c>
2869diff --git a/support/Makefile b/support/Makefile
2870index 362a51f882..aa57207bdc 100644
2871--- a/support/Makefile
2872+++ b/support/Makefile
2873@@ -131,6 +131,7 @@ libsupport-routines = \
2874 xfreopen \
2875 xftruncate \
2876 xgetline \
2877+ xgetpeername \
2878 xgetsockname \
2879 xlisten \
2880 xlseek \
2881diff --git a/support/xgetpeername.c b/support/xgetpeername.c
2882new file mode 100644
2883index 0000000000..6f448e456a
2884--- /dev/null
2885+++ b/support/xgetpeername.c
2886@@ -0,0 +1,30 @@
2887+/* getpeername with error checking.
2888+ Copyright (C) 2024 Free Software Foundation, Inc.
2889+ This file is part of the GNU C Library.
2890+
2891+ The GNU C Library is free software; you can redistribute it and/or
2892+ modify it under the terms of the GNU Lesser General Public
2893+ License as published by the Free Software Foundation; either
2894+ version 2.1 of the License, or (at your option) any later version.
2895+
2896+ The GNU C Library is distributed in the hope that it will be useful,
2897+ but WITHOUT ANY WARRANTY; without even the implied warranty of
2898+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2899+ Lesser General Public License for more details.
2900+
2901+ You should have received a copy of the GNU Lesser General Public
2902+ License along with the GNU C Library; if not, see
2903+ <https://www.gnu.org/licenses/>. */
2904+
2905+#include <support/xsocket.h>
2906+
2907+#include <stdio.h>
2908+#include <stdlib.h>
2909+#include <support/check.h>
2910+
2911+void
2912+xgetpeername (int fd, struct sockaddr *sa, socklen_t *plen)
2913+{
2914+ if (getpeername (fd, sa, plen) != 0)
2915+ FAIL_EXIT1 ("getpeername (%d): %m", fd);
2916+}
2917diff --git a/support/xsocket.h b/support/xsocket.h
2918index 3e44103546..4ac0e1f5ff 100644
2919--- a/support/xsocket.h
2920+++ b/support/xsocket.h
2921@@ -26,6 +26,7 @@
2922 int xsocket (int, int, int);
2923 void xsetsockopt (int, int, int, const void *, socklen_t);
2924 void xgetsockname (int, struct sockaddr *, socklen_t *);
2925+void xgetpeername (int, struct sockaddr *, socklen_t *);
2926 void xconnect (int, const struct sockaddr *, socklen_t);
2927 void xbind (int, const struct sockaddr *, socklen_t);
2928 void xlisten (int, int);
2929diff --git a/sysdeps/aarch64/configure b/sysdeps/aarch64/configure
2930old mode 100644
2931new mode 100755
2932index ca57edce47..9606137e8d
2933--- a/sysdeps/aarch64/configure
2934+++ b/sysdeps/aarch64/configure
2935@@ -325,9 +325,10 @@ then :
2936 printf %s "(cached) " >&6
2937 else $as_nop
2938 cat > conftest.s <<\EOF
2939- ptrue p0.b
2940+ .arch armv8.2-a+sve
2941+ ptrue p0.b
2942 EOF
2943-if { ac_try='${CC-cc} -c -march=armv8.2-a+sve conftest.s 1>&5'
2944+if { ac_try='${CC-cc} -c conftest.s 1>&5'
2945 { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
2946 (eval $ac_try) 2>&5
2947 ac_status=$?
2948diff --git a/sysdeps/aarch64/configure.ac b/sysdeps/aarch64/configure.ac
2949index 27874eceb4..56d12d661d 100644
2950--- a/sysdeps/aarch64/configure.ac
2951+++ b/sysdeps/aarch64/configure.ac
2952@@ -90,9 +90,10 @@ LIBC_CONFIG_VAR([aarch64-variant-pcs], [$libc_cv_aarch64_variant_pcs])
2953 # Check if asm support armv8.2-a+sve
2954 AC_CACHE_CHECK([for SVE support in assembler], [libc_cv_aarch64_sve_asm], [dnl
2955 cat > conftest.s <<\EOF
2956- ptrue p0.b
2957+ .arch armv8.2-a+sve
2958+ ptrue p0.b
2959 EOF
2960-if AC_TRY_COMMAND(${CC-cc} -c -march=armv8.2-a+sve conftest.s 1>&AS_MESSAGE_LOG_FD); then
2961+if AC_TRY_COMMAND(${CC-cc} -c conftest.s 1>&AS_MESSAGE_LOG_FD); then
2962 libc_cv_aarch64_sve_asm=yes
2963 else
2964 libc_cv_aarch64_sve_asm=no
2965diff --git a/sysdeps/aarch64/cpu-features.h b/sysdeps/aarch64/cpu-features.h
2966index 77a782422a..5f2da91ebb 100644
2967--- a/sysdeps/aarch64/cpu-features.h
2968+++ b/sysdeps/aarch64/cpu-features.h
2969@@ -71,6 +71,7 @@ struct cpu_features
2970 /* Currently, the GLIBC memory tagging tunable only defines 8 bits. */
2971 uint8_t mte_state;
2972 bool sve;
2973+ bool prefer_sve_ifuncs;
2974 bool mops;
2975 };
2976
2977diff --git a/sysdeps/aarch64/fpu/acos_advsimd.c b/sysdeps/aarch64/fpu/acos_advsimd.c
2978index a8eabb5e71..0a86c9823a 100644
2979--- a/sysdeps/aarch64/fpu/acos_advsimd.c
2980+++ b/sysdeps/aarch64/fpu/acos_advsimd.c
2981@@ -40,8 +40,8 @@ static const struct data
2982 };
2983
2984 #define AllMask v_u64 (0xffffffffffffffff)
2985-#define Oneu (0x3ff0000000000000)
2986-#define Small (0x3e50000000000000) /* 2^-53. */
2987+#define Oneu 0x3ff0000000000000
2988+#define Small 0x3e50000000000000 /* 2^-53. */
2989
2990 #if WANT_SIMD_EXCEPT
2991 static float64x2_t VPCS_ATTR NOINLINE
2992diff --git a/sysdeps/aarch64/fpu/asin_advsimd.c b/sysdeps/aarch64/fpu/asin_advsimd.c
2993index 141646e954..2de6eff407 100644
2994--- a/sysdeps/aarch64/fpu/asin_advsimd.c
2995+++ b/sysdeps/aarch64/fpu/asin_advsimd.c
2996@@ -39,8 +39,8 @@ static const struct data
2997 };
2998
2999 #define AllMask v_u64 (0xffffffffffffffff)
3000-#define One (0x3ff0000000000000)
3001-#define Small (0x3e50000000000000) /* 2^-12. */
3002+#define One 0x3ff0000000000000
3003+#define Small 0x3e50000000000000 /* 2^-12. */
3004
3005 #if WANT_SIMD_EXCEPT
3006 static float64x2_t VPCS_ATTR NOINLINE
3007diff --git a/sysdeps/aarch64/fpu/atan2_sve.c b/sysdeps/aarch64/fpu/atan2_sve.c
3008index 09a4c559b8..04fa71fa37 100644
3009--- a/sysdeps/aarch64/fpu/atan2_sve.c
3010+++ b/sysdeps/aarch64/fpu/atan2_sve.c
3011@@ -37,9 +37,6 @@ static const struct data
3012 .pi_over_2 = 0x1.921fb54442d18p+0,
3013 };
3014
3015-/* Useful constants. */
3016-#define SignMask sv_u64 (0x8000000000000000)
3017-
3018 /* Special cases i.e. 0, infinity, nan (fall back to scalar calls). */
3019 static svfloat64_t NOINLINE
3020 special_case (svfloat64_t y, svfloat64_t x, svfloat64_t ret,
3021@@ -72,14 +69,15 @@ svfloat64_t SV_NAME_D2 (atan2) (svfloat64_t y, svfloat64_t x, const svbool_t pg)
3022 svbool_t cmp_y = zeroinfnan (iy, pg);
3023 svbool_t cmp_xy = svorr_z (pg, cmp_x, cmp_y);
3024
3025- svuint64_t sign_x = svand_x (pg, ix, SignMask);
3026- svuint64_t sign_y = svand_x (pg, iy, SignMask);
3027- svuint64_t sign_xy = sveor_x (pg, sign_x, sign_y);
3028-
3029 svfloat64_t ax = svabs_x (pg, x);
3030 svfloat64_t ay = svabs_x (pg, y);
3031+ svuint64_t iax = svreinterpret_u64 (ax);
3032+ svuint64_t iay = svreinterpret_u64 (ay);
3033+
3034+ svuint64_t sign_x = sveor_x (pg, ix, iax);
3035+ svuint64_t sign_y = sveor_x (pg, iy, iay);
3036+ svuint64_t sign_xy = sveor_x (pg, sign_x, sign_y);
3037
3038- svbool_t pred_xlt0 = svcmplt (pg, x, 0.0);
3039 svbool_t pred_aygtax = svcmpgt (pg, ay, ax);
3040
3041 /* Set up z for call to atan. */
3042@@ -88,8 +86,9 @@ svfloat64_t SV_NAME_D2 (atan2) (svfloat64_t y, svfloat64_t x, const svbool_t pg)
3043 svfloat64_t z = svdiv_x (pg, n, d);
3044
3045 /* Work out the correct shift. */
3046- svfloat64_t shift = svsel (pred_xlt0, sv_f64 (-2.0), sv_f64 (0.0));
3047- shift = svsel (pred_aygtax, svadd_x (pg, shift, 1.0), shift);
3048+ svfloat64_t shift = svreinterpret_f64 (svlsr_x (pg, sign_x, 1));
3049+ shift = svsel (pred_aygtax, sv_f64 (1.0), shift);
3050+ shift = svreinterpret_f64 (svorr_x (pg, sign_x, svreinterpret_u64 (shift)));
3051 shift = svmul_x (pg, shift, data_ptr->pi_over_2);
3052
3053 /* Use split Estrin scheme for P(z^2) with deg(P)=19. */
3054@@ -109,10 +108,10 @@ svfloat64_t SV_NAME_D2 (atan2) (svfloat64_t y, svfloat64_t x, const svbool_t pg)
3055 ret = svadd_m (pg, ret, shift);
3056
3057 /* Account for the sign of x and y. */
3058- ret = svreinterpret_f64 (sveor_x (pg, svreinterpret_u64 (ret), sign_xy));
3059-
3060 if (__glibc_unlikely (svptest_any (pg, cmp_xy)))
3061- return special_case (y, x, ret, cmp_xy);
3062-
3063- return ret;
3064+ return special_case (
3065+ y, x,
3066+ svreinterpret_f64 (sveor_x (pg, svreinterpret_u64 (ret), sign_xy)),
3067+ cmp_xy);
3068+ return svreinterpret_f64 (sveor_x (pg, svreinterpret_u64 (ret), sign_xy));
3069 }
3070diff --git a/sysdeps/aarch64/fpu/atan2f_sve.c b/sysdeps/aarch64/fpu/atan2f_sve.c
3071index b92f83cdea..9ea197147c 100644
3072--- a/sysdeps/aarch64/fpu/atan2f_sve.c
3073+++ b/sysdeps/aarch64/fpu/atan2f_sve.c
3074@@ -32,10 +32,8 @@ static const struct data
3075 .pi_over_2 = 0x1.921fb6p+0f,
3076 };
3077
3078-#define SignMask sv_u32 (0x80000000)
3079-
3080 /* Special cases i.e. 0, infinity, nan (fall back to scalar calls). */
3081-static inline svfloat32_t
3082+static svfloat32_t NOINLINE
3083 special_case (svfloat32_t y, svfloat32_t x, svfloat32_t ret,
3084 const svbool_t cmp)
3085 {
3086@@ -67,14 +65,15 @@ svfloat32_t SV_NAME_F2 (atan2) (svfloat32_t y, svfloat32_t x, const svbool_t pg)
3087 svbool_t cmp_y = zeroinfnan (iy, pg);
3088 svbool_t cmp_xy = svorr_z (pg, cmp_x, cmp_y);
3089
3090- svuint32_t sign_x = svand_x (pg, ix, SignMask);
3091- svuint32_t sign_y = svand_x (pg, iy, SignMask);
3092- svuint32_t sign_xy = sveor_x (pg, sign_x, sign_y);
3093-
3094 svfloat32_t ax = svabs_x (pg, x);
3095 svfloat32_t ay = svabs_x (pg, y);
3096+ svuint32_t iax = svreinterpret_u32 (ax);
3097+ svuint32_t iay = svreinterpret_u32 (ay);
3098+
3099+ svuint32_t sign_x = sveor_x (pg, ix, iax);
3100+ svuint32_t sign_y = sveor_x (pg, iy, iay);
3101+ svuint32_t sign_xy = sveor_x (pg, sign_x, sign_y);
3102
3103- svbool_t pred_xlt0 = svcmplt (pg, x, 0.0);
3104 svbool_t pred_aygtax = svcmpgt (pg, ay, ax);
3105
3106 /* Set up z for call to atan. */
3107@@ -83,11 +82,12 @@ svfloat32_t SV_NAME_F2 (atan2) (svfloat32_t y, svfloat32_t x, const svbool_t pg)
3108 svfloat32_t z = svdiv_x (pg, n, d);
3109
3110 /* Work out the correct shift. */
3111- svfloat32_t shift = svsel (pred_xlt0, sv_f32 (-2.0), sv_f32 (0.0));
3112- shift = svsel (pred_aygtax, svadd_x (pg, shift, 1.0), shift);
3113+ svfloat32_t shift = svreinterpret_f32 (svlsr_x (pg, sign_x, 1));
3114+ shift = svsel (pred_aygtax, sv_f32 (1.0), shift);
3115+ shift = svreinterpret_f32 (svorr_x (pg, sign_x, svreinterpret_u32 (shift)));
3116 shift = svmul_x (pg, shift, sv_f32 (data_ptr->pi_over_2));
3117
3118- /* Use split Estrin scheme for P(z^2) with deg(P)=7. */
3119+ /* Use pure Estrin scheme for P(z^2) with deg(P)=7. */
3120 svfloat32_t z2 = svmul_x (pg, z, z);
3121 svfloat32_t z4 = svmul_x (pg, z2, z2);
3122 svfloat32_t z8 = svmul_x (pg, z4, z4);
3123@@ -101,10 +101,12 @@ svfloat32_t SV_NAME_F2 (atan2) (svfloat32_t y, svfloat32_t x, const svbool_t pg)
3124 ret = svadd_m (pg, ret, shift);
3125
3126 /* Account for the sign of x and y. */
3127- ret = svreinterpret_f32 (sveor_x (pg, svreinterpret_u32 (ret), sign_xy));
3128
3129 if (__glibc_unlikely (svptest_any (pg, cmp_xy)))
3130- return special_case (y, x, ret, cmp_xy);
3131+ return special_case (
3132+ y, x,
3133+ svreinterpret_f32 (sveor_x (pg, svreinterpret_u32 (ret), sign_xy)),
3134+ cmp_xy);
3135
3136- return ret;
3137+ return svreinterpret_f32 (sveor_x (pg, svreinterpret_u32 (ret), sign_xy));
3138 }
3139diff --git a/sysdeps/aarch64/fpu/cos_advsimd.c b/sysdeps/aarch64/fpu/cos_advsimd.c
3140index 2897e8b909..3924c9ce44 100644
3141--- a/sysdeps/aarch64/fpu/cos_advsimd.c
3142+++ b/sysdeps/aarch64/fpu/cos_advsimd.c
3143@@ -63,8 +63,7 @@ float64x2_t VPCS_ATTR V_NAME_D1 (cos) (float64x2_t x)
3144 special-case handler later. */
3145 r = vbslq_f64 (cmp, v_f64 (1.0), r);
3146 #else
3147- cmp = vcageq_f64 (d->range_val, x);
3148- cmp = vceqzq_u64 (cmp); /* cmp = ~cmp. */
3149+ cmp = vcageq_f64 (x, d->range_val);
3150 r = x;
3151 #endif
3152
3153diff --git a/sysdeps/aarch64/fpu/cosf_advsimd.c b/sysdeps/aarch64/fpu/cosf_advsimd.c
3154index 60abc8dfcf..d0c285b03a 100644
3155--- a/sysdeps/aarch64/fpu/cosf_advsimd.c
3156+++ b/sysdeps/aarch64/fpu/cosf_advsimd.c
3157@@ -64,8 +64,7 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (cos) (float32x4_t x)
3158 special-case handler later. */
3159 r = vbslq_f32 (cmp, v_f32 (1.0f), r);
3160 #else
3161- cmp = vcageq_f32 (d->range_val, x);
3162- cmp = vceqzq_u32 (cmp); /* cmp = ~cmp. */
3163+ cmp = vcageq_f32 (x, d->range_val);
3164 r = x;
3165 #endif
3166
3167diff --git a/sysdeps/aarch64/fpu/exp10_advsimd.c b/sysdeps/aarch64/fpu/exp10_advsimd.c
3168index fe7149b191..eeb31ca839 100644
3169--- a/sysdeps/aarch64/fpu/exp10_advsimd.c
3170+++ b/sysdeps/aarch64/fpu/exp10_advsimd.c
3171@@ -57,7 +57,7 @@ const static struct data
3172 # define BigBound v_u64 (0x4070000000000000) /* asuint64 (0x1p8). */
3173 # define Thres v_u64 (0x2070000000000000) /* BigBound - TinyBound. */
3174
3175-static inline float64x2_t VPCS_ATTR
3176+static float64x2_t VPCS_ATTR NOINLINE
3177 special_case (float64x2_t x, float64x2_t y, uint64x2_t cmp)
3178 {
3179 /* If fenv exceptions are to be triggered correctly, fall back to the scalar
3180@@ -72,7 +72,7 @@ special_case (float64x2_t x, float64x2_t y, uint64x2_t cmp)
3181 # define SpecialBias1 v_u64 (0x7000000000000000) /* 0x1p769. */
3182 # define SpecialBias2 v_u64 (0x3010000000000000) /* 0x1p-254. */
3183
3184-static float64x2_t VPCS_ATTR NOINLINE
3185+static inline float64x2_t VPCS_ATTR
3186 special_case (float64x2_t s, float64x2_t y, float64x2_t n,
3187 const struct data *d)
3188 {
3189diff --git a/sysdeps/aarch64/fpu/exp10f_advsimd.c b/sysdeps/aarch64/fpu/exp10f_advsimd.c
3190index 7ee0c90948..ab117b69da 100644
3191--- a/sysdeps/aarch64/fpu/exp10f_advsimd.c
3192+++ b/sysdeps/aarch64/fpu/exp10f_advsimd.c
3193@@ -25,7 +25,8 @@
3194 static const struct data
3195 {
3196 float32x4_t poly[5];
3197- float32x4_t shift, log10_2, log2_10_hi, log2_10_lo;
3198+ float32x4_t log10_2_and_inv, shift;
3199+
3200 #if !WANT_SIMD_EXCEPT
3201 float32x4_t scale_thresh;
3202 #endif
3203@@ -38,9 +39,9 @@ static const struct data
3204 .poly = { V4 (0x1.26bb16p+1f), V4 (0x1.5350d2p+1f), V4 (0x1.04744ap+1f),
3205 V4 (0x1.2d8176p+0f), V4 (0x1.12b41ap-1f) },
3206 .shift = V4 (0x1.8p23f),
3207- .log10_2 = V4 (0x1.a934fp+1),
3208- .log2_10_hi = V4 (0x1.344136p-2),
3209- .log2_10_lo = V4 (-0x1.ec10cp-27),
3210+
3211+ /* Stores constants 1/log10(2), log10(2)_high, log10(2)_low, 0. */
3212+ .log10_2_and_inv = { 0x1.a934fp+1, 0x1.344136p-2, -0x1.ec10cp-27, 0 },
3213 #if !WANT_SIMD_EXCEPT
3214 .scale_thresh = V4 (ScaleBound)
3215 #endif
3216@@ -98,24 +99,22 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (exp10) (float32x4_t x)
3217 #if WANT_SIMD_EXCEPT
3218 /* asuint(x) - TinyBound >= BigBound - TinyBound. */
3219 uint32x4_t cmp = vcgeq_u32 (
3220- vsubq_u32 (vandq_u32 (vreinterpretq_u32_f32 (x), v_u32 (0x7fffffff)),
3221- TinyBound),
3222- Thres);
3223+ vsubq_u32 (vreinterpretq_u32_f32 (vabsq_f32 (x)), TinyBound), Thres);
3224 float32x4_t xm = x;
3225 /* If any lanes are special, mask them with 1 and retain a copy of x to allow
3226 special case handler to fix special lanes later. This is only necessary if
3227 fenv exceptions are to be triggered correctly. */
3228 if (__glibc_unlikely (v_any_u32 (cmp)))
3229- x = vbslq_f32 (cmp, v_f32 (1), x);
3230+ x = v_zerofy_f32 (x, cmp);
3231 #endif
3232
3233 /* exp10(x) = 2^n * 10^r = 2^n * (1 + poly (r)),
3234 with poly(r) in [1/sqrt(2), sqrt(2)] and
3235 x = r + n * log10 (2), with r in [-log10(2)/2, log10(2)/2]. */
3236- float32x4_t z = vfmaq_f32 (d->shift, x, d->log10_2);
3237+ float32x4_t z = vfmaq_laneq_f32 (d->shift, x, d->log10_2_and_inv, 0);
3238 float32x4_t n = vsubq_f32 (z, d->shift);
3239- float32x4_t r = vfmsq_f32 (x, n, d->log2_10_hi);
3240- r = vfmsq_f32 (r, n, d->log2_10_lo);
3241+ float32x4_t r = vfmsq_laneq_f32 (x, n, d->log10_2_and_inv, 1);
3242+ r = vfmsq_laneq_f32 (r, n, d->log10_2_and_inv, 2);
3243 uint32x4_t e = vshlq_n_u32 (vreinterpretq_u32_f32 (z), 23);
3244
3245 float32x4_t scale = vreinterpretq_f32_u32 (vaddq_u32 (e, ExponentBias));
3246diff --git a/sysdeps/aarch64/fpu/exp2_advsimd.c b/sysdeps/aarch64/fpu/exp2_advsimd.c
3247index 391a93180c..ae1e63d503 100644
3248--- a/sysdeps/aarch64/fpu/exp2_advsimd.c
3249+++ b/sysdeps/aarch64/fpu/exp2_advsimd.c
3250@@ -24,6 +24,7 @@
3251 #define IndexMask (N - 1)
3252 #define BigBound 1022.0
3253 #define UOFlowBound 1280.0
3254+#define TinyBound 0x2000000000000000 /* asuint64(0x1p-511). */
3255
3256 static const struct data
3257 {
3258@@ -48,14 +49,13 @@ lookup_sbits (uint64x2_t i)
3259
3260 #if WANT_SIMD_EXCEPT
3261
3262-# define TinyBound 0x2000000000000000 /* asuint64(0x1p-511). */
3263 # define Thres 0x2080000000000000 /* asuint64(512.0) - TinyBound. */
3264
3265 /* Call scalar exp2 as a fallback. */
3266 static float64x2_t VPCS_ATTR NOINLINE
3267-special_case (float64x2_t x)
3268+special_case (float64x2_t x, float64x2_t y, uint64x2_t is_special)
3269 {
3270- return v_call_f64 (exp2, x, x, v_u64 (0xffffffffffffffff));
3271+ return v_call_f64 (exp2, x, y, is_special);
3272 }
3273
3274 #else
3275@@ -65,7 +65,7 @@ special_case (float64x2_t x)
3276 # define SpecialBias1 0x7000000000000000 /* 0x1p769. */
3277 # define SpecialBias2 0x3010000000000000 /* 0x1p-254. */
3278
3279-static float64x2_t VPCS_ATTR
3280+static inline float64x2_t VPCS_ATTR
3281 special_case (float64x2_t s, float64x2_t y, float64x2_t n,
3282 const struct data *d)
3283 {
3284@@ -94,10 +94,10 @@ float64x2_t V_NAME_D1 (exp2) (float64x2_t x)
3285 #if WANT_SIMD_EXCEPT
3286 uint64x2_t ia = vreinterpretq_u64_f64 (vabsq_f64 (x));
3287 cmp = vcgeq_u64 (vsubq_u64 (ia, v_u64 (TinyBound)), v_u64 (Thres));
3288- /* If any special case (inf, nan, small and large x) is detected,
3289- fall back to scalar for all lanes. */
3290- if (__glibc_unlikely (v_any_u64 (cmp)))
3291- return special_case (x);
3292+ /* Mask special lanes and retain a copy of x for passing to special-case
3293+ handler. */
3294+ float64x2_t xc = x;
3295+ x = v_zerofy_f64 (x, cmp);
3296 #else
3297 cmp = vcagtq_f64 (x, d->scale_big_bound);
3298 #endif
3299@@ -120,9 +120,11 @@ float64x2_t V_NAME_D1 (exp2) (float64x2_t x)
3300 float64x2_t y = v_pairwise_poly_3_f64 (r, r2, d->poly);
3301 y = vmulq_f64 (r, y);
3302
3303-#if !WANT_SIMD_EXCEPT
3304 if (__glibc_unlikely (v_any_u64 (cmp)))
3305+#if !WANT_SIMD_EXCEPT
3306 return special_case (s, y, n, d);
3307+#else
3308+ return special_case (xc, vfmaq_f64 (s, s, y), cmp);
3309 #endif
3310 return vfmaq_f64 (s, s, y);
3311 }
3312diff --git a/sysdeps/aarch64/fpu/exp2f_sve.c b/sysdeps/aarch64/fpu/exp2f_sve.c
3313index 9a5a523a10..8a686e3e05 100644
3314--- a/sysdeps/aarch64/fpu/exp2f_sve.c
3315+++ b/sysdeps/aarch64/fpu/exp2f_sve.c
3316@@ -20,6 +20,8 @@
3317 #include "sv_math.h"
3318 #include "poly_sve_f32.h"
3319
3320+#define Thres 0x1.5d5e2ap+6f
3321+
3322 static const struct data
3323 {
3324 float poly[5];
3325@@ -33,7 +35,7 @@ static const struct data
3326 .shift = 0x1.903f8p17f,
3327 /* Roughly 87.3. For x < -Thres, the result is subnormal and not handled
3328 correctly by FEXPA. */
3329- .thres = 0x1.5d5e2ap+6f,
3330+ .thres = Thres,
3331 };
3332
3333 static svfloat32_t NOINLINE
3334diff --git a/sysdeps/aarch64/fpu/exp_advsimd.c b/sysdeps/aarch64/fpu/exp_advsimd.c
3335index fd215f1d2c..5e3a9a0d44 100644
3336--- a/sysdeps/aarch64/fpu/exp_advsimd.c
3337+++ b/sysdeps/aarch64/fpu/exp_advsimd.c
3338@@ -54,7 +54,7 @@ const static volatile struct
3339 # define BigBound v_u64 (0x4080000000000000) /* asuint64 (0x1p9). */
3340 # define SpecialBound v_u64 (0x2080000000000000) /* BigBound - TinyBound. */
3341
3342-static inline float64x2_t VPCS_ATTR
3343+static float64x2_t VPCS_ATTR NOINLINE
3344 special_case (float64x2_t x, float64x2_t y, uint64x2_t cmp)
3345 {
3346 /* If fenv exceptions are to be triggered correctly, fall back to the scalar
3347@@ -69,7 +69,7 @@ special_case (float64x2_t x, float64x2_t y, uint64x2_t cmp)
3348 # define SpecialBias1 v_u64 (0x7000000000000000) /* 0x1p769. */
3349 # define SpecialBias2 v_u64 (0x3010000000000000) /* 0x1p-254. */
3350
3351-static float64x2_t VPCS_ATTR NOINLINE
3352+static inline float64x2_t VPCS_ATTR
3353 special_case (float64x2_t s, float64x2_t y, float64x2_t n)
3354 {
3355 /* 2^(n/N) may overflow, break it up into s1*s2. */
3356diff --git a/sysdeps/aarch64/fpu/expm1_advsimd.c b/sysdeps/aarch64/fpu/expm1_advsimd.c
3357index 0b85bd06f3..3628398674 100644
3358--- a/sysdeps/aarch64/fpu/expm1_advsimd.c
3359+++ b/sysdeps/aarch64/fpu/expm1_advsimd.c
3360@@ -23,7 +23,7 @@
3361 static const struct data
3362 {
3363 float64x2_t poly[11];
3364- float64x2_t invln2, ln2_lo, ln2_hi, shift;
3365+ float64x2_t invln2, ln2, shift;
3366 int64x2_t exponent_bias;
3367 #if WANT_SIMD_EXCEPT
3368 uint64x2_t thresh, tiny_bound;
3369@@ -38,8 +38,7 @@ static const struct data
3370 V2 (0x1.71ddf82db5bb4p-19), V2 (0x1.27e517fc0d54bp-22),
3371 V2 (0x1.af5eedae67435p-26), V2 (0x1.1f143d060a28ap-29) },
3372 .invln2 = V2 (0x1.71547652b82fep0),
3373- .ln2_hi = V2 (0x1.62e42fefa39efp-1),
3374- .ln2_lo = V2 (0x1.abc9e3b39803fp-56),
3375+ .ln2 = { 0x1.62e42fefa39efp-1, 0x1.abc9e3b39803fp-56 },
3376 .shift = V2 (0x1.8p52),
3377 .exponent_bias = V2 (0x3ff0000000000000),
3378 #if WANT_SIMD_EXCEPT
3379@@ -83,7 +82,7 @@ float64x2_t VPCS_ATTR V_NAME_D1 (expm1) (float64x2_t x)
3380 x = v_zerofy_f64 (x, special);
3381 #else
3382 /* Large input, NaNs and Infs. */
3383- uint64x2_t special = vceqzq_u64 (vcaltq_f64 (x, d->oflow_bound));
3384+ uint64x2_t special = vcageq_f64 (x, d->oflow_bound);
3385 #endif
3386
3387 /* Reduce argument to smaller range:
3388@@ -93,8 +92,8 @@ float64x2_t VPCS_ATTR V_NAME_D1 (expm1) (float64x2_t x)
3389 where 2^i is exact because i is an integer. */
3390 float64x2_t n = vsubq_f64 (vfmaq_f64 (d->shift, d->invln2, x), d->shift);
3391 int64x2_t i = vcvtq_s64_f64 (n);
3392- float64x2_t f = vfmsq_f64 (x, n, d->ln2_hi);
3393- f = vfmsq_f64 (f, n, d->ln2_lo);
3394+ float64x2_t f = vfmsq_laneq_f64 (x, n, d->ln2, 0);
3395+ f = vfmsq_laneq_f64 (f, n, d->ln2, 1);
3396
3397 /* Approximate expm1(f) using polynomial.
3398 Taylor expansion for expm1(x) has the form:
3399diff --git a/sysdeps/aarch64/fpu/expm1f_advsimd.c b/sysdeps/aarch64/fpu/expm1f_advsimd.c
3400index 8d4c9a2193..93db200f61 100644
3401--- a/sysdeps/aarch64/fpu/expm1f_advsimd.c
3402+++ b/sysdeps/aarch64/fpu/expm1f_advsimd.c
3403@@ -23,7 +23,8 @@
3404 static const struct data
3405 {
3406 float32x4_t poly[5];
3407- float32x4_t invln2, ln2_lo, ln2_hi, shift;
3408+ float32x4_t invln2_and_ln2;
3409+ float32x4_t shift;
3410 int32x4_t exponent_bias;
3411 #if WANT_SIMD_EXCEPT
3412 uint32x4_t thresh;
3413@@ -34,9 +35,8 @@ static const struct data
3414 /* Generated using fpminimax with degree=5 in [-log(2)/2, log(2)/2]. */
3415 .poly = { V4 (0x1.fffffep-2), V4 (0x1.5554aep-3), V4 (0x1.555736p-5),
3416 V4 (0x1.12287cp-7), V4 (0x1.6b55a2p-10) },
3417- .invln2 = V4 (0x1.715476p+0f),
3418- .ln2_hi = V4 (0x1.62e4p-1f),
3419- .ln2_lo = V4 (0x1.7f7d1cp-20f),
3420+ /* Stores constants: invln2, ln2_hi, ln2_lo, 0. */
3421+ .invln2_and_ln2 = { 0x1.715476p+0f, 0x1.62e4p-1f, 0x1.7f7d1cp-20f, 0 },
3422 .shift = V4 (0x1.8p23f),
3423 .exponent_bias = V4 (0x3f800000),
3424 #if !WANT_SIMD_EXCEPT
3425@@ -80,7 +80,7 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (expm1) (float32x4_t x)
3426 x = v_zerofy_f32 (x, special);
3427 #else
3428 /* Handles very large values (+ve and -ve), +/-NaN, +/-Inf. */
3429- uint32x4_t special = vceqzq_u32 (vcaltq_f32 (x, d->oflow_bound));
3430+ uint32x4_t special = vcagtq_f32 (x, d->oflow_bound);
3431 #endif
3432
3433 /* Reduce argument to smaller range:
3434@@ -88,10 +88,11 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (expm1) (float32x4_t x)
3435 and f = x - i * ln2, then f is in [-ln2/2, ln2/2].
3436 exp(x) - 1 = 2^i * (expm1(f) + 1) - 1
3437 where 2^i is exact because i is an integer. */
3438- float32x4_t j = vsubq_f32 (vfmaq_f32 (d->shift, d->invln2, x), d->shift);
3439+ float32x4_t j = vsubq_f32 (
3440+ vfmaq_laneq_f32 (d->shift, x, d->invln2_and_ln2, 0), d->shift);
3441 int32x4_t i = vcvtq_s32_f32 (j);
3442- float32x4_t f = vfmsq_f32 (x, j, d->ln2_hi);
3443- f = vfmsq_f32 (f, j, d->ln2_lo);
3444+ float32x4_t f = vfmsq_laneq_f32 (x, j, d->invln2_and_ln2, 1);
3445+ f = vfmsq_laneq_f32 (f, j, d->invln2_and_ln2, 2);
3446
3447 /* Approximate expm1(f) using polynomial.
3448 Taylor expansion for expm1(x) has the form:
3449diff --git a/sysdeps/aarch64/fpu/log_advsimd.c b/sysdeps/aarch64/fpu/log_advsimd.c
3450index 067ae79613..21df61728c 100644
3451--- a/sysdeps/aarch64/fpu/log_advsimd.c
3452+++ b/sysdeps/aarch64/fpu/log_advsimd.c
3453@@ -58,8 +58,13 @@ lookup (uint64x2_t i)
3454 uint64_t i1 = (i[1] >> (52 - V_LOG_TABLE_BITS)) & IndexMask;
3455 float64x2_t e0 = vld1q_f64 (&__v_log_data.table[i0].invc);
3456 float64x2_t e1 = vld1q_f64 (&__v_log_data.table[i1].invc);
3457+#if __BYTE_ORDER == __LITTLE_ENDIAN
3458 e.invc = vuzp1q_f64 (e0, e1);
3459 e.logc = vuzp2q_f64 (e0, e1);
3460+#else
3461+ e.invc = vuzp1q_f64 (e1, e0);
3462+ e.logc = vuzp2q_f64 (e1, e0);
3463+#endif
3464 return e;
3465 }
3466
3467diff --git a/sysdeps/aarch64/fpu/sin_advsimd.c b/sysdeps/aarch64/fpu/sin_advsimd.c
3468index efce183e86..a0d9d3b819 100644
3469--- a/sysdeps/aarch64/fpu/sin_advsimd.c
3470+++ b/sysdeps/aarch64/fpu/sin_advsimd.c
3471@@ -75,8 +75,7 @@ float64x2_t VPCS_ATTR V_NAME_D1 (sin) (float64x2_t x)
3472 r = vbslq_f64 (cmp, vreinterpretq_f64_u64 (cmp), x);
3473 #else
3474 r = x;
3475- cmp = vcageq_f64 (d->range_val, x);
3476- cmp = vceqzq_u64 (cmp); /* cmp = ~cmp. */
3477+ cmp = vcageq_f64 (x, d->range_val);
3478 #endif
3479
3480 /* n = rint(|x|/pi). */
3481diff --git a/sysdeps/aarch64/fpu/sinf_advsimd.c b/sysdeps/aarch64/fpu/sinf_advsimd.c
3482index 60cf3f2ca1..375dfc3331 100644
3483--- a/sysdeps/aarch64/fpu/sinf_advsimd.c
3484+++ b/sysdeps/aarch64/fpu/sinf_advsimd.c
3485@@ -67,8 +67,7 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (sin) (float32x4_t x)
3486 r = vbslq_f32 (cmp, vreinterpretq_f32_u32 (cmp), x);
3487 #else
3488 r = x;
3489- cmp = vcageq_f32 (d->range_val, x);
3490- cmp = vceqzq_u32 (cmp); /* cmp = ~cmp. */
3491+ cmp = vcageq_f32 (x, d->range_val);
3492 #endif
3493
3494 /* n = rint(|x|/pi) */
3495diff --git a/sysdeps/aarch64/fpu/tan_advsimd.c b/sysdeps/aarch64/fpu/tan_advsimd.c
3496index d7e5ba7b1a..0459821ab2 100644
3497--- a/sysdeps/aarch64/fpu/tan_advsimd.c
3498+++ b/sysdeps/aarch64/fpu/tan_advsimd.c
3499@@ -23,7 +23,7 @@
3500 static const struct data
3501 {
3502 float64x2_t poly[9];
3503- float64x2_t half_pi_hi, half_pi_lo, two_over_pi, shift;
3504+ float64x2_t half_pi, two_over_pi, shift;
3505 #if !WANT_SIMD_EXCEPT
3506 float64x2_t range_val;
3507 #endif
3508@@ -34,8 +34,7 @@ static const struct data
3509 V2 (0x1.226e5e5ecdfa3p-7), V2 (0x1.d6c7ddbf87047p-9),
3510 V2 (0x1.7ea75d05b583ep-10), V2 (0x1.289f22964a03cp-11),
3511 V2 (0x1.4e4fd14147622p-12) },
3512- .half_pi_hi = V2 (0x1.921fb54442d18p0),
3513- .half_pi_lo = V2 (0x1.1a62633145c07p-54),
3514+ .half_pi = { 0x1.921fb54442d18p0, 0x1.1a62633145c07p-54 },
3515 .two_over_pi = V2 (0x1.45f306dc9c883p-1),
3516 .shift = V2 (0x1.8p52),
3517 #if !WANT_SIMD_EXCEPT
3518@@ -56,15 +55,15 @@ special_case (float64x2_t x)
3519
3520 /* Vector approximation for double-precision tan.
3521 Maximum measured error is 3.48 ULP:
3522- __v_tan(0x1.4457047ef78d8p+20) got -0x1.f6ccd8ecf7dedp+37
3523- want -0x1.f6ccd8ecf7deap+37. */
3524+ _ZGVnN2v_tan(0x1.4457047ef78d8p+20) got -0x1.f6ccd8ecf7dedp+37
3525+ want -0x1.f6ccd8ecf7deap+37. */
3526 float64x2_t VPCS_ATTR V_NAME_D1 (tan) (float64x2_t x)
3527 {
3528 const struct data *dat = ptr_barrier (&data);
3529- /* Our argument reduction cannot calculate q with sufficient accuracy for very
3530- large inputs. Fall back to scalar routine for all lanes if any are too
3531- large, or Inf/NaN. If fenv exceptions are expected, also fall back for tiny
3532- input to avoid underflow. */
3533+ /* Our argument reduction cannot calculate q with sufficient accuracy for
3534+ very large inputs. Fall back to scalar routine for all lanes if any are
3535+ too large, or Inf/NaN. If fenv exceptions are expected, also fall back for
3536+ tiny input to avoid underflow. */
3537 #if WANT_SIMD_EXCEPT
3538 uint64x2_t iax = vreinterpretq_u64_f64 (vabsq_f64 (x));
3539 /* iax - tiny_bound > range_val - tiny_bound. */
3540@@ -82,8 +81,8 @@ float64x2_t VPCS_ATTR V_NAME_D1 (tan) (float64x2_t x)
3541 /* Use q to reduce x to r in [-pi/4, pi/4], by:
3542 r = x - q * pi/2, in extended precision. */
3543 float64x2_t r = x;
3544- r = vfmsq_f64 (r, q, dat->half_pi_hi);
3545- r = vfmsq_f64 (r, q, dat->half_pi_lo);
3546+ r = vfmsq_laneq_f64 (r, q, dat->half_pi, 0);
3547+ r = vfmsq_laneq_f64 (r, q, dat->half_pi, 1);
3548 /* Further reduce r to [-pi/8, pi/8], to be reconstructed using double angle
3549 formula. */
3550 r = vmulq_n_f64 (r, 0.5);
3551@@ -106,14 +105,15 @@ float64x2_t VPCS_ATTR V_NAME_D1 (tan) (float64x2_t x)
3552 and reciprocity around pi/2:
3553 tan(x) = 1 / (tan(pi/2 - x))
3554 to assemble result using change-of-sign and conditional selection of
3555- numerator/denominator, dependent on odd/even-ness of q (hence quadrant). */
3556+ numerator/denominator, dependent on odd/even-ness of q (hence quadrant).
3557+ */
3558 float64x2_t n = vfmaq_f64 (v_f64 (-1), p, p);
3559 float64x2_t d = vaddq_f64 (p, p);
3560
3561 uint64x2_t no_recip = vtstq_u64 (vreinterpretq_u64_s64 (qi), v_u64 (1));
3562
3563 #if !WANT_SIMD_EXCEPT
3564- uint64x2_t special = vceqzq_u64 (vcaleq_f64 (x, dat->range_val));
3565+ uint64x2_t special = vcageq_f64 (x, dat->range_val);
3566 if (__glibc_unlikely (v_any_u64 (special)))
3567 return special_case (x);
3568 #endif
3569diff --git a/sysdeps/aarch64/fpu/tanf_advsimd.c b/sysdeps/aarch64/fpu/tanf_advsimd.c
3570index 1f16103f8a..5a7489390a 100644
3571--- a/sysdeps/aarch64/fpu/tanf_advsimd.c
3572+++ b/sysdeps/aarch64/fpu/tanf_advsimd.c
3573@@ -23,7 +23,8 @@
3574 static const struct data
3575 {
3576 float32x4_t poly[6];
3577- float32x4_t neg_half_pi_1, neg_half_pi_2, neg_half_pi_3, two_over_pi, shift;
3578+ float32x4_t pi_consts;
3579+ float32x4_t shift;
3580 #if !WANT_SIMD_EXCEPT
3581 float32x4_t range_val;
3582 #endif
3583@@ -31,10 +32,9 @@ static const struct data
3584 /* Coefficients generated using FPMinimax. */
3585 .poly = { V4 (0x1.55555p-2f), V4 (0x1.11166p-3f), V4 (0x1.b88a78p-5f),
3586 V4 (0x1.7b5756p-6f), V4 (0x1.4ef4cep-8f), V4 (0x1.0e1e74p-7f) },
3587- .neg_half_pi_1 = V4 (-0x1.921fb6p+0f),
3588- .neg_half_pi_2 = V4 (0x1.777a5cp-25f),
3589- .neg_half_pi_3 = V4 (0x1.ee59dap-50f),
3590- .two_over_pi = V4 (0x1.45f306p-1f),
3591+ /* Stores constants: (-pi/2)_high, (-pi/2)_mid, (-pi/2)_low, and 2/pi. */
3592+ .pi_consts
3593+ = { -0x1.921fb6p+0f, 0x1.777a5cp-25f, 0x1.ee59dap-50f, 0x1.45f306p-1f },
3594 .shift = V4 (0x1.8p+23f),
3595 #if !WANT_SIMD_EXCEPT
3596 .range_val = V4 (0x1p15f),
3597@@ -58,10 +58,11 @@ eval_poly (float32x4_t z, const struct data *d)
3598 {
3599 float32x4_t z2 = vmulq_f32 (z, z);
3600 #if WANT_SIMD_EXCEPT
3601- /* Tiny z (<= 0x1p-31) will underflow when calculating z^4. If fp exceptions
3602- are to be triggered correctly, sidestep this by fixing such lanes to 0. */
3603+ /* Tiny z (<= 0x1p-31) will underflow when calculating z^4.
3604+ If fp exceptions are to be triggered correctly,
3605+ sidestep this by fixing such lanes to 0. */
3606 uint32x4_t will_uflow
3607- = vcleq_u32 (vreinterpretq_u32_f32 (vabsq_f32 (z)), TinyBound);
3608+ = vcleq_u32 (vreinterpretq_u32_f32 (vabsq_f32 (z)), TinyBound);
3609 if (__glibc_unlikely (v_any_u32 (will_uflow)))
3610 z2 = vbslq_f32 (will_uflow, v_f32 (0), z2);
3611 #endif
3612@@ -94,16 +95,16 @@ float32x4_t VPCS_ATTR NOINLINE V_NAME_F1 (tan) (float32x4_t x)
3613 #endif
3614
3615 /* n = rint(x/(pi/2)). */
3616- float32x4_t q = vfmaq_f32 (d->shift, d->two_over_pi, x);
3617+ float32x4_t q = vfmaq_laneq_f32 (d->shift, x, d->pi_consts, 3);
3618 float32x4_t n = vsubq_f32 (q, d->shift);
3619 /* Determine if x lives in an interval, where |tan(x)| grows to infinity. */
3620 uint32x4_t pred_alt = vtstq_u32 (vreinterpretq_u32_f32 (q), v_u32 (1));
3621
3622 /* r = x - n * (pi/2) (range reduction into -pi./4 .. pi/4). */
3623 float32x4_t r;
3624- r = vfmaq_f32 (x, d->neg_half_pi_1, n);
3625- r = vfmaq_f32 (r, d->neg_half_pi_2, n);
3626- r = vfmaq_f32 (r, d->neg_half_pi_3, n);
3627+ r = vfmaq_laneq_f32 (x, n, d->pi_consts, 0);
3628+ r = vfmaq_laneq_f32 (r, n, d->pi_consts, 1);
3629+ r = vfmaq_laneq_f32 (r, n, d->pi_consts, 2);
3630
3631 /* If x lives in an interval, where |tan(x)|
3632 - is finite, then use a polynomial approximation of the form
3633diff --git a/sysdeps/aarch64/multiarch/init-arch.h b/sysdeps/aarch64/multiarch/init-arch.h
3634index c52860efb2..61dc40088f 100644
3635--- a/sysdeps/aarch64/multiarch/init-arch.h
3636+++ b/sysdeps/aarch64/multiarch/init-arch.h
3637@@ -36,5 +36,7 @@
3638 MTE_ENABLED (); \
3639 bool __attribute__((unused)) sve = \
3640 GLRO(dl_aarch64_cpu_features).sve; \
3641+ bool __attribute__((unused)) prefer_sve_ifuncs = \
3642+ GLRO(dl_aarch64_cpu_features).prefer_sve_ifuncs; \
3643 bool __attribute__((unused)) mops = \
3644 GLRO(dl_aarch64_cpu_features).mops;
3645diff --git a/sysdeps/aarch64/multiarch/memcpy.c b/sysdeps/aarch64/multiarch/memcpy.c
3646index d12eccfca5..ce53567dab 100644
3647--- a/sysdeps/aarch64/multiarch/memcpy.c
3648+++ b/sysdeps/aarch64/multiarch/memcpy.c
3649@@ -47,7 +47,7 @@ select_memcpy_ifunc (void)
3650 {
3651 if (IS_A64FX (midr))
3652 return __memcpy_a64fx;
3653- return __memcpy_sve;
3654+ return prefer_sve_ifuncs ? __memcpy_sve : __memcpy_generic;
3655 }
3656
3657 if (IS_THUNDERX (midr))
3658diff --git a/sysdeps/aarch64/multiarch/memmove.c b/sysdeps/aarch64/multiarch/memmove.c
3659index 2081eeb4d4..fe95037be3 100644
3660--- a/sysdeps/aarch64/multiarch/memmove.c
3661+++ b/sysdeps/aarch64/multiarch/memmove.c
3662@@ -47,7 +47,7 @@ select_memmove_ifunc (void)
3663 {
3664 if (IS_A64FX (midr))
3665 return __memmove_a64fx;
3666- return __memmove_sve;
3667+ return prefer_sve_ifuncs ? __memmove_sve : __memmove_generic;
3668 }
3669
3670 if (IS_THUNDERX (midr))
3671diff --git a/sysdeps/aarch64/multiarch/memset_generic.S b/sysdeps/aarch64/multiarch/memset_generic.S
3672index 81748bdbce..e125a5ed85 100644
3673--- a/sysdeps/aarch64/multiarch/memset_generic.S
3674+++ b/sysdeps/aarch64/multiarch/memset_generic.S
3675@@ -33,3 +33,7 @@
3676 #endif
3677
3678 #include <../memset.S>
3679+
3680+#if IS_IN (rtld)
3681+strong_alias (memset, __memset_generic)
3682+#endif
3683diff --git a/sysdeps/aarch64/preconfigure b/sysdeps/aarch64/preconfigure
3684index d9bd1f8558..19657b627b 100644
3685--- a/sysdeps/aarch64/preconfigure
3686+++ b/sysdeps/aarch64/preconfigure
3687@@ -2,5 +2,6 @@ case "$machine" in
3688 aarch64*)
3689 base_machine=aarch64
3690 machine=aarch64
3691+ mtls_descriptor=desc
3692 ;;
3693 esac
3694diff --git a/sysdeps/arc/utmp-size.h b/sysdeps/arc/utmp-size.h
3695new file mode 100644
3696index 0000000000..a247fcd3da
3697--- /dev/null
3698+++ b/sysdeps/arc/utmp-size.h
3699@@ -0,0 +1,3 @@
3700+/* arc has less padding than other architectures with 64-bit time_t. */
3701+#define UTMP_SIZE 392
3702+#define LASTLOG_SIZE 296
3703diff --git a/sysdeps/arm/Makefile b/sysdeps/arm/Makefile
3704index d5cea717a9..619474eca9 100644
3705--- a/sysdeps/arm/Makefile
3706+++ b/sysdeps/arm/Makefile
3707@@ -13,15 +13,15 @@ $(objpfx)libgcc-stubs.a: $(objpfx)aeabi_unwind_cpp_pr1.os
3708 lib-noranlib: $(objpfx)libgcc-stubs.a
3709
3710 ifeq ($(build-shared),yes)
3711-ifeq (yes,$(have-mtls-dialect-gnu2))
3712+ifneq (no,$(have-mtls-descriptor))
3713 tests += tst-armtlsdescloc tst-armtlsdescextnow tst-armtlsdescextlazy
3714 modules-names += tst-armtlsdesclocmod
3715 modules-names += tst-armtlsdescextlazymod tst-armtlsdescextnowmod
3716 CPPFLAGS-tst-armtlsdescextnowmod.c += -Dstatic=
3717 CPPFLAGS-tst-armtlsdescextlazymod.c += -Dstatic=
3718-CFLAGS-tst-armtlsdesclocmod.c += -mtls-dialect=gnu2
3719-CFLAGS-tst-armtlsdescextnowmod.c += -mtls-dialect=gnu2
3720-CFLAGS-tst-armtlsdescextlazymod.c += -mtls-dialect=gnu2
3721+CFLAGS-tst-armtlsdesclocmod.c += -mtls-dialect=$(have-mtls-descriptor)
3722+CFLAGS-tst-armtlsdescextnowmod.c += -mtls-dialect=$(have-mtls-descriptor)
3723+CFLAGS-tst-armtlsdescextlazymod.c += -mtls-dialect=$(have-mtls-descriptor)
3724 LDFLAGS-tst-armtlsdescextnowmod.so += -Wl,-z,now
3725 tst-armtlsdescloc-ENV = LD_BIND_NOW=1
3726 tst-armtlsdescextnow-ENV = LD_BIND_NOW=1
3727diff --git a/sysdeps/arm/bits/wordsize.h b/sysdeps/arm/bits/wordsize.h
3728new file mode 100644
3729index 0000000000..6ecbfe7c86
3730--- /dev/null
3731+++ b/sysdeps/arm/bits/wordsize.h
3732@@ -0,0 +1,21 @@
3733+/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
3734+ This file is part of the GNU C Library.
3735+
3736+ The GNU C Library is free software; you can redistribute it and/or
3737+ modify it under the terms of the GNU Lesser General Public
3738+ License as published by the Free Software Foundation; either
3739+ version 2.1 of the License, or (at your option) any later version.
3740+
3741+ The GNU C Library is distributed in the hope that it will be useful,
3742+ but WITHOUT ANY WARRANTY; without even the implied warranty of
3743+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3744+ Lesser General Public License for more details.
3745+
3746+ You should have received a copy of the GNU Lesser General Public
3747+ License along with the GNU C Library; if not, see
3748+ <https://www.gnu.org/licenses/>. */
3749+
3750+#define __WORDSIZE 32
3751+#define __WORDSIZE_TIME64_COMPAT32 1
3752+#define __WORDSIZE32_SIZE_ULONG 0
3753+#define __WORDSIZE32_PTRDIFF_LONG 0
3754diff --git a/sysdeps/arm/configure b/sysdeps/arm/configure
3755index 35e2918922..4ef4d46cbd 100644
3756--- a/sysdeps/arm/configure
3757+++ b/sysdeps/arm/configure
3758@@ -187,6 +187,38 @@ else
3759 default-abi = soft"
3760 fi
3761
3762+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether VFP supports 32 registers" >&5
3763+printf %s "checking whether VFP supports 32 registers... " >&6; }
3764+if test ${libc_cv_arm_pcs_vfp_d32+y}
3765+then :
3766+ printf %s "(cached) " >&6
3767+else $as_nop
3768+
3769+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
3770+/* end confdefs.h. */
3771+
3772+void foo (void)
3773+{
3774+ asm volatile ("vldr d16,=17" : : : "d16");
3775+}
3776+
3777+_ACEOF
3778+if ac_fn_c_try_compile "$LINENO"
3779+then :
3780+ libc_cv_arm_pcs_vfp_d32=yes
3781+else $as_nop
3782+ libc_cv_arm_pcs_vfp_d32=no
3783+fi
3784+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
3785+fi
3786+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_arm_pcs_vfp_d32" >&5
3787+printf "%s\n" "$libc_cv_arm_pcs_vfp_d32" >&6; }
3788+if test "$libc_cv_arm_pcs_vfp_d32" = yes ;
3789+then
3790+ printf "%s\n" "#define HAVE_ARM_PCS_VFP_D32 1" >>confdefs.h
3791+
3792+fi
3793+
3794 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether PC-relative relocs in movw/movt work properly" >&5
3795 printf %s "checking whether PC-relative relocs in movw/movt work properly... " >&6; }
3796 if test ${libc_cv_arm_pcrel_movw+y}
3797diff --git a/sysdeps/arm/configure.ac b/sysdeps/arm/configure.ac
3798index 5172e30bbe..cd00ddc9d9 100644
3799--- a/sysdeps/arm/configure.ac
3800+++ b/sysdeps/arm/configure.ac
3801@@ -21,6 +21,21 @@ else
3802 LIBC_CONFIG_VAR([default-abi], [soft])
3803 fi
3804
3805+AC_CACHE_CHECK([whether VFP supports 32 registers],
3806+ libc_cv_arm_pcs_vfp_d32, [
3807+AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
3808+void foo (void)
3809+{
3810+ asm volatile ("vldr d16,=17" : : : "d16");
3811+}
3812+]])],
3813+ [libc_cv_arm_pcs_vfp_d32=yes],
3814+ [libc_cv_arm_pcs_vfp_d32=no])])
3815+if test "$libc_cv_arm_pcs_vfp_d32" = yes ;
3816+then
3817+ AC_DEFINE(HAVE_ARM_PCS_VFP_D32)
3818+fi
3819+
3820 AC_CACHE_CHECK([whether PC-relative relocs in movw/movt work properly],
3821 libc_cv_arm_pcrel_movw, [
3822 cat > conftest.s <<\EOF
3823diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
3824index b857bbc868..dd1a0f6b6e 100644
3825--- a/sysdeps/arm/dl-machine.h
3826+++ b/sysdeps/arm/dl-machine.h
3827@@ -139,7 +139,6 @@ _start:\n\
3828 _dl_start_user:\n\
3829 adr r6, .L_GET_GOT\n\
3830 add sl, sl, r6\n\
3831- ldr r4, [sl, r4]\n\
3832 @ save the entry point in another register\n\
3833 mov r6, r0\n\
3834 @ get the original arg count\n\
3835diff --git a/sysdeps/arm/dl-tlsdesc.S b/sysdeps/arm/dl-tlsdesc.S
3836index 764c56e70f..ada106521d 100644
3837--- a/sysdeps/arm/dl-tlsdesc.S
3838+++ b/sysdeps/arm/dl-tlsdesc.S
3839@@ -19,6 +19,7 @@
3840 #include <sysdep.h>
3841 #include <arm-features.h>
3842 #include <tls.h>
3843+#include <rtld-global-offsets.h>
3844 #include "tlsdesc.h"
3845
3846 .text
3847@@ -83,14 +84,20 @@ _dl_tlsdesc_dynamic(struct tlsdesc *tdp)
3848 .align 2
3849 _dl_tlsdesc_dynamic:
3850 /* Our calling convention is to clobber r0, r1 and the processor
3851- flags. All others that are modified must be saved */
3852- eabi_save ({r2,r3,r4,lr})
3853- push {r2,r3,r4,lr}
3854- cfi_adjust_cfa_offset (16)
3855+ flags. All others that are modified must be saved. r5 is
3856+ used as the hwcap value to avoid reload after __tls_get_addr
3857+ call. If required we will save the vector register on the slow
3858+ path. */
3859+ eabi_save ({r2,r3,r4,r5,ip,lr})
3860+ push {r2,r3,r4,r5,ip,lr}
3861+ cfi_adjust_cfa_offset (24)
3862 cfi_rel_offset (r2,0)
3863 cfi_rel_offset (r3,4)
3864 cfi_rel_offset (r4,8)
3865- cfi_rel_offset (lr,12)
3866+ cfi_rel_offset (r5,12)
3867+ cfi_rel_offset (ip,16)
3868+ cfi_rel_offset (lr,20)
3869+
3870 ldr r1, [r0] /* td */
3871 GET_TLS (lr)
3872 mov r4, r0 /* r4 = tp */
3873@@ -113,22 +120,69 @@ _dl_tlsdesc_dynamic:
3874 rsbne r0, r4, r3
3875 bne 2f
3876 1: mov r0, r1
3877+
3878+ /* Load the hwcap to check for vector support. */
3879+ ldr r2, 3f
3880+ ldr r1, .Lrtld_global_ro
3881+0: add r2, pc, r2
3882+ ldr r2, [r2, r1]
3883+ ldr r5, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
3884+
3885+#ifdef __SOFTFP__
3886+ tst r5, #HWCAP_ARM_VFP
3887+ beq .Lno_vfp
3888+#endif
3889+
3890+ /* Store the VFP registers. Don't use VFP instructions directly
3891+ because this code is used in non-VFP multilibs. */
3892+#define VFP_STACK_REQ (32*8 + 8)
3893+ sub sp, sp, VFP_STACK_REQ
3894+ cfi_adjust_cfa_offset (VFP_STACK_REQ)
3895+ mov r3, sp
3896+ .inst 0xeca30b20 /* vstmia r3!, {d0-d15} */
3897+ tst r5, #HWCAP_ARM_VFPD32
3898+ beq 4f
3899+ .inst 0xece30b20 /* vstmia r3!, {d16-d31} */
3900+ /* Store the floating-point status register. */
3901+4: .inst 0xeef12a10 /* vmrs r2, fpscr */
3902+ str r2, [r3]
3903+.Lno_vfp:
3904 bl __tls_get_addr
3905 rsb r0, r4, r0
3906+#ifdef __SOFTFP__
3907+ tst r5, #HWCAP_ARM_VFP
3908+ beq 2f
3909+#endif
3910+ mov r3, sp
3911+ .inst 0xecb30b20 /* vldmia r3!, {d0-d15} */
3912+ tst r5, #HWCAP_ARM_VFPD32
3913+ beq 5f
3914+ .inst 0xecf30b20 /* vldmia r3!, {d16-d31} */
3915+ ldr r4, [r3]
3916+5: .inst 0xeee14a10 /* vmsr fpscr, r4 */
3917+ add sp, sp, VFP_STACK_REQ
3918+ cfi_adjust_cfa_offset (-VFP_STACK_REQ)
3919+
3920 2:
3921 #if ((defined (__ARM_ARCH_4T__) && defined (__THUMB_INTERWORK__)) \
3922 || defined (ARM_ALWAYS_BX))
3923- pop {r2,r3,r4, lr}
3924- cfi_adjust_cfa_offset (-16)
3925+ pop {r2,r3,r4,r5,ip, lr}
3926+ cfi_adjust_cfa_offset (-20)
3927 cfi_restore (lr)
3928+ cfi_restore (ip)
3929+ cfi_restore (r5)
3930 cfi_restore (r4)
3931 cfi_restore (r3)
3932 cfi_restore (r2)
3933 bx lr
3934 #else
3935- pop {r2,r3,r4, pc}
3936+ pop {r2,r3,r4,r5,ip, pc}
3937 #endif
3938 eabi_fnend
3939 cfi_endproc
3940 .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic
3941+
3942+3: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS
3943+.Lrtld_global_ro:
3944+ .long C_SYMBOL_NAME(_rtld_global_ro)(GOT)
3945 #endif /* SHARED */
3946diff --git a/sysdeps/arm/tst-gnu2-tls2.h b/sysdeps/arm/tst-gnu2-tls2.h
3947new file mode 100644
3948index 0000000000..e413ac21fb
3949--- /dev/null
3950+++ b/sysdeps/arm/tst-gnu2-tls2.h
3951@@ -0,0 +1,128 @@
3952+/* Test TLSDESC relocation. ARM version.
3953+ Copyright (C) 2024 Free Software Foundation, Inc.
3954+ This file is part of the GNU C Library.
3955+
3956+ The GNU C Library is free software; you can redistribute it and/or
3957+ modify it under the terms of the GNU Lesser General Public
3958+ License as published by the Free Software Foundation; either
3959+ version 2.1 of the License, or (at your option) any later version.
3960+
3961+ The GNU C Library is distributed in the hope that it will be useful,
3962+ but WITHOUT ANY WARRANTY; without even the implied warranty of
3963+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3964+ Lesser General Public License for more details.
3965+
3966+ You should have received a copy of the GNU Lesser General Public
3967+ License along with the GNU C Library; if not, see
3968+ <https://www.gnu.org/licenses/>. */
3969+
3970+#include <config.h>
3971+#include <sys/auxv.h>
3972+#include <string.h>
3973+#include <stdlib.h>
3974+#include <endian.h>
3975+
3976+#ifndef __SOFTFP__
3977+
3978+# ifdef HAVE_ARM_PCS_VFP_D32
3979+# define SAVE_VFP_D32 \
3980+ asm volatile ("vldr d16,=17" : : : "d16"); \
3981+ asm volatile ("vldr d17,=18" : : : "d17"); \
3982+ asm volatile ("vldr d18,=19" : : : "d18"); \
3983+ asm volatile ("vldr d19,=20" : : : "d19"); \
3984+ asm volatile ("vldr d20,=21" : : : "d20"); \
3985+ asm volatile ("vldr d21,=22" : : : "d21"); \
3986+ asm volatile ("vldr d22,=23" : : : "d22"); \
3987+ asm volatile ("vldr d23,=24" : : : "d23"); \
3988+ asm volatile ("vldr d24,=25" : : : "d24"); \
3989+ asm volatile ("vldr d25,=26" : : : "d25"); \
3990+ asm volatile ("vldr d26,=27" : : : "d26"); \
3991+ asm volatile ("vldr d27,=28" : : : "d27"); \
3992+ asm volatile ("vldr d28,=29" : : : "d28"); \
3993+ asm volatile ("vldr d29,=30" : : : "d29"); \
3994+ asm volatile ("vldr d30,=31" : : : "d30"); \
3995+ asm volatile ("vldr d31,=32" : : : "d31");
3996+# else
3997+# define SAVE_VFP_D32
3998+# endif
3999+
4000+# define INIT_TLSDESC_CALL() \
4001+ unsigned long hwcap = getauxval (AT_HWCAP)
4002+
4003+/* Set each vector register to a value from 1 to 32 before the TLS access,
4004+ dump to memory after TLS access, and compare with the expected values. */
4005+
4006+# define BEFORE_TLSDESC_CALL() \
4007+ if (hwcap & HWCAP_ARM_VFP) \
4008+ { \
4009+ asm volatile ("vldr d0,=1" : : : "d0"); \
4010+ asm volatile ("vldr d1,=2" : : : "d1"); \
4011+ asm volatile ("vldr d2,=3" : : : "d1"); \
4012+ asm volatile ("vldr d3,=4" : : : "d3"); \
4013+ asm volatile ("vldr d4,=5" : : : "d4"); \
4014+ asm volatile ("vldr d5,=6" : : : "d5"); \
4015+ asm volatile ("vldr d6,=7" : : : "d6"); \
4016+ asm volatile ("vldr d7,=8" : : : "d7"); \
4017+ asm volatile ("vldr d8,=9" : : : "d8"); \
4018+ asm volatile ("vldr d9,=10" : : : "d9"); \
4019+ asm volatile ("vldr d10,=11" : : : "d10"); \
4020+ asm volatile ("vldr d11,=12" : : : "d11"); \
4021+ asm volatile ("vldr d12,=13" : : : "d12"); \
4022+ asm volatile ("vldr d13,=14" : : : "d13"); \
4023+ asm volatile ("vldr d14,=15" : : : "d14"); \
4024+ asm volatile ("vldr d15,=16" : : : "d15"); \
4025+ } \
4026+ if (hwcap & HWCAP_ARM_VFPD32) \
4027+ { \
4028+ SAVE_VFP_D32 \
4029+ }
4030+
4031+# define VFP_STACK_REQ (16*8)
4032+# if __BYTE_ORDER == __BIG_ENDIAN
4033+# define DISP 7
4034+# else
4035+# define DISP 0
4036+# endif
4037+
4038+# ifdef HAVE_ARM_PCS_VFP_D32
4039+# define CHECK_VFP_D32 \
4040+ char vfp[VFP_STACK_REQ]; \
4041+ asm volatile ("vstmia %0, {d16-d31}\n" \
4042+ : \
4043+ : "r" (vfp) \
4044+ : "memory"); \
4045+ \
4046+ char expected[VFP_STACK_REQ] = { 0 }; \
4047+ for (int i = 0; i < 16; ++i) \
4048+ expected[i * 8 + DISP] = i + 17; \
4049+ \
4050+ if (memcmp (vfp, expected, VFP_STACK_REQ) != 0) \
4051+ abort ();
4052+# else
4053+# define CHECK_VFP_D32
4054+# endif
4055+
4056+# define AFTER_TLSDESC_CALL() \
4057+ if (hwcap & HWCAP_ARM_VFP) \
4058+ { \
4059+ char vfp[VFP_STACK_REQ]; \
4060+ asm volatile ("vstmia %0, {d0-d15}\n" \
4061+ : \
4062+ : "r" (vfp) \
4063+ : "memory"); \
4064+ \
4065+ char expected[VFP_STACK_REQ] = { 0 }; \
4066+ for (int i = 0; i < 16; ++i) \
4067+ expected[i * 8 + DISP] = i + 1; \
4068+ \
4069+ if (memcmp (vfp, expected, VFP_STACK_REQ) != 0) \
4070+ abort (); \
4071+ } \
4072+ if (hwcap & HWCAP_ARM_VFPD32) \
4073+ { \
4074+ CHECK_VFP_D32 \
4075+ }
4076+
4077+#endif /* __SOFTFP__ */
4078+
4079+#include_next <tst-gnu2-tls2.h>
4080diff --git a/sysdeps/arm/utmp-size.h b/sysdeps/arm/utmp-size.h
4081new file mode 100644
4082index 0000000000..8f21ebe1b6
4083--- /dev/null
4084+++ b/sysdeps/arm/utmp-size.h
4085@@ -0,0 +1,2 @@
4086+#define UTMP_SIZE 384
4087+#define LASTLOG_SIZE 292
4088diff --git a/sysdeps/csky/bits/wordsize.h b/sysdeps/csky/bits/wordsize.h
4089new file mode 100644
4090index 0000000000..6ecbfe7c86
4091--- /dev/null
4092+++ b/sysdeps/csky/bits/wordsize.h
4093@@ -0,0 +1,21 @@
4094+/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
4095+ This file is part of the GNU C Library.
4096+
4097+ The GNU C Library is free software; you can redistribute it and/or
4098+ modify it under the terms of the GNU Lesser General Public
4099+ License as published by the Free Software Foundation; either
4100+ version 2.1 of the License, or (at your option) any later version.
4101+
4102+ The GNU C Library is distributed in the hope that it will be useful,
4103+ but WITHOUT ANY WARRANTY; without even the implied warranty of
4104+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4105+ Lesser General Public License for more details.
4106+
4107+ You should have received a copy of the GNU Lesser General Public
4108+ License along with the GNU C Library; if not, see
4109+ <https://www.gnu.org/licenses/>. */
4110+
4111+#define __WORDSIZE 32
4112+#define __WORDSIZE_TIME64_COMPAT32 1
4113+#define __WORDSIZE32_SIZE_ULONG 0
4114+#define __WORDSIZE32_PTRDIFF_LONG 0
4115diff --git a/sysdeps/csky/utmp-size.h b/sysdeps/csky/utmp-size.h
4116new file mode 100644
4117index 0000000000..8f21ebe1b6
4118--- /dev/null
4119+++ b/sysdeps/csky/utmp-size.h
4120@@ -0,0 +1,2 @@
4121+#define UTMP_SIZE 384
4122+#define LASTLOG_SIZE 292
4123diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
4124index 117c901ccc..50f58a60e3 100644
4125--- a/sysdeps/generic/ldsodefs.h
4126+++ b/sysdeps/generic/ldsodefs.h
4127@@ -646,6 +646,8 @@ struct rtld_global_ro
4128 /* Mask for more hardware capabilities that are available on some
4129 platforms. */
4130 EXTERN uint64_t _dl_hwcap2;
4131+ EXTERN uint64_t _dl_hwcap3;
4132+ EXTERN uint64_t _dl_hwcap4;
4133
4134 EXTERN enum dso_sort_algorithm _dl_dso_sort_algo;
4135
4136diff --git a/sysdeps/generic/utmp-size.h b/sysdeps/generic/utmp-size.h
4137new file mode 100644
4138index 0000000000..89dbe878b0
4139--- /dev/null
4140+++ b/sysdeps/generic/utmp-size.h
4141@@ -0,0 +1,23 @@
4142+/* Expected sizes of utmp-related structures stored in files. 64-bit version.
4143+ Copyright (C) 2024 Free Software Foundation, Inc.
4144+ This file is part of the GNU C Library.
4145+
4146+ The GNU C Library is free software; you can redistribute it and/or
4147+ modify it under the terms of the GNU Lesser General Public
4148+ License as published by the Free Software Foundation; either
4149+ version 2.1 of the License, or (at your option) any later version.
4150+
4151+ The GNU C Library is distributed in the hope that it will be useful,
4152+ but WITHOUT ANY WARRANTY; without even the implied warranty of
4153+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4154+ Lesser General Public License for more details.
4155+
4156+ You should have received a copy of the GNU Lesser General Public
4157+ License along with the GNU C Library; if not, see
4158+ <https://www.gnu.org/licenses/>. */
4159+
4160+/* Expected size, in bytes, of struct utmp and struct utmpx. */
4161+#define UTMP_SIZE 400
4162+
4163+/* Expected size, in bytes, of struct lastlog. */
4164+#define LASTLOG_SIZE 296
4165diff --git a/sysdeps/hppa/utmp-size.h b/sysdeps/hppa/utmp-size.h
4166new file mode 100644
4167index 0000000000..8f21ebe1b6
4168--- /dev/null
4169+++ b/sysdeps/hppa/utmp-size.h
4170@@ -0,0 +1,2 @@
4171+#define UTMP_SIZE 384
4172+#define LASTLOG_SIZE 292
4173diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
4174index fc1ef96587..50d74fe6e9 100644
4175--- a/sysdeps/i386/dl-machine.h
4176+++ b/sysdeps/i386/dl-machine.h
4177@@ -347,7 +347,7 @@ and creates an unsatisfiable circular dependency.\n",
4178 {
4179 td->arg = _dl_make_tlsdesc_dynamic
4180 (sym_map, sym->st_value + (ElfW(Word))td->arg);
4181- td->entry = _dl_tlsdesc_dynamic;
4182+ td->entry = GLRO(dl_x86_tlsdesc_dynamic);
4183 }
4184 else
4185 # endif
4186diff --git a/sysdeps/i386/dl-tlsdesc-dynamic.h b/sysdeps/i386/dl-tlsdesc-dynamic.h
4187new file mode 100644
4188index 0000000000..3627028577
4189--- /dev/null
4190+++ b/sysdeps/i386/dl-tlsdesc-dynamic.h
4191@@ -0,0 +1,190 @@
4192+/* Thread-local storage handling in the ELF dynamic linker. i386 version.
4193+ Copyright (C) 2004-2024 Free Software Foundation, Inc.
4194+ This file is part of the GNU C Library.
4195+
4196+ The GNU C Library is free software; you can redistribute it and/or
4197+ modify it under the terms of the GNU Lesser General Public
4198+ License as published by the Free Software Foundation; either
4199+ version 2.1 of the License, or (at your option) any later version.
4200+
4201+ The GNU C Library is distributed in the hope that it will be useful,
4202+ but WITHOUT ANY WARRANTY; without even the implied warranty of
4203+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4204+ Lesser General Public License for more details.
4205+
4206+ You should have received a copy of the GNU Lesser General Public
4207+ License along with the GNU C Library; if not, see
4208+ <https://www.gnu.org/licenses/>. */
4209+
4210+#undef REGISTER_SAVE_AREA
4211+
4212+#if !defined USE_FNSAVE && (STATE_SAVE_ALIGNMENT % 16) != 0
4213+# error STATE_SAVE_ALIGNMENT must be multiple of 16
4214+#endif
4215+
4216+#if DL_RUNTIME_RESOLVE_REALIGN_STACK
4217+# ifdef USE_FNSAVE
4218+# error USE_FNSAVE shouldn't be defined
4219+# endif
4220+# ifdef USE_FXSAVE
4221+/* Use fxsave to save all registers. */
4222+# define REGISTER_SAVE_AREA 512
4223+# endif
4224+#else
4225+# ifdef USE_FNSAVE
4226+/* Use fnsave to save x87 FPU stack registers. */
4227+# define REGISTER_SAVE_AREA 108
4228+# else
4229+# ifndef USE_FXSAVE
4230+# error USE_FXSAVE must be defined
4231+# endif
4232+/* Use fxsave to save all registers. Add 12 bytes to align the stack
4233+ to 16 bytes. */
4234+# define REGISTER_SAVE_AREA (512 + 12)
4235+# endif
4236+#endif
4237+
4238+ .hidden _dl_tlsdesc_dynamic
4239+ .global _dl_tlsdesc_dynamic
4240+ .type _dl_tlsdesc_dynamic,@function
4241+
4242+ /* This function is used for symbols that need dynamic TLS.
4243+
4244+ %eax points to the TLS descriptor, such that 0(%eax) points to
4245+ _dl_tlsdesc_dynamic itself, and 4(%eax) points to a struct
4246+ tlsdesc_dynamic_arg object. It must return in %eax the offset
4247+ between the thread pointer and the object denoted by the
4248+ argument, without clobbering any registers.
4249+
4250+ The assembly code that follows is a rendition of the following
4251+ C code, hand-optimized a little bit.
4252+
4253+ptrdiff_t
4254+__attribute__ ((__regparm__ (1)))
4255+_dl_tlsdesc_dynamic (struct tlsdesc *tdp)
4256+{
4257+ struct tlsdesc_dynamic_arg *td = tdp->arg;
4258+ dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer + DTV_OFFSET);
4259+ if (__builtin_expect (td->gen_count <= dtv[0].counter
4260+ && (dtv[td->tlsinfo.ti_module].pointer.val
4261+ != TLS_DTV_UNALLOCATED),
4262+ 1))
4263+ return dtv[td->tlsinfo.ti_module].pointer.val + td->tlsinfo.ti_offset
4264+ - __thread_pointer;
4265+
4266+ return ___tls_get_addr (&td->tlsinfo) - __thread_pointer;
4267+}
4268+*/
4269+ cfi_startproc
4270+ .align 16
4271+_dl_tlsdesc_dynamic:
4272+ /* Like all TLS resolvers, preserve call-clobbered registers.
4273+ We need two scratch regs anyway. */
4274+ subl $32, %esp
4275+ cfi_adjust_cfa_offset (32)
4276+ movl %ecx, 20(%esp)
4277+ movl %edx, 24(%esp)
4278+ movl TLSDESC_ARG(%eax), %eax
4279+ movl %gs:DTV_OFFSET, %edx
4280+ movl TLSDESC_GEN_COUNT(%eax), %ecx
4281+ cmpl (%edx), %ecx
4282+ ja 2f
4283+ movl TLSDESC_MODID(%eax), %ecx
4284+ movl (%edx,%ecx,8), %edx
4285+ cmpl $-1, %edx
4286+ je 2f
4287+ movl TLSDESC_MODOFF(%eax), %eax
4288+ addl %edx, %eax
4289+1:
4290+ movl 20(%esp), %ecx
4291+ subl %gs:0, %eax
4292+ movl 24(%esp), %edx
4293+ addl $32, %esp
4294+ cfi_adjust_cfa_offset (-32)
4295+ ret
4296+ .p2align 4,,7
4297+2:
4298+ cfi_adjust_cfa_offset (32)
4299+#if DL_RUNTIME_RESOLVE_REALIGN_STACK
4300+ movl %ebx, -28(%esp)
4301+ movl %esp, %ebx
4302+ cfi_def_cfa_register(%ebx)
4303+ and $-STATE_SAVE_ALIGNMENT, %esp
4304+#endif
4305+#ifdef REGISTER_SAVE_AREA
4306+ subl $REGISTER_SAVE_AREA, %esp
4307+# if !DL_RUNTIME_RESOLVE_REALIGN_STACK
4308+ cfi_adjust_cfa_offset(REGISTER_SAVE_AREA)
4309+# endif
4310+#else
4311+# if !DL_RUNTIME_RESOLVE_REALIGN_STACK
4312+# error DL_RUNTIME_RESOLVE_REALIGN_STACK must be true
4313+# endif
4314+ /* Allocate stack space of the required size to save the state. */
4315+ LOAD_PIC_REG (cx)
4316+ subl RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+XSAVE_STATE_SIZE_OFFSET+_rtld_local_ro@GOTOFF(%ecx), %esp
4317+#endif
4318+#ifdef USE_FNSAVE
4319+ fnsave (%esp)
4320+#elif defined USE_FXSAVE
4321+ fxsave (%esp)
4322+#else
4323+ /* Save the argument for ___tls_get_addr in EAX. */
4324+ movl %eax, %ecx
4325+ movl $TLSDESC_CALL_STATE_SAVE_MASK, %eax
4326+ xorl %edx, %edx
4327+ /* Clear the XSAVE Header. */
4328+# ifdef USE_XSAVE
4329+ movl %edx, (512)(%esp)
4330+ movl %edx, (512 + 4 * 1)(%esp)
4331+ movl %edx, (512 + 4 * 2)(%esp)
4332+ movl %edx, (512 + 4 * 3)(%esp)
4333+# endif
4334+ movl %edx, (512 + 4 * 4)(%esp)
4335+ movl %edx, (512 + 4 * 5)(%esp)
4336+ movl %edx, (512 + 4 * 6)(%esp)
4337+ movl %edx, (512 + 4 * 7)(%esp)
4338+ movl %edx, (512 + 4 * 8)(%esp)
4339+ movl %edx, (512 + 4 * 9)(%esp)
4340+ movl %edx, (512 + 4 * 10)(%esp)
4341+ movl %edx, (512 + 4 * 11)(%esp)
4342+ movl %edx, (512 + 4 * 12)(%esp)
4343+ movl %edx, (512 + 4 * 13)(%esp)
4344+ movl %edx, (512 + 4 * 14)(%esp)
4345+ movl %edx, (512 + 4 * 15)(%esp)
4346+# ifdef USE_XSAVE
4347+ xsave (%esp)
4348+# else
4349+ xsavec (%esp)
4350+# endif
4351+ /* Restore the argument for ___tls_get_addr in EAX. */
4352+ movl %ecx, %eax
4353+#endif
4354+ call HIDDEN_JUMPTARGET (___tls_get_addr)
4355+ /* Get register content back. */
4356+#ifdef USE_FNSAVE
4357+ frstor (%esp)
4358+#elif defined USE_FXSAVE
4359+ fxrstor (%esp)
4360+#else
4361+ /* Save and retore ___tls_get_addr return value stored in EAX. */
4362+ movl %eax, %ecx
4363+ movl $TLSDESC_CALL_STATE_SAVE_MASK, %eax
4364+ xorl %edx, %edx
4365+ xrstor (%esp)
4366+ movl %ecx, %eax
4367+#endif
4368+#if DL_RUNTIME_RESOLVE_REALIGN_STACK
4369+ mov %ebx, %esp
4370+ cfi_def_cfa_register(%esp)
4371+ movl -28(%esp), %ebx
4372+ cfi_restore(%ebx)
4373+#else
4374+ addl $REGISTER_SAVE_AREA, %esp
4375+ cfi_adjust_cfa_offset(-REGISTER_SAVE_AREA)
4376+#endif
4377+ jmp 1b
4378+ cfi_endproc
4379+ .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic
4380+
4381+#undef STATE_SAVE_ALIGNMENT
4382diff --git a/sysdeps/i386/dl-tlsdesc.S b/sysdeps/i386/dl-tlsdesc.S
4383index 90d93caa0c..f002feee56 100644
4384--- a/sysdeps/i386/dl-tlsdesc.S
4385+++ b/sysdeps/i386/dl-tlsdesc.S
4386@@ -18,8 +18,27 @@
4387
4388 #include <sysdep.h>
4389 #include <tls.h>
4390+#include <cpu-features-offsets.h>
4391+#include <features-offsets.h>
4392 #include "tlsdesc.h"
4393
4394+#ifndef DL_STACK_ALIGNMENT
4395+/* Due to GCC bug:
4396+
4397+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066
4398+
4399+ __tls_get_addr may be called with 4-byte stack alignment. Although
4400+ this bug has been fixed in GCC 4.9.4, 5.3 and 6, we can't assume
4401+ that stack will be always aligned at 16 bytes. */
4402+# define DL_STACK_ALIGNMENT 4
4403+#endif
4404+
4405+/* True if _dl_tlsdesc_dynamic should align stack for STATE_SAVE or align
4406+ stack to MINIMUM_ALIGNMENT bytes before calling ___tls_get_addr. */
4407+#define DL_RUNTIME_RESOLVE_REALIGN_STACK \
4408+ (STATE_SAVE_ALIGNMENT > DL_STACK_ALIGNMENT \
4409+ || MINIMUM_ALIGNMENT > DL_STACK_ALIGNMENT)
4410+
4411 .text
4412
4413 /* This function is used to compute the TP offset for symbols in
4414@@ -65,69 +84,35 @@ _dl_tlsdesc_undefweak:
4415 .size _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak
4416
4417 #ifdef SHARED
4418- .hidden _dl_tlsdesc_dynamic
4419- .global _dl_tlsdesc_dynamic
4420- .type _dl_tlsdesc_dynamic,@function
4421-
4422- /* This function is used for symbols that need dynamic TLS.
4423-
4424- %eax points to the TLS descriptor, such that 0(%eax) points to
4425- _dl_tlsdesc_dynamic itself, and 4(%eax) points to a struct
4426- tlsdesc_dynamic_arg object. It must return in %eax the offset
4427- between the thread pointer and the object denoted by the
4428- argument, without clobbering any registers.
4429-
4430- The assembly code that follows is a rendition of the following
4431- C code, hand-optimized a little bit.
4432-
4433-ptrdiff_t
4434-__attribute__ ((__regparm__ (1)))
4435-_dl_tlsdesc_dynamic (struct tlsdesc *tdp)
4436-{
4437- struct tlsdesc_dynamic_arg *td = tdp->arg;
4438- dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer + DTV_OFFSET);
4439- if (__builtin_expect (td->gen_count <= dtv[0].counter
4440- && (dtv[td->tlsinfo.ti_module].pointer.val
4441- != TLS_DTV_UNALLOCATED),
4442- 1))
4443- return dtv[td->tlsinfo.ti_module].pointer.val + td->tlsinfo.ti_offset
4444- - __thread_pointer;
4445-
4446- return ___tls_get_addr (&td->tlsinfo) - __thread_pointer;
4447-}
4448-*/
4449- cfi_startproc
4450- .align 16
4451-_dl_tlsdesc_dynamic:
4452- /* Like all TLS resolvers, preserve call-clobbered registers.
4453- We need two scratch regs anyway. */
4454- subl $28, %esp
4455- cfi_adjust_cfa_offset (28)
4456- movl %ecx, 20(%esp)
4457- movl %edx, 24(%esp)
4458- movl TLSDESC_ARG(%eax), %eax
4459- movl %gs:DTV_OFFSET, %edx
4460- movl TLSDESC_GEN_COUNT(%eax), %ecx
4461- cmpl (%edx), %ecx
4462- ja .Lslow
4463- movl TLSDESC_MODID(%eax), %ecx
4464- movl (%edx,%ecx,8), %edx
4465- cmpl $-1, %edx
4466- je .Lslow
4467- movl TLSDESC_MODOFF(%eax), %eax
4468- addl %edx, %eax
4469-.Lret:
4470- movl 20(%esp), %ecx
4471- subl %gs:0, %eax
4472- movl 24(%esp), %edx
4473- addl $28, %esp
4474- cfi_adjust_cfa_offset (-28)
4475- ret
4476- .p2align 4,,7
4477-.Lslow:
4478- cfi_adjust_cfa_offset (28)
4479- call HIDDEN_JUMPTARGET (___tls_get_addr)
4480- jmp .Lret
4481- cfi_endproc
4482- .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic
4483+# define USE_FNSAVE
4484+# define MINIMUM_ALIGNMENT 4
4485+# define STATE_SAVE_ALIGNMENT 4
4486+# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_fnsave
4487+# include "dl-tlsdesc-dynamic.h"
4488+# undef _dl_tlsdesc_dynamic
4489+# undef MINIMUM_ALIGNMENT
4490+# undef USE_FNSAVE
4491+
4492+# define MINIMUM_ALIGNMENT 16
4493+
4494+# define USE_FXSAVE
4495+# define STATE_SAVE_ALIGNMENT 16
4496+# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_fxsave
4497+# include "dl-tlsdesc-dynamic.h"
4498+# undef _dl_tlsdesc_dynamic
4499+# undef USE_FXSAVE
4500+
4501+# define USE_XSAVE
4502+# define STATE_SAVE_ALIGNMENT 64
4503+# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_xsave
4504+# include "dl-tlsdesc-dynamic.h"
4505+# undef _dl_tlsdesc_dynamic
4506+# undef USE_XSAVE
4507+
4508+# define USE_XSAVEC
4509+# define STATE_SAVE_ALIGNMENT 64
4510+# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_xsavec
4511+# include "dl-tlsdesc-dynamic.h"
4512+# undef _dl_tlsdesc_dynamic
4513+# undef USE_XSAVEC
4514 #endif /* SHARED */
4515diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
4516index 84e6686eba..f2139fc172 100644
4517--- a/sysdeps/i386/fpu/libm-test-ulps
4518+++ b/sysdeps/i386/fpu/libm-test-ulps
4519@@ -1232,6 +1232,7 @@ ldouble: 6
4520
4521 Function: "hypot":
4522 double: 1
4523+float: 1
4524 float128: 1
4525 ldouble: 1
4526
4527diff --git a/sysdeps/i386/i586/memcpy.S b/sysdeps/i386/i586/memcpy.S
4528index 3e26f112d6..79856d498a 100644
4529--- a/sysdeps/i386/i586/memcpy.S
4530+++ b/sysdeps/i386/i586/memcpy.S
4531@@ -26,7 +26,7 @@
4532 #define LEN SRC+4
4533
4534 .text
4535-#if defined PIC && IS_IN (libc)
4536+#if defined SHARED && IS_IN (libc)
4537 ENTRY (__memcpy_chk)
4538 movl 12(%esp), %eax
4539 cmpl %eax, 16(%esp)
4540diff --git a/sysdeps/i386/i686/memmove.S b/sysdeps/i386/i686/memmove.S
4541index f230359ad6..effd958120 100644
4542--- a/sysdeps/i386/i686/memmove.S
4543+++ b/sysdeps/i386/i686/memmove.S
4544@@ -29,7 +29,7 @@
4545 #define SRC DEST+4
4546 #define LEN SRC+4
4547
4548-#if defined PIC && IS_IN (libc)
4549+#if defined SHARED && IS_IN (libc)
4550 ENTRY_CHK (__memmove_chk)
4551 movl 12(%esp), %eax
4552 cmpl %eax, 16(%esp)
4553diff --git a/sysdeps/i386/i686/memset.S b/sysdeps/i386/i686/memset.S
4554index f02f5a6df7..ab06771ea0 100644
4555--- a/sysdeps/i386/i686/memset.S
4556+++ b/sysdeps/i386/i686/memset.S
4557@@ -27,7 +27,7 @@
4558 #define LEN CHR+4
4559
4560 .text
4561-#if defined PIC && IS_IN (libc)
4562+#if defined SHARED && IS_IN (libc)
4563 ENTRY_CHK (__memset_chk)
4564 movl 12(%esp), %eax
4565 cmpl %eax, 16(%esp)
4566diff --git a/sysdeps/i386/i686/multiarch/memrchr-c.c b/sysdeps/i386/i686/multiarch/memrchr-c.c
4567index ef7bbbe792..20bfdf3af3 100644
4568--- a/sysdeps/i386/i686/multiarch/memrchr-c.c
4569+++ b/sysdeps/i386/i686/multiarch/memrchr-c.c
4570@@ -5,3 +5,4 @@ extern void *__memrchr_ia32 (const void *, int, size_t);
4571 #endif
4572
4573 #include "string/memrchr.c"
4574+strong_alias (__memrchr_ia32, __GI___memrchr)
4575diff --git a/sysdeps/i386/i686/multiarch/memrchr-sse2.S b/sysdeps/i386/i686/multiarch/memrchr-sse2.S
4576index d9dae04171..e123f87435 100644
4577--- a/sysdeps/i386/i686/multiarch/memrchr-sse2.S
4578+++ b/sysdeps/i386/i686/multiarch/memrchr-sse2.S
4579@@ -720,5 +720,4 @@ L(ret_null):
4580 ret
4581
4582 END (__memrchr_sse2)
4583-strong_alias (__memrchr_sse2, __GI___memrchr)
4584 #endif
4585diff --git a/sysdeps/loongarch/fpu/e_scalbf.c b/sysdeps/loongarch/fpu/e_scalbf.c
4586index 9f05485236..7c0395fbb5 100644
4587--- a/sysdeps/loongarch/fpu/e_scalbf.c
4588+++ b/sysdeps/loongarch/fpu/e_scalbf.c
4589@@ -57,4 +57,4 @@ __ieee754_scalbf (float x, float fn)
4590
4591 return x;
4592 }
4593-libm_alias_finite (__ieee754_scalb, __scalb)
4594+libm_alias_finite (__ieee754_scalbf, __scalbf)
4595diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile
4596index fe863e1ba4..01762ef526 100644
4597--- a/sysdeps/loongarch/lp64/multiarch/Makefile
4598+++ b/sysdeps/loongarch/lp64/multiarch/Makefile
4599@@ -1,52 +1,52 @@
4600 ifeq ($(subdir),string)
4601 sysdep_routines += \
4602- strlen-aligned \
4603- strlen-lsx \
4604- strlen-lasx \
4605- strnlen-aligned \
4606- strnlen-lsx \
4607- strnlen-lasx \
4608+ memchr-aligned \
4609+ memchr-lasx \
4610+ memchr-lsx \
4611+ memcmp-aligned \
4612+ memcmp-lasx \
4613+ memcmp-lsx \
4614+ memcpy-aligned \
4615+ memcpy-unaligned \
4616+ memmove-lasx \
4617+ memmove-lsx \
4618+ memmove-unaligned \
4619+ memrchr-generic \
4620+ memrchr-lasx \
4621+ memrchr-lsx \
4622+ memset-aligned \
4623+ memset-lasx \
4624+ memset-lsx \
4625+ memset-unaligned \
4626+ rawmemchr-aligned \
4627+ rawmemchr-lasx \
4628+ rawmemchr-lsx \
4629+ stpcpy-aligned \
4630+ stpcpy-lasx \
4631+ stpcpy-lsx \
4632+ stpcpy-unaligned \
4633 strchr-aligned \
4634- strchr-lsx \
4635 strchr-lasx \
4636- strrchr-aligned \
4637- strrchr-lsx \
4638- strrchr-lasx \
4639+ strchr-lsx \
4640 strchrnul-aligned \
4641- strchrnul-lsx \
4642 strchrnul-lasx \
4643+ strchrnul-lsx \
4644 strcmp-aligned \
4645 strcmp-lsx \
4646- strncmp-aligned \
4647- strncmp-lsx \
4648 strcpy-aligned \
4649- strcpy-unaligned \
4650- strcpy-lsx \
4651 strcpy-lasx \
4652- stpcpy-aligned \
4653- stpcpy-unaligned \
4654- stpcpy-lsx \
4655- stpcpy-lasx \
4656- memcpy-aligned \
4657- memcpy-unaligned \
4658- memmove-unaligned \
4659- memmove-lsx \
4660- memmove-lasx \
4661- rawmemchr-aligned \
4662- rawmemchr-lsx \
4663- rawmemchr-lasx \
4664- memchr-aligned \
4665- memchr-lsx \
4666- memchr-lasx \
4667- memrchr-generic \
4668- memrchr-lsx \
4669- memrchr-lasx \
4670- memset-aligned \
4671- memset-unaligned \
4672- memset-lsx \
4673- memset-lasx \
4674- memcmp-aligned \
4675- memcmp-lsx \
4676- memcmp-lasx \
4677+ strcpy-lsx \
4678+ strcpy-unaligned \
4679+ strlen-aligned \
4680+ strlen-lasx \
4681+ strlen-lsx \
4682+ strncmp-aligned \
4683+ strncmp-lsx \
4684+ strnlen-aligned \
4685+ strnlen-lasx \
4686+ strnlen-lsx \
4687+ strrchr-aligned \
4688+ strrchr-lasx \
4689+ strrchr-lsx \
4690 # sysdep_routines
4691 endif
4692diff --git a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h
4693index cb640d77b7..a73390b12f 100644
4694--- a/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h
4695+++ b/sysdeps/loongarch/lp64/multiarch/dl-symbol-redir-ifunc.h
4696@@ -19,6 +19,9 @@
4697 #ifndef _DL_IFUNC_GENERIC_H
4698 #define _DL_IFUNC_GENERIC_H
4699
4700+#ifndef SHARED
4701 asm ("memset = __memset_aligned");
4702+asm ("memcmp = __memcmp_aligned");
4703+#endif
4704
4705 #endif
4706diff --git a/sysdeps/m68k/bits/wordsize.h b/sysdeps/m68k/bits/wordsize.h
4707new file mode 100644
4708index 0000000000..6ecbfe7c86
4709--- /dev/null
4710+++ b/sysdeps/m68k/bits/wordsize.h
4711@@ -0,0 +1,21 @@
4712+/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
4713+ This file is part of the GNU C Library.
4714+
4715+ The GNU C Library is free software; you can redistribute it and/or
4716+ modify it under the terms of the GNU Lesser General Public
4717+ License as published by the Free Software Foundation; either
4718+ version 2.1 of the License, or (at your option) any later version.
4719+
4720+ The GNU C Library is distributed in the hope that it will be useful,
4721+ but WITHOUT ANY WARRANTY; without even the implied warranty of
4722+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4723+ Lesser General Public License for more details.
4724+
4725+ You should have received a copy of the GNU Lesser General Public
4726+ License along with the GNU C Library; if not, see
4727+ <https://www.gnu.org/licenses/>. */
4728+
4729+#define __WORDSIZE 32
4730+#define __WORDSIZE_TIME64_COMPAT32 1
4731+#define __WORDSIZE32_SIZE_ULONG 0
4732+#define __WORDSIZE32_PTRDIFF_LONG 0
4733diff --git a/sysdeps/m68k/utmp-size.h b/sysdeps/m68k/utmp-size.h
4734new file mode 100644
4735index 0000000000..5946685819
4736--- /dev/null
4737+++ b/sysdeps/m68k/utmp-size.h
4738@@ -0,0 +1,3 @@
4739+/* m68k has 2-byte alignment. */
4740+#define UTMP_SIZE 382
4741+#define LASTLOG_SIZE 292
4742diff --git a/sysdeps/microblaze/bits/wordsize.h b/sysdeps/microblaze/bits/wordsize.h
4743new file mode 100644
4744index 0000000000..6ecbfe7c86
4745--- /dev/null
4746+++ b/sysdeps/microblaze/bits/wordsize.h
4747@@ -0,0 +1,21 @@
4748+/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
4749+ This file is part of the GNU C Library.
4750+
4751+ The GNU C Library is free software; you can redistribute it and/or
4752+ modify it under the terms of the GNU Lesser General Public
4753+ License as published by the Free Software Foundation; either
4754+ version 2.1 of the License, or (at your option) any later version.
4755+
4756+ The GNU C Library is distributed in the hope that it will be useful,
4757+ but WITHOUT ANY WARRANTY; without even the implied warranty of
4758+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4759+ Lesser General Public License for more details.
4760+
4761+ You should have received a copy of the GNU Lesser General Public
4762+ License along with the GNU C Library; if not, see
4763+ <https://www.gnu.org/licenses/>. */
4764+
4765+#define __WORDSIZE 32
4766+#define __WORDSIZE_TIME64_COMPAT32 1
4767+#define __WORDSIZE32_SIZE_ULONG 0
4768+#define __WORDSIZE32_PTRDIFF_LONG 0
4769diff --git a/sysdeps/microblaze/utmp-size.h b/sysdeps/microblaze/utmp-size.h
4770new file mode 100644
4771index 0000000000..8f21ebe1b6
4772--- /dev/null
4773+++ b/sysdeps/microblaze/utmp-size.h
4774@@ -0,0 +1,2 @@
4775+#define UTMP_SIZE 384
4776+#define LASTLOG_SIZE 292
4777diff --git a/sysdeps/mips/bits/wordsize.h b/sysdeps/mips/bits/wordsize.h
4778index 57f0f2a22f..30dd3fd85d 100644
4779--- a/sysdeps/mips/bits/wordsize.h
4780+++ b/sysdeps/mips/bits/wordsize.h
4781@@ -19,11 +19,7 @@
4782
4783 #define __WORDSIZE _MIPS_SZPTR
4784
4785-#if _MIPS_SIM == _ABI64
4786-# define __WORDSIZE_TIME64_COMPAT32 1
4787-#else
4788-# define __WORDSIZE_TIME64_COMPAT32 0
4789-#endif
4790+#define __WORDSIZE_TIME64_COMPAT32 1
4791
4792 #if __WORDSIZE == 32
4793 #define __WORDSIZE32_SIZE_ULONG 0
4794diff --git a/sysdeps/mips/mips64/libm-test-ulps b/sysdeps/mips/mips64/libm-test-ulps
4795index 78969745b2..933aba4735 100644
4796--- a/sysdeps/mips/mips64/libm-test-ulps
4797+++ b/sysdeps/mips/mips64/libm-test-ulps
4798@@ -1066,17 +1066,17 @@ double: 1
4799 ldouble: 1
4800
4801 Function: "j0":
4802-double: 2
4803+double: 3
4804 float: 9
4805 ldouble: 2
4806
4807 Function: "j0_downward":
4808-double: 5
4809+double: 6
4810 float: 9
4811 ldouble: 9
4812
4813 Function: "j0_towardzero":
4814-double: 6
4815+double: 7
4816 float: 9
4817 ldouble: 9
4818
4819@@ -1146,6 +1146,7 @@ float: 6
4820 ldouble: 8
4821
4822 Function: "log":
4823+double: 1
4824 float: 1
4825 ldouble: 1
4826
4827diff --git a/sysdeps/mips/utmp-size.h b/sysdeps/mips/utmp-size.h
4828new file mode 100644
4829index 0000000000..8f21ebe1b6
4830--- /dev/null
4831+++ b/sysdeps/mips/utmp-size.h
4832@@ -0,0 +1,2 @@
4833+#define UTMP_SIZE 384
4834+#define LASTLOG_SIZE 292
4835diff --git a/sysdeps/nios2/bits/wordsize.h b/sysdeps/nios2/bits/wordsize.h
4836new file mode 100644
4837index 0000000000..6ecbfe7c86
4838--- /dev/null
4839+++ b/sysdeps/nios2/bits/wordsize.h
4840@@ -0,0 +1,21 @@
4841+/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
4842+ This file is part of the GNU C Library.
4843+
4844+ The GNU C Library is free software; you can redistribute it and/or
4845+ modify it under the terms of the GNU Lesser General Public
4846+ License as published by the Free Software Foundation; either
4847+ version 2.1 of the License, or (at your option) any later version.
4848+
4849+ The GNU C Library is distributed in the hope that it will be useful,
4850+ but WITHOUT ANY WARRANTY; without even the implied warranty of
4851+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4852+ Lesser General Public License for more details.
4853+
4854+ You should have received a copy of the GNU Lesser General Public
4855+ License along with the GNU C Library; if not, see
4856+ <https://www.gnu.org/licenses/>. */
4857+
4858+#define __WORDSIZE 32
4859+#define __WORDSIZE_TIME64_COMPAT32 1
4860+#define __WORDSIZE32_SIZE_ULONG 0
4861+#define __WORDSIZE32_PTRDIFF_LONG 0
4862diff --git a/sysdeps/nios2/utmp-size.h b/sysdeps/nios2/utmp-size.h
4863new file mode 100644
4864index 0000000000..8f21ebe1b6
4865--- /dev/null
4866+++ b/sysdeps/nios2/utmp-size.h
4867@@ -0,0 +1,2 @@
4868+#define UTMP_SIZE 384
4869+#define LASTLOG_SIZE 292
4870diff --git a/sysdeps/or1k/utmp-size.h b/sysdeps/or1k/utmp-size.h
4871new file mode 100644
4872index 0000000000..6b3653aa4d
4873--- /dev/null
4874+++ b/sysdeps/or1k/utmp-size.h
4875@@ -0,0 +1,3 @@
4876+/* or1k has less padding than other architectures with 64-bit time_t. */
4877+#define UTMP_SIZE 392
4878+#define LASTLOG_SIZE 296
4879diff --git a/sysdeps/powerpc/dl-procinfo.c b/sysdeps/powerpc/dl-procinfo.c
4880index a76bb6e5b0..8cf00aa7e3 100644
4881--- a/sysdeps/powerpc/dl-procinfo.c
4882+++ b/sysdeps/powerpc/dl-procinfo.c
4883@@ -38,6 +38,10 @@
4884 needed.
4885 */
4886
4887+/* The total number of available bits (including those prior to
4888+ _DL_HWCAP_FIRST). Some of these bits might not be used. */
4889+#define _DL_HWCAP_COUNT 128
4890+
4891 #ifndef PROCINFO_CLASS
4892 # define PROCINFO_CLASS
4893 #endif
4894@@ -61,7 +65,7 @@ PROCINFO_CLASS struct cpu_features _dl_powerpc_cpu_features
4895 #if !defined PROCINFO_DECL && defined SHARED
4896 ._dl_powerpc_cap_flags
4897 #else
4898-PROCINFO_CLASS const char _dl_powerpc_cap_flags[64][15]
4899+PROCINFO_CLASS const char _dl_powerpc_cap_flags[_DL_HWCAP_COUNT][15]
4900 #endif
4901 #ifndef PROCINFO_DECL
4902 = {
4903diff --git a/sysdeps/powerpc/dl-procinfo.h b/sysdeps/powerpc/dl-procinfo.h
4904index 68f4241095..b36697ba44 100644
4905--- a/sysdeps/powerpc/dl-procinfo.h
4906+++ b/sysdeps/powerpc/dl-procinfo.h
4907@@ -22,22 +22,23 @@
4908 #include <ldsodefs.h>
4909 #include <sysdep.h> /* This defines the PPC_FEATURE[2]_* macros. */
4910
4911-/* The total number of available bits (including those prior to
4912- _DL_HWCAP_FIRST). Some of these bits might not be used. */
4913-#define _DL_HWCAP_COUNT 64
4914+/* Feature masks are all 32-bits in size. */
4915+#define _DL_HWCAP_SIZE 32
4916
4917-/* Features started at bit 31 and decremented as new features were added. */
4918-#define _DL_HWCAP_LAST 31
4919+/* AT_HWCAP2 feature strings follow the AT_HWCAP feature strings. */
4920+#define _DL_HWCAP2_OFFSET _DL_HWCAP_SIZE
4921
4922-/* AT_HWCAP2 features started at bit 31 and decremented as new features were
4923- added. HWCAP2 feature bits start at bit 0. */
4924-#define _DL_HWCAP2_LAST 31
4925+/* AT_HWCAP3 feature strings follow the AT_HWCAP2 feature strings. */
4926+#define _DL_HWCAP3_OFFSET (_DL_HWCAP2_OFFSET + _DL_HWCAP_SIZE)
4927+
4928+/* AT_HWCAP4 feature strings follow the AT_HWCAP3 feature strings. */
4929+#define _DL_HWCAP4_OFFSET (_DL_HWCAP3_OFFSET + _DL_HWCAP_SIZE)
4930
4931 /* These bits influence library search. */
4932 #define HWCAP_IMPORTANT (PPC_FEATURE_HAS_ALTIVEC \
4933 + PPC_FEATURE_HAS_DFP)
4934
4935-#define _DL_PLATFORMS_COUNT 16
4936+#define _DL_PLATFORMS_COUNT 17
4937
4938 #define _DL_FIRST_PLATFORM 32
4939 /* Mask to filter out platforms. */
4940@@ -61,6 +62,7 @@
4941 #define PPC_PLATFORM_POWER8 13
4942 #define PPC_PLATFORM_POWER9 14
4943 #define PPC_PLATFORM_POWER10 15
4944+#define PPC_PLATFORM_POWER11 16
4945
4946 static inline const char *
4947 __attribute__ ((unused))
4948@@ -88,6 +90,11 @@ _dl_string_platform (const char *str)
4949 ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER10;
4950 str++;
4951 }
4952+ else if (str[1] == '1')
4953+ {
4954+ ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER11;
4955+ str++;
4956+ }
4957 else
4958 return -1;
4959 break;
4960@@ -187,21 +194,42 @@ _dl_procinfo (unsigned int type, unsigned long int word)
4961 case AT_HWCAP:
4962 _dl_printf ("AT_HWCAP: ");
4963
4964- for (int i = 0; i <= _DL_HWCAP_LAST; ++i)
4965+ for (int i = 0; i < _DL_HWCAP_SIZE; ++i)
4966 if (word & (1 << i))
4967 _dl_printf (" %s", _dl_hwcap_string (i));
4968 break;
4969 case AT_HWCAP2:
4970 {
4971- unsigned int offset = _DL_HWCAP_LAST + 1;
4972
4973 _dl_printf ("AT_HWCAP2: ");
4974
4975- /* We have to go through them all because the kernel added the
4976- AT_HWCAP2 features starting with the high bits. */
4977- for (int i = 0; i <= _DL_HWCAP2_LAST; ++i)
4978- if (word & (1 << i))
4979- _dl_printf (" %s", _dl_hwcap_string (offset + i));
4980+ /* We have to go through them all because the kernel added the
4981+ AT_HWCAP2 features starting with the high bits. */
4982+ for (int i = 0; i < _DL_HWCAP_SIZE; ++i)
4983+ if (word & (1 << i))
4984+ _dl_printf (" %s", _dl_hwcap_string (_DL_HWCAP2_OFFSET + i));
4985+ break;
4986+ }
4987+ case AT_HWCAP3:
4988+ {
4989+ _dl_printf ("AT_HWCAP3: ");
4990+
4991+ /* We have to go through them all because the kernel added the
4992+ AT_HWCAP3 features starting with the high bits. */
4993+ for (int i = 0; i < _DL_HWCAP_SIZE; ++i)
4994+ if (word & (1 << i))
4995+ _dl_printf (" %s", _dl_hwcap_string (_DL_HWCAP3_OFFSET + i));
4996+ break;
4997+ }
4998+ case AT_HWCAP4:
4999+ {
5000+ _dl_printf ("AT_HWCAP4: ");
5001+
5002+ /* We have to go through them all because the kernel added the
5003+ AT_HWCAP4 features starting with the high bits. */
5004+ for (int i = 0; i <= _DL_HWCAP_SIZE; ++i)
5005+ if (word & (1 << i))
5006+ _dl_printf (" %s", _dl_hwcap_string (_DL_HWCAP4_OFFSET + i));
5007 break;
5008 }
5009 case AT_L1I_CACHEGEOMETRY:
5010diff --git a/sysdeps/powerpc/hwcapinfo.c b/sysdeps/powerpc/hwcapinfo.c
5011index 76344f285a..f6fede15a7 100644
5012--- a/sysdeps/powerpc/hwcapinfo.c
5013+++ b/sysdeps/powerpc/hwcapinfo.c
5014@@ -31,7 +31,7 @@ void
5015 __tcb_parse_hwcap_and_convert_at_platform (void)
5016 {
5017
5018- uint64_t h1, h2;
5019+ uint64_t h1, h2, h3, h4;
5020
5021 /* Read AT_PLATFORM string from auxv and convert it to a number. */
5022 __tcb.at_platform = _dl_string_platform (GLRO (dl_platform));
5023@@ -39,6 +39,8 @@ __tcb_parse_hwcap_and_convert_at_platform (void)
5024 /* Read HWCAP and HWCAP2 from auxv. */
5025 h1 = GLRO (dl_hwcap);
5026 h2 = GLRO (dl_hwcap2);
5027+ h3 = GLRO (dl_hwcap3);
5028+ h4 = GLRO (dl_hwcap4);
5029
5030 /* hwcap contains only the latest supported ISA, the code checks which is
5031 and fills the previous supported ones. */
5032@@ -64,13 +66,16 @@ __tcb_parse_hwcap_and_convert_at_platform (void)
5033 else if (h1 & PPC_FEATURE_POWER5)
5034 h1 |= PPC_FEATURE_POWER4;
5035
5036- uint64_t array_hwcaps[] = { h1, h2 };
5037+ uint64_t array_hwcaps[] = { h1, h2, h3, h4 };
5038 init_cpu_features (&GLRO(dl_powerpc_cpu_features), array_hwcaps);
5039
5040 /* Consolidate both HWCAP and HWCAP2 into a single doubleword so that
5041 we can read both in a single load later. */
5042 __tcb.hwcap = (h1 << 32) | (h2 & 0xffffffff);
5043- __tcb.hwcap_extn = 0x0;
5044+
5045+ /* Consolidate both HWCAP3 and HWCAP4 into a single doubleword so that
5046+ we can read both in a single load later. */
5047+ __tcb.hwcap_extn = (h3 << 32) | (h4 & 0xffffffff);
5048
5049 }
5050 #if IS_IN (rtld)
5051diff --git a/sysdeps/powerpc/powerpc32/bits/wordsize.h b/sysdeps/powerpc/powerpc32/bits/wordsize.h
5052index 04ca9debf0..6993fb6b29 100644
5053--- a/sysdeps/powerpc/powerpc32/bits/wordsize.h
5054+++ b/sysdeps/powerpc/powerpc32/bits/wordsize.h
5055@@ -2,10 +2,9 @@
5056
5057 #if defined __powerpc64__
5058 # define __WORDSIZE 64
5059-# define __WORDSIZE_TIME64_COMPAT32 1
5060 #else
5061 # define __WORDSIZE 32
5062-# define __WORDSIZE_TIME64_COMPAT32 0
5063 # define __WORDSIZE32_SIZE_ULONG 0
5064 # define __WORDSIZE32_PTRDIFF_LONG 0
5065 #endif
5066+#define __WORDSIZE_TIME64_COMPAT32 1
5067diff --git a/sysdeps/powerpc/powerpc32/power11/Implies b/sysdeps/powerpc/powerpc32/power11/Implies
5068new file mode 100644
5069index 0000000000..051cbe0f79
5070--- /dev/null
5071+++ b/sysdeps/powerpc/powerpc32/power11/Implies
5072@@ -0,0 +1,2 @@
5073+powerpc/powerpc32/power10/fpu
5074+powerpc/powerpc32/power10
5075diff --git a/sysdeps/powerpc/powerpc32/power11/fpu/multiarch/Implies b/sysdeps/powerpc/powerpc32/power11/fpu/multiarch/Implies
5076new file mode 100644
5077index 0000000000..58edb2861d
5078--- /dev/null
5079+++ b/sysdeps/powerpc/powerpc32/power11/fpu/multiarch/Implies
5080@@ -0,0 +1 @@
5081+powerpc/powerpc32/power10/fpu/multiarch
5082diff --git a/sysdeps/powerpc/powerpc32/power11/multiarch/Implies b/sysdeps/powerpc/powerpc32/power11/multiarch/Implies
5083new file mode 100644
5084index 0000000000..c70f0428ba
5085--- /dev/null
5086+++ b/sysdeps/powerpc/powerpc32/power11/multiarch/Implies
5087@@ -0,0 +1 @@
5088+powerpc/powerpc32/power10/multiarch
5089diff --git a/sysdeps/powerpc/powerpc64/be/power11/Implies b/sysdeps/powerpc/powerpc64/be/power11/Implies
5090new file mode 100644
5091index 0000000000..de481d1c13
5092--- /dev/null
5093+++ b/sysdeps/powerpc/powerpc64/be/power11/Implies
5094@@ -0,0 +1,2 @@
5095+powerpc/powerpc64/be/power10/fpu
5096+powerpc/powerpc64/be/power10
5097diff --git a/sysdeps/powerpc/powerpc64/be/power11/fpu/Implies b/sysdeps/powerpc/powerpc64/be/power11/fpu/Implies
5098new file mode 100644
5099index 0000000000..dff0e13064
5100--- /dev/null
5101+++ b/sysdeps/powerpc/powerpc64/be/power11/fpu/Implies
5102@@ -0,0 +1 @@
5103+powerpc/powerpc64/be/power10/fpu
5104diff --git a/sysdeps/powerpc/powerpc64/be/power11/fpu/multiarch/Implies b/sysdeps/powerpc/powerpc64/be/power11/fpu/multiarch/Implies
5105new file mode 100644
5106index 0000000000..c3f259e009
5107--- /dev/null
5108+++ b/sysdeps/powerpc/powerpc64/be/power11/fpu/multiarch/Implies
5109@@ -0,0 +1 @@
5110+powerpc/powerpc64/be/power10/fpu/multiarch
5111diff --git a/sysdeps/powerpc/powerpc64/be/power11/multiarch/Implies b/sysdeps/powerpc/powerpc64/be/power11/multiarch/Implies
5112new file mode 100644
5113index 0000000000..9491a394c9
5114--- /dev/null
5115+++ b/sysdeps/powerpc/powerpc64/be/power11/multiarch/Implies
5116@@ -0,0 +1 @@
5117+powerpc/powerpc64/be/power10/multiarch
5118diff --git a/sysdeps/powerpc/powerpc64/bits/wordsize.h b/sysdeps/powerpc/powerpc64/bits/wordsize.h
5119index 04ca9debf0..6993fb6b29 100644
5120--- a/sysdeps/powerpc/powerpc64/bits/wordsize.h
5121+++ b/sysdeps/powerpc/powerpc64/bits/wordsize.h
5122@@ -2,10 +2,9 @@
5123
5124 #if defined __powerpc64__
5125 # define __WORDSIZE 64
5126-# define __WORDSIZE_TIME64_COMPAT32 1
5127 #else
5128 # define __WORDSIZE 32
5129-# define __WORDSIZE_TIME64_COMPAT32 0
5130 # define __WORDSIZE32_SIZE_ULONG 0
5131 # define __WORDSIZE32_PTRDIFF_LONG 0
5132 #endif
5133+#define __WORDSIZE_TIME64_COMPAT32 1
5134diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
5135index c6682f3445..2b6f5d2b08 100644
5136--- a/sysdeps/powerpc/powerpc64/dl-machine.h
5137+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
5138@@ -78,6 +78,7 @@ elf_host_tolerates_class (const Elf64_Ehdr *ehdr)
5139 static inline Elf64_Addr
5140 elf_machine_load_address (void) __attribute__ ((const));
5141
5142+#ifndef __PCREL__
5143 static inline Elf64_Addr
5144 elf_machine_load_address (void)
5145 {
5146@@ -105,6 +106,24 @@ elf_machine_dynamic (void)
5147 /* Then subtract off the load address offset. */
5148 return runtime_dynamic - elf_machine_load_address() ;
5149 }
5150+#else /* __PCREL__ */
5151+/* In PCREL mode, r2 may have been clobbered. Rely on relative
5152+ relocations instead. */
5153+
5154+static inline ElfW(Addr)
5155+elf_machine_load_address (void)
5156+{
5157+ extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
5158+ return (ElfW(Addr)) &__ehdr_start;
5159+}
5160+
5161+static inline ElfW(Addr)
5162+elf_machine_dynamic (void)
5163+{
5164+ extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
5165+ return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address ();
5166+}
5167+#endif /* __PCREL__ */
5168
5169 /* The PLT uses Elf64_Rela relocs. */
5170 #define elf_machine_relplt elf_machine_rela
5171diff --git a/sysdeps/powerpc/powerpc64/le/power11/Implies b/sysdeps/powerpc/powerpc64/le/power11/Implies
5172new file mode 100644
5173index 0000000000..e18182dcc1
5174--- /dev/null
5175+++ b/sysdeps/powerpc/powerpc64/le/power11/Implies
5176@@ -0,0 +1,2 @@
5177+powerpc/powerpc64/le/power10/fpu
5178+powerpc/powerpc64/le/power10
5179diff --git a/sysdeps/powerpc/powerpc64/le/power11/fpu/Implies b/sysdeps/powerpc/powerpc64/le/power11/fpu/Implies
5180new file mode 100644
5181index 0000000000..e41bd55684
5182--- /dev/null
5183+++ b/sysdeps/powerpc/powerpc64/le/power11/fpu/Implies
5184@@ -0,0 +1 @@
5185+powerpc/powerpc64/le/power10/fpu
5186diff --git a/sysdeps/powerpc/powerpc64/le/power11/fpu/multiarch/Implies b/sysdeps/powerpc/powerpc64/le/power11/fpu/multiarch/Implies
5187new file mode 100644
5188index 0000000000..c838d50931
5189--- /dev/null
5190+++ b/sysdeps/powerpc/powerpc64/le/power11/fpu/multiarch/Implies
5191@@ -0,0 +1 @@
5192+powerpc/powerpc64/le/power10/fpu/multiarch
5193diff --git a/sysdeps/powerpc/powerpc64/le/power11/multiarch/Implies b/sysdeps/powerpc/powerpc64/le/power11/multiarch/Implies
5194new file mode 100644
5195index 0000000000..687248c3c2
5196--- /dev/null
5197+++ b/sysdeps/powerpc/powerpc64/le/power11/multiarch/Implies
5198@@ -0,0 +1 @@
5199+powerpc/powerpc64/le/power10/multiarch
5200diff --git a/sysdeps/powerpc/powerpc64/le/tst-glibc-hwcaps.c b/sysdeps/powerpc/powerpc64/le/tst-glibc-hwcaps.c
5201index 77465d9133..65d3e69303 100644
5202--- a/sysdeps/powerpc/powerpc64/le/tst-glibc-hwcaps.c
5203+++ b/sysdeps/powerpc/powerpc64/le/tst-glibc-hwcaps.c
5204@@ -36,9 +36,11 @@ compute_level (void)
5205 return 9;
5206 if (strcmp (platform, "power10") == 0)
5207 return 10;
5208+ if (strcmp (platform, "power11") == 0)
5209+ return 11;
5210 printf ("warning: unrecognized AT_PLATFORM value: %s\n", platform);
5211- /* Assume that the new platform supports POWER10. */
5212- return 10;
5213+ /* Assume that the new platform supports POWER11. */
5214+ return 11;
5215 }
5216
5217 static int
5218diff --git a/sysdeps/powerpc/preconfigure b/sysdeps/powerpc/preconfigure
5219index 4de94089a3..9e5a07ab6d 100644
5220--- a/sysdeps/powerpc/preconfigure
5221+++ b/sysdeps/powerpc/preconfigure
5222@@ -58,7 +58,7 @@ fi
5223
5224 ;;
5225
5226- a2|970|power[4-9]|power5x|power6+|power10)
5227+ a2|970|power[4-9]|power5x|power6+|power10|power11)
5228 submachine=${archcpu}
5229 if test ${libc_cv_cc_submachine+y}
5230 then :
5231diff --git a/sysdeps/powerpc/preconfigure.ac b/sysdeps/powerpc/preconfigure.ac
5232index 6c63bd8257..14b6dafd4a 100644
5233--- a/sysdeps/powerpc/preconfigure.ac
5234+++ b/sysdeps/powerpc/preconfigure.ac
5235@@ -46,7 +46,7 @@ case "${machine}:${submachine}" in
5236 AC_CACHE_VAL(libc_cv_cc_submachine,libc_cv_cc_submachine="")
5237 ;;
5238
5239- a2|970|power[[4-9]]|power5x|power6+|power10)
5240+ a2|970|power[[4-9]]|power5x|power6+|power10|power11)
5241 submachine=${archcpu}
5242 AC_CACHE_VAL(libc_cv_cc_submachine,libc_cv_cc_submachine="")
5243 ;;
5244diff --git a/sysdeps/powerpc/utmp-size.h b/sysdeps/powerpc/utmp-size.h
5245new file mode 100644
5246index 0000000000..8f21ebe1b6
5247--- /dev/null
5248+++ b/sysdeps/powerpc/utmp-size.h
5249@@ -0,0 +1,2 @@
5250+#define UTMP_SIZE 384
5251+#define LASTLOG_SIZE 292
5252diff --git a/sysdeps/pthread/tst-cancel30.c b/sysdeps/pthread/tst-cancel30.c
5253index 3030660e5f..94ad6281bc 100644
5254--- a/sysdeps/pthread/tst-cancel30.c
5255+++ b/sysdeps/pthread/tst-cancel30.c
5256@@ -18,6 +18,7 @@
5257 License along with the GNU C Library; if not, see
5258 <https://www.gnu.org/licenses/>. */
5259
5260+#include <errno.h>
5261 #include <support/check.h>
5262 #include <support/xstdio.h>
5263 #include <support/xthread.h>
5264@@ -46,13 +47,19 @@ tf (void *arg)
5265
5266 /* Wait indefinitely for cancellation, which only works if asynchronous
5267 cancellation is enabled. */
5268-#if defined SYS_ppoll || defined SYS_ppoll_time64
5269-# ifndef SYS_ppoll_time64
5270-# define SYS_ppoll_time64 SYS_ppoll
5271+#ifdef SYS_ppoll_time64
5272+ long int ret = syscall (SYS_ppoll_time64, NULL, 0, NULL, NULL);
5273+ (void) ret;
5274+# ifdef SYS_ppoll
5275+ if (ret == -1 && errno == ENOSYS)
5276+ syscall (SYS_ppoll, NULL, 0, NULL, NULL);
5277 # endif
5278- syscall (SYS_ppoll_time64, NULL, 0, NULL, NULL);
5279 #else
5280+# ifdef SYS_ppoll
5281+ syscall (SYS_ppoll, NULL, 0, NULL, NULL);
5282+# else
5283 for (;;);
5284+# endif
5285 #endif
5286
5287 return 0;
5288diff --git a/sysdeps/riscv/utmp-size.h b/sysdeps/riscv/utmp-size.h
5289new file mode 100644
5290index 0000000000..8f21ebe1b6
5291--- /dev/null
5292+++ b/sysdeps/riscv/utmp-size.h
5293@@ -0,0 +1,2 @@
5294+#define UTMP_SIZE 384
5295+#define LASTLOG_SIZE 292
5296diff --git a/sysdeps/sh/bits/wordsize.h b/sysdeps/sh/bits/wordsize.h
5297new file mode 100644
5298index 0000000000..6ecbfe7c86
5299--- /dev/null
5300+++ b/sysdeps/sh/bits/wordsize.h
5301@@ -0,0 +1,21 @@
5302+/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
5303+ This file is part of the GNU C Library.
5304+
5305+ The GNU C Library is free software; you can redistribute it and/or
5306+ modify it under the terms of the GNU Lesser General Public
5307+ License as published by the Free Software Foundation; either
5308+ version 2.1 of the License, or (at your option) any later version.
5309+
5310+ The GNU C Library is distributed in the hope that it will be useful,
5311+ but WITHOUT ANY WARRANTY; without even the implied warranty of
5312+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5313+ Lesser General Public License for more details.
5314+
5315+ You should have received a copy of the GNU Lesser General Public
5316+ License along with the GNU C Library; if not, see
5317+ <https://www.gnu.org/licenses/>. */
5318+
5319+#define __WORDSIZE 32
5320+#define __WORDSIZE_TIME64_COMPAT32 1
5321+#define __WORDSIZE32_SIZE_ULONG 0
5322+#define __WORDSIZE32_PTRDIFF_LONG 0
5323diff --git a/sysdeps/sh/utmp-size.h b/sysdeps/sh/utmp-size.h
5324new file mode 100644
5325index 0000000000..8f21ebe1b6
5326--- /dev/null
5327+++ b/sysdeps/sh/utmp-size.h
5328@@ -0,0 +1,2 @@
5329+#define UTMP_SIZE 384
5330+#define LASTLOG_SIZE 292
5331diff --git a/sysdeps/sparc/sparc32/bits/wordsize.h b/sysdeps/sparc/sparc32/bits/wordsize.h
5332index 4bbd2e63b4..a2e79e0fa9 100644
5333--- a/sysdeps/sparc/sparc32/bits/wordsize.h
5334+++ b/sysdeps/sparc/sparc32/bits/wordsize.h
5335@@ -1,6 +1,6 @@
5336 /* Determine the wordsize from the preprocessor defines. */
5337
5338 #define __WORDSIZE 32
5339-#define __WORDSIZE_TIME64_COMPAT32 0
5340+#define __WORDSIZE_TIME64_COMPAT32 1
5341 #define __WORDSIZE32_SIZE_ULONG 0
5342 #define __WORDSIZE32_PTRDIFF_LONG 0
5343diff --git a/sysdeps/sparc/sparc64/bits/wordsize.h b/sysdeps/sparc/sparc64/bits/wordsize.h
5344index 2f66f10d72..ea103e5970 100644
5345--- a/sysdeps/sparc/sparc64/bits/wordsize.h
5346+++ b/sysdeps/sparc/sparc64/bits/wordsize.h
5347@@ -2,10 +2,9 @@
5348
5349 #if defined __arch64__ || defined __sparcv9
5350 # define __WORDSIZE 64
5351-# define __WORDSIZE_TIME64_COMPAT32 1
5352 #else
5353 # define __WORDSIZE 32
5354-# define __WORDSIZE_TIME64_COMPAT32 0
5355 # define __WORDSIZE32_SIZE_ULONG 0
5356 # define __WORDSIZE32_PTRDIFF_LONG 0
5357 #endif
5358+#define __WORDSIZE_TIME64_COMPAT32 1
5359diff --git a/sysdeps/sparc/sparc64/rtld-memset.c b/sysdeps/sparc/sparc64/rtld-memset.c
5360index 55f3835790..a19202a620 100644
5361--- a/sysdeps/sparc/sparc64/rtld-memset.c
5362+++ b/sysdeps/sparc/sparc64/rtld-memset.c
5363@@ -1 +1,4 @@
5364 #include <string/memset.c>
5365+#if IS_IN(rtld)
5366+strong_alias (memset, __memset_ultra1)
5367+#endif
5368diff --git a/sysdeps/sparc/utmp-size.h b/sysdeps/sparc/utmp-size.h
5369new file mode 100644
5370index 0000000000..8f21ebe1b6
5371--- /dev/null
5372+++ b/sysdeps/sparc/utmp-size.h
5373@@ -0,0 +1,2 @@
5374+#define UTMP_SIZE 384
5375+#define LASTLOG_SIZE 292
5376diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
5377index b1a3f673f0..c0b047bc0d 100644
5378--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
5379+++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
5380@@ -21,6 +21,7 @@
5381 #include <sys/auxv.h>
5382 #include <elf/dl-hwcaps.h>
5383 #include <sys/prctl.h>
5384+#include <sys/utsname.h>
5385 #include <dl-tunables-parse.h>
5386
5387 #define DCZID_DZP_MASK (1 << 4)
5388@@ -62,6 +63,46 @@ get_midr_from_mcpu (const struct tunable_str_t *mcpu)
5389 return UINT64_MAX;
5390 }
5391
5392+#if __LINUX_KERNEL_VERSION < 0x060200
5393+
5394+/* Return true if we prefer using SVE in string ifuncs. Old kernels disable
5395+ SVE after every system call which results in unnecessary traps if memcpy
5396+ uses SVE. This is true for kernels between 4.15.0 and before 6.2.0, except
5397+ for 5.14.0 which was patched. For these versions return false to avoid using
5398+ SVE ifuncs.
5399+ Parse the kernel version into a 24-bit kernel.major.minor value without
5400+ calling any library functions. If uname() is not supported or if the version
5401+ format is not recognized, assume the kernel is modern and return true. */
5402+
5403+static inline bool
5404+prefer_sve_ifuncs (void)
5405+{
5406+ struct utsname buf;
5407+ const char *p = &buf.release[0];
5408+ int kernel = 0;
5409+ int val;
5410+
5411+ if (__uname (&buf) < 0)
5412+ return true;
5413+
5414+ for (int shift = 16; shift >= 0; shift -= 8)
5415+ {
5416+ for (val = 0; *p >= '0' && *p <= '9'; p++)
5417+ val = val * 10 + *p - '0';
5418+ kernel |= (val & 255) << shift;
5419+ if (*p++ != '.')
5420+ break;
5421+ }
5422+
5423+ if (kernel >= 0x060200 || kernel == 0x050e00)
5424+ return true;
5425+ if (kernel >= 0x040f00)
5426+ return false;
5427+ return true;
5428+}
5429+
5430+#endif
5431+
5432 static inline void
5433 init_cpu_features (struct cpu_features *cpu_features)
5434 {
5435@@ -126,6 +167,13 @@ init_cpu_features (struct cpu_features *cpu_features)
5436 /* Check if SVE is supported. */
5437 cpu_features->sve = GLRO (dl_hwcap) & HWCAP_SVE;
5438
5439+ cpu_features->prefer_sve_ifuncs = cpu_features->sve;
5440+
5441+#if __LINUX_KERNEL_VERSION < 0x060200
5442+ if (cpu_features->sve)
5443+ cpu_features->prefer_sve_ifuncs = prefer_sve_ifuncs ();
5444+#endif
5445+
5446 /* Check if MOPS is supported. */
5447 cpu_features->mops = GLRO (dl_hwcap2) & HWCAP2_MOPS;
5448 }
5449diff --git a/sysdeps/unix/sysv/linux/dl-parse_auxv.h b/sysdeps/unix/sysv/linux/dl-parse_auxv.h
5450index e3d758b163..ea2a58ecb1 100644
5451--- a/sysdeps/unix/sysv/linux/dl-parse_auxv.h
5452+++ b/sysdeps/unix/sysv/linux/dl-parse_auxv.h
5453@@ -47,6 +47,8 @@ void _dl_parse_auxv (ElfW(auxv_t) *av, dl_parse_auxv_t auxv_values)
5454 GLRO(dl_platform) = (void *) auxv_values[AT_PLATFORM];
5455 GLRO(dl_hwcap) = auxv_values[AT_HWCAP];
5456 GLRO(dl_hwcap2) = auxv_values[AT_HWCAP2];
5457+ GLRO(dl_hwcap3) = auxv_values[AT_HWCAP3];
5458+ GLRO(dl_hwcap4) = auxv_values[AT_HWCAP4];
5459 GLRO(dl_clktck) = auxv_values[AT_CLKTCK];
5460 GLRO(dl_fpu_control) = auxv_values[AT_FPUCW];
5461 _dl_random = (void *) auxv_values[AT_RANDOM];
5462diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c
5463index ad3692d738..e1b14e9eb3 100644
5464--- a/sysdeps/unix/sysv/linux/dl-sysdep.c
5465+++ b/sysdeps/unix/sysv/linux/dl-sysdep.c
5466@@ -197,6 +197,8 @@ _dl_show_auxv (void)
5467 [AT_SYSINFO_EHDR - 2] = { "SYSINFO_EHDR: 0x", hex },
5468 [AT_RANDOM - 2] = { "RANDOM: 0x", hex },
5469 [AT_HWCAP2 - 2] = { "HWCAP2: 0x", hex },
5470+ [AT_HWCAP3 - 2] = { "HWCAP3: 0x", hex },
5471+ [AT_HWCAP4 - 2] = { "HWCAP4: 0x", hex },
5472 [AT_MINSIGSTKSZ - 2] = { "MINSIGSTKSZ: ", dec },
5473 [AT_L1I_CACHESIZE - 2] = { "L1I_CACHESIZE: ", dec },
5474 [AT_L1I_CACHEGEOMETRY - 2] = { "L1I_CACHEGEOMETRY: 0x", hex },
5475diff --git a/sysdeps/unix/sysv/linux/hppa/bits/wordsize.h b/sysdeps/unix/sysv/linux/hppa/bits/wordsize.h
5476new file mode 100644
5477index 0000000000..6ecbfe7c86
5478--- /dev/null
5479+++ b/sysdeps/unix/sysv/linux/hppa/bits/wordsize.h
5480@@ -0,0 +1,21 @@
5481+/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
5482+ This file is part of the GNU C Library.
5483+
5484+ The GNU C Library is free software; you can redistribute it and/or
5485+ modify it under the terms of the GNU Lesser General Public
5486+ License as published by the Free Software Foundation; either
5487+ version 2.1 of the License, or (at your option) any later version.
5488+
5489+ The GNU C Library is distributed in the hope that it will be useful,
5490+ but WITHOUT ANY WARRANTY; without even the implied warranty of
5491+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5492+ Lesser General Public License for more details.
5493+
5494+ You should have received a copy of the GNU Lesser General Public
5495+ License along with the GNU C Library; if not, see
5496+ <https://www.gnu.org/licenses/>. */
5497+
5498+#define __WORDSIZE 32
5499+#define __WORDSIZE_TIME64_COMPAT32 1
5500+#define __WORDSIZE32_SIZE_ULONG 0
5501+#define __WORDSIZE32_PTRDIFF_LONG 0
5502diff --git a/sysdeps/unix/sysv/linux/mips/clone3.S b/sysdeps/unix/sysv/linux/mips/clone3.S
5503index e9fec2fa47..481b8ae963 100644
5504--- a/sysdeps/unix/sysv/linux/mips/clone3.S
5505+++ b/sysdeps/unix/sysv/linux/mips/clone3.S
5506@@ -37,11 +37,6 @@
5507
5508 .text
5509 .set nomips16
5510-#if _MIPS_SIM == _ABIO32
5511-# define EXTRA_LOCALS 1
5512-#else
5513-# define EXTRA_LOCALS 0
5514-#endif
5515 #define FRAMESZ ((NARGSAVE*SZREG)+ALSZ)&ALMASK
5516 GPOFF= FRAMESZ-(1*SZREG)
5517 NESTED(__clone3, SZREG, sp)
5518@@ -68,8 +63,31 @@ NESTED(__clone3, SZREG, sp)
5519 beqz a0, L(error) /* No NULL cl_args pointer. */
5520 beqz a2, L(error) /* No NULL function pointer. */
5521
5522+#if _MIPS_SIM == _ABIO32
5523+ /* Both stack and stack_size on clone_args are defined as uint64_t, and
5524+ there is no need to handle values larger than to 32 bits for o32. */
5525+# if __BYTE_ORDER == __BIG_ENDIAN
5526+# define CL_STACKPOINTER_OFFSET 44
5527+# define CL_STACKSIZE_OFFSET 52
5528+# else
5529+# define CL_STACKPOINTER_OFFSET 40
5530+# define CL_STACKSIZE_OFFSET 48
5531+# endif
5532+
5533+ /* For o32 we need to setup a minimal stack frame to allow cprestore
5534+ on __thread_start_clone3. Also there is no guarantee by kABI that
5535+ $8 will be preserved after syscall execution (so we need to save it
5536+ on the provided stack). */
5537+ lw t0, CL_STACKPOINTER_OFFSET(a0) /* Load the stack pointer. */
5538+ lw t1, CL_STACKSIZE_OFFSET(a0) /* Load the stack_size. */
5539+ addiu t1, -32 /* Update the stack size. */
5540+ addu t2, t1, t0 /* Calculate the thread stack. */
5541+ sw a3, 0(t2) /* Save argument pointer. */
5542+ sw t1, CL_STACKSIZE_OFFSET(a0) /* Save the new stack size. */
5543+#else
5544 move $8, a3 /* a3 is set to 0/1 for syscall success/error
5545 while a4/$8 is returned unmodified. */
5546+#endif
5547
5548 /* Do the system call, the kernel expects:
5549 v0: system call number
5550@@ -125,7 +143,11 @@ L(thread_start_clone3):
5551
5552 /* Restore the arg for user's function. */
5553 move t9, a2 /* Function pointer. */
5554+#if _MIPS_SIM == _ABIO32
5555+ PTR_L a0, 0(sp)
5556+#else
5557 move a0, $8 /* Argument pointer. */
5558+#endif
5559
5560 /* Call the user's function. */
5561 jal t9
5562diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h b/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h
5563index 04ca9debf0..6993fb6b29 100644
5564--- a/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h
5565+++ b/sysdeps/unix/sysv/linux/powerpc/bits/wordsize.h
5566@@ -2,10 +2,9 @@
5567
5568 #if defined __powerpc64__
5569 # define __WORDSIZE 64
5570-# define __WORDSIZE_TIME64_COMPAT32 1
5571 #else
5572 # define __WORDSIZE 32
5573-# define __WORDSIZE_TIME64_COMPAT32 0
5574 # define __WORDSIZE32_SIZE_ULONG 0
5575 # define __WORDSIZE32_PTRDIFF_LONG 0
5576 #endif
5577+#define __WORDSIZE_TIME64_COMPAT32 1
5578diff --git a/sysdeps/unix/sysv/linux/powerpc/cpu-features.c b/sysdeps/unix/sysv/linux/powerpc/cpu-features.c
5579index 8e8a5ec2ea..a947d62db6 100644
5580--- a/sysdeps/unix/sysv/linux/powerpc/cpu-features.c
5581+++ b/sysdeps/unix/sysv/linux/powerpc/cpu-features.c
5582@@ -94,6 +94,8 @@ init_cpu_features (struct cpu_features *cpu_features, uint64_t hwcaps[])
5583 which are set by __tcb_parse_hwcap_and_convert_at_platform. */
5584 cpu_features->hwcap = hwcaps[0];
5585 cpu_features->hwcap2 = hwcaps[1];
5586+ cpu_features->hwcap3 = hwcaps[2];
5587+ cpu_features->hwcap4 = hwcaps[3];
5588 /* Default is to use aligned memory access on optimized function unless
5589 tunables is enable, since for this case user can explicit disable
5590 unaligned optimizations. */
5591diff --git a/sysdeps/unix/sysv/linux/powerpc/cpu-features.h b/sysdeps/unix/sysv/linux/powerpc/cpu-features.h
5592index 1294f0b601..e9eb6a13c8 100644
5593--- a/sysdeps/unix/sysv/linux/powerpc/cpu-features.h
5594+++ b/sysdeps/unix/sysv/linux/powerpc/cpu-features.h
5595@@ -26,6 +26,8 @@ struct cpu_features
5596 bool use_cached_memopt;
5597 unsigned long int hwcap;
5598 unsigned long int hwcap2;
5599+ unsigned long int hwcap3;
5600+ unsigned long int hwcap4;
5601 };
5602
5603 static const char hwcap_names[] = {
5604diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
5605index a4705daf1c..6a00cd88cd 100644
5606--- a/sysdeps/unix/sysv/linux/powerpc/libc-start.c
5607+++ b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
5608@@ -87,6 +87,12 @@ __libc_start_main_impl (int argc, char **argv,
5609 case AT_HWCAP2:
5610 _dl_hwcap2 = (unsigned long int) av->a_un.a_val;
5611 break;
5612+ case AT_HWCAP3:
5613+ _dl_hwcap3 = (unsigned long int) av->a_un.a_val;
5614+ break;
5615+ case AT_HWCAP4:
5616+ _dl_hwcap4 = (unsigned long int) av->a_un.a_val;
5617+ break;
5618 case AT_PLATFORM:
5619 _dl_platform = (void *) av->a_un.a_val;
5620 break;
5621diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/clone.S b/sysdeps/unix/sysv/linux/s390/s390-32/clone.S
5622index 4c882ef2ee..a7a863242c 100644
5623--- a/sysdeps/unix/sysv/linux/s390/s390-32/clone.S
5624+++ b/sysdeps/unix/sysv/linux/s390/s390-32/clone.S
5625@@ -53,6 +53,7 @@ ENTRY(__clone)
5626 br %r14
5627 error:
5628 lhi %r2,-EINVAL
5629+ lm %r6,%r7,24(%r15) /* Load registers. */
5630 j SYSCALL_ERROR_LABEL
5631 PSEUDO_END (__clone)
5632
5633diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/clone.S b/sysdeps/unix/sysv/linux/s390/s390-64/clone.S
5634index 4eb104be71..c552a6b8de 100644
5635--- a/sysdeps/unix/sysv/linux/s390/s390-64/clone.S
5636+++ b/sysdeps/unix/sysv/linux/s390/s390-64/clone.S
5637@@ -54,6 +54,7 @@ ENTRY(__clone)
5638 br %r14
5639 error:
5640 lghi %r2,-EINVAL
5641+ lmg %r6,%r7,48(%r15) /* Restore registers. */
5642 jg SYSCALL_ERROR_LABEL
5643 PSEUDO_END (__clone)
5644
5645diff --git a/sysdeps/unix/sysv/linux/sched_getcpu.c b/sysdeps/unix/sysv/linux/sched_getcpu.c
5646index dfb884568d..72a3360550 100644
5647--- a/sysdeps/unix/sysv/linux/sched_getcpu.c
5648+++ b/sysdeps/unix/sysv/linux/sched_getcpu.c
5649@@ -33,17 +33,9 @@ vsyscall_sched_getcpu (void)
5650 return r == -1 ? r : cpu;
5651 }
5652
5653-#ifdef RSEQ_SIG
5654 int
5655 sched_getcpu (void)
5656 {
5657 int cpu_id = THREAD_GETMEM_VOLATILE (THREAD_SELF, rseq_area.cpu_id);
5658 return __glibc_likely (cpu_id >= 0) ? cpu_id : vsyscall_sched_getcpu ();
5659 }
5660-#else /* RSEQ_SIG */
5661-int
5662-sched_getcpu (void)
5663-{
5664- return vsyscall_sched_getcpu ();
5665-}
5666-#endif /* RSEQ_SIG */
5667diff --git a/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h b/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h
5668index 7562875ee2..ea103e5970 100644
5669--- a/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h
5670+++ b/sysdeps/unix/sysv/linux/sparc/bits/wordsize.h
5671@@ -2,10 +2,9 @@
5672
5673 #if defined __arch64__ || defined __sparcv9
5674 # define __WORDSIZE 64
5675-# define __WORDSIZE_TIME64_COMPAT32 1
5676 #else
5677 # define __WORDSIZE 32
5678 # define __WORDSIZE32_SIZE_ULONG 0
5679 # define __WORDSIZE32_PTRDIFF_LONG 0
5680-# define __WORDSIZE_TIME64_COMPAT32 0
5681 #endif
5682+#define __WORDSIZE_TIME64_COMPAT32 1
5683diff --git a/sysdeps/unix/sysv/linux/timespec_get.c b/sysdeps/unix/sysv/linux/timespec_get.c
5684index c6e5e66289..778d1e3354 100644
5685--- a/sysdeps/unix/sysv/linux/timespec_get.c
5686+++ b/sysdeps/unix/sysv/linux/timespec_get.c
5687@@ -5,7 +5,7 @@
5688 The GNU C Library is free software; you can redistribute it and/or
5689 modify it under the terms of the GNU Lesser General Public
5690 License as published by the Free Software Foundation; either
5691- version 2.1 of the License.
5692+ version 2.1 of the License, or (at your option) any later version.
5693
5694 The GNU C Library is distributed in the hope that it will be useful,
5695 but WITHOUT ANY WARRANTY; without even the implied warranty of
5696diff --git a/sysdeps/unix/sysv/linux/timespec_getres.c b/sysdeps/unix/sysv/linux/timespec_getres.c
5697index 5acebe2a2c..2eef9e512c 100644
5698--- a/sysdeps/unix/sysv/linux/timespec_getres.c
5699+++ b/sysdeps/unix/sysv/linux/timespec_getres.c
5700@@ -5,7 +5,7 @@
5701 The GNU C Library is free software; you can redistribute it and/or
5702 modify it under the terms of the GNU Lesser General Public
5703 License as published by the Free Software Foundation; either
5704- version 2.1 of the License.
5705+ version 2.1 of the License, or (at your option) any later version.
5706
5707 The GNU C Library is distributed in the hope that it will be useful,
5708 but WITHOUT ANY WARRANTY; without even the implied warranty of
5709diff --git a/sysdeps/unix/sysv/linux/tst-clone.c b/sysdeps/unix/sysv/linux/tst-clone.c
5710index 470676ab2b..2bc7124983 100644
5711--- a/sysdeps/unix/sysv/linux/tst-clone.c
5712+++ b/sysdeps/unix/sysv/linux/tst-clone.c
5713@@ -16,12 +16,16 @@
5714 License along with the GNU C Library; if not, see
5715 <https://www.gnu.org/licenses/>. */
5716
5717-/* BZ #2386 */
5718+/* BZ #2386, BZ #31402 */
5719 #include <errno.h>
5720 #include <stdio.h>
5721 #include <stdlib.h>
5722 #include <unistd.h>
5723 #include <sched.h>
5724+#include <stackinfo.h> /* For _STACK_GROWS_{UP,DOWN}. */
5725+#include <support/check.h>
5726+
5727+volatile unsigned v = 0xdeadbeef;
5728
5729 int child_fn(void *arg)
5730 {
5731@@ -30,22 +34,67 @@ int child_fn(void *arg)
5732 }
5733
5734 static int
5735-do_test (void)
5736+__attribute__((noinline))
5737+do_clone (int (*fn)(void *), void *stack)
5738 {
5739 int result;
5740+ unsigned int a = v;
5741+ unsigned int b = v;
5742+ unsigned int c = v;
5743+ unsigned int d = v;
5744+ unsigned int e = v;
5745+ unsigned int f = v;
5746+ unsigned int g = v;
5747+ unsigned int h = v;
5748+ unsigned int i = v;
5749+ unsigned int j = v;
5750+ unsigned int k = v;
5751+ unsigned int l = v;
5752+ unsigned int m = v;
5753+ unsigned int n = v;
5754+ unsigned int o = v;
5755+
5756+ result = clone (fn, stack, 0, NULL);
5757+
5758+ /* Check that clone does not clobber call-saved registers. */
5759+ TEST_VERIFY (a == v && b == v && c == v && d == v && e == v && f == v
5760+ && g == v && h == v && i == v && j == v && k == v && l == v
5761+ && m == v && n == v && o == v);
5762+
5763+ return result;
5764+}
5765+
5766+static void
5767+__attribute__((noinline))
5768+do_test_single (int (*fn)(void *), void *stack)
5769+{
5770+ printf ("%s (fn=%p, stack=%p)\n", __FUNCTION__, fn, stack);
5771+ errno = 0;
5772+
5773+ int result = do_clone (fn, stack);
5774+
5775+ TEST_COMPARE (errno, EINVAL);
5776+ TEST_COMPARE (result, -1);
5777+}
5778
5779- result = clone (child_fn, NULL, 0, NULL);
5780+static int
5781+do_test (void)
5782+{
5783+ char st[128 * 1024] __attribute__ ((aligned));
5784+ void *stack = NULL;
5785+#if _STACK_GROWS_DOWN
5786+ stack = st + sizeof (st);
5787+#elif _STACK_GROWS_UP
5788+ stack = st;
5789+#else
5790+# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
5791+#endif
5792
5793- if (errno != EINVAL || result != -1)
5794- {
5795- printf ("FAIL: clone()=%d (wanted -1) errno=%d (wanted %d)\n",
5796- result, errno, EINVAL);
5797- return 1;
5798- }
5799+ do_test_single (child_fn, NULL);
5800+ do_test_single (NULL, stack);
5801+ do_test_single (NULL, NULL);
5802
5803- puts ("All OK");
5804 return 0;
5805 }
5806
5807-#define TEST_FUNCTION do_test ()
5808-#include "../test-skeleton.c"
5809+#include <support/test-driver.c>
5810diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile
5811index 4223feb95f..9a1e7aa646 100644
5812--- a/sysdeps/unix/sysv/linux/x86_64/Makefile
5813+++ b/sysdeps/unix/sysv/linux/x86_64/Makefile
5814@@ -63,6 +63,33 @@ $(objpfx)libx86-64-isa-level%.os: $(..)/sysdeps/unix/sysv/linux/x86_64/x86-64-is
5815 $(objpfx)libx86-64-isa-level.so: $(objpfx)libx86-64-isa-level-1.so
5816 cp $< $@
5817 endif
5818+
5819+ifeq (yes,$(have-mamx-tile))
5820+tests += \
5821+ tst-gnu2-tls2-amx \
5822+# tests
5823+
5824+modules-names += \
5825+ tst-gnu2-tls2-amx-mod0 \
5826+ tst-gnu2-tls2-amx-mod1 \
5827+ tst-gnu2-tls2-amx-mod2 \
5828+# modules-names
5829+
5830+$(objpfx)tst-gnu2-tls2-amx: $(shared-thread-library)
5831+$(objpfx)tst-gnu2-tls2-amx.out: \
5832+ $(objpfx)tst-gnu2-tls2-amx-mod0.so \
5833+ $(objpfx)tst-gnu2-tls2-amx-mod1.so \
5834+ $(objpfx)tst-gnu2-tls2-amx-mod2.so
5835+$(objpfx)tst-gnu2-tls2-amx-mod0.so: $(libsupport)
5836+$(objpfx)tst-gnu2-tls2-amx-mod1.so: $(libsupport)
5837+$(objpfx)tst-gnu2-tls2-amx-mod2.so: $(libsupport)
5838+
5839+CFLAGS-tst-gnu2-tls2-amx.c += -mamx-tile
5840+CFLAGS-tst-gnu2-tls2-amx-mod0.c += -mamx-tile -mtls-dialect=gnu2
5841+CFLAGS-tst-gnu2-tls2-amx-mod1.c += -mamx-tile -mtls-dialect=gnu2
5842+CFLAGS-tst-gnu2-tls2-amx-mod2.c += -mamx-tile -mtls-dialect=gnu2
5843+endif
5844+
5845 endif # $(subdir) == elf
5846
5847 ifneq ($(enable-cet),no)
5848diff --git a/sysdeps/unix/sysv/linux/x86_64/include/asm/prctl.h b/sysdeps/unix/sysv/linux/x86_64/include/asm/prctl.h
5849index 2f511321ad..ef4631bf4b 100644
5850--- a/sysdeps/unix/sysv/linux/x86_64/include/asm/prctl.h
5851+++ b/sysdeps/unix/sysv/linux/x86_64/include/asm/prctl.h
5852@@ -20,3 +20,8 @@
5853 # define ARCH_SHSTK_SHSTK 0x1
5854 # define ARCH_SHSTK_WRSS 0x2
5855 #endif
5856+
5857+#ifndef ARCH_GET_XCOMP_PERM
5858+# define ARCH_GET_XCOMP_PERM 0x1022
5859+# define ARCH_REQ_XCOMP_PERM 0x1023
5860+#endif
5861diff --git a/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod0.c b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod0.c
5862new file mode 100644
5863index 0000000000..2e0c7b91b7
5864--- /dev/null
5865+++ b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod0.c
5866@@ -0,0 +1,2 @@
5867+#include "tst-gnu2-tls2-amx.h"
5868+#include <tst-gnu2-tls2mod0.c>
5869diff --git a/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod1.c b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod1.c
5870new file mode 100644
5871index 0000000000..b8a8ccf1c1
5872--- /dev/null
5873+++ b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod1.c
5874@@ -0,0 +1,2 @@
5875+#include "tst-gnu2-tls2-amx.h"
5876+#include <tst-gnu2-tls2mod1.c>
5877diff --git a/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod2.c b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod2.c
5878new file mode 100644
5879index 0000000000..cdf4a8f363
5880--- /dev/null
5881+++ b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx-mod2.c
5882@@ -0,0 +1,2 @@
5883+#include "tst-gnu2-tls2-amx.h"
5884+#include <tst-gnu2-tls2mod2.c>
5885diff --git a/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.c b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.c
5886new file mode 100644
5887index 0000000000..ae4dd82556
5888--- /dev/null
5889+++ b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.c
5890@@ -0,0 +1,83 @@
5891+/* Test TLSDESC relocation with AMX.
5892+ Copyright (C) 2024 Free Software Foundation, Inc.
5893+ This file is part of the GNU C Library.
5894+
5895+ The GNU C Library is free software; you can redistribute it and/or
5896+ modify it under the terms of the GNU Lesser General Public
5897+ License as published by the Free Software Foundation; either
5898+ version 2.1 of the License, or (at your option) any later version.
5899+
5900+ The GNU C Library is distributed in the hope that it will be useful,
5901+ but WITHOUT ANY WARRANTY; without even the implied warranty of
5902+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5903+ Lesser General Public License for more details.
5904+
5905+ You should have received a copy of the GNU Lesser General Public
5906+ License along with the GNU C Library; if not, see
5907+ <http://www.gnu.org/licenses/>. */
5908+
5909+#include <stdbool.h>
5910+#include <asm/prctl.h>
5911+#include <support/check.h>
5912+#include "tst-gnu2-tls2-amx.h"
5913+
5914+extern int arch_prctl (int, ...);
5915+
5916+#define X86_XSTATE_TILECFG_ID 17
5917+#define X86_XSTATE_TILEDATA_ID 18
5918+
5919+/* Initialize tile config. */
5920+__attribute__ ((noinline, noclone))
5921+static void
5922+init_tile_config (__tilecfg *tileinfo)
5923+{
5924+ int i;
5925+ tileinfo->palette_id = 1;
5926+ tileinfo->start_row = 0;
5927+
5928+ tileinfo->colsb[0] = MAX_ROWS;
5929+ tileinfo->rows[0] = MAX_ROWS;
5930+
5931+ for (i = 1; i < 4; ++i)
5932+ {
5933+ tileinfo->colsb[i] = MAX_COLS;
5934+ tileinfo->rows[i] = MAX_ROWS;
5935+ }
5936+
5937+ _tile_loadconfig (tileinfo);
5938+}
5939+
5940+static bool
5941+enable_amx (void)
5942+{
5943+ uint64_t bitmask;
5944+ if (arch_prctl (ARCH_GET_XCOMP_PERM, &bitmask) != 0)
5945+ return false;
5946+
5947+ if ((bitmask & (1 << X86_XSTATE_TILECFG_ID)) == 0)
5948+ return false;
5949+
5950+ if (arch_prctl (ARCH_REQ_XCOMP_PERM, X86_XSTATE_TILEDATA_ID) != 0)
5951+ return false;
5952+
5953+ /* Load tile configuration. */
5954+ __tilecfg tile_data = { 0 };
5955+ init_tile_config (&tile_data);
5956+
5957+ return true;
5958+}
5959+
5960+/* An architecture can define it to clobber caller-saved registers in
5961+ malloc below to verify that the implicit TLSDESC call won't change
5962+ caller-saved registers. */
5963+static void
5964+clear_tile_register (void)
5965+{
5966+ _tile_zero (2);
5967+}
5968+
5969+#define MOD(i) "tst-gnu2-tls2-amx-mod" #i ".so"
5970+#define IS_SUPPORTED() enable_amx ()
5971+#define PREPARE_MALLOC() clear_tile_register ()
5972+
5973+#include <elf/tst-gnu2-tls2.c>
5974diff --git a/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.h b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.h
5975new file mode 100644
5976index 0000000000..1845a3caba
5977--- /dev/null
5978+++ b/sysdeps/unix/sysv/linux/x86_64/tst-gnu2-tls2-amx.h
5979@@ -0,0 +1,63 @@
5980+/* Test TLSDESC relocation with AMX.
5981+ Copyright (C) 2024 Free Software Foundation, Inc.
5982+ This file is part of the GNU C Library.
5983+
5984+ The GNU C Library is free software; you can redistribute it and/or
5985+ modify it under the terms of the GNU Lesser General Public
5986+ License as published by the Free Software Foundation; either
5987+ version 2.1 of the License, or (at your option) any later version.
5988+
5989+ The GNU C Library is distributed in the hope that it will be useful,
5990+ but WITHOUT ANY WARRANTY; without even the implied warranty of
5991+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5992+ Lesser General Public License for more details.
5993+
5994+ You should have received a copy of the GNU Lesser General Public
5995+ License along with the GNU C Library; if not, see
5996+ <http://www.gnu.org/licenses/>. */
5997+
5998+#include <stdint.h>
5999+#include <string.h>
6000+#include <x86intrin.h>
6001+#include <support/check.h>
6002+
6003+#define MAX_ROWS 16
6004+#define MAX_COLS 64
6005+#define MAX 1024
6006+#define STRIDE 64
6007+
6008+typedef struct __tile_config
6009+{
6010+ uint8_t palette_id;
6011+ uint8_t start_row;
6012+ uint8_t reserved_0[14];
6013+ uint16_t colsb[16];
6014+ uint8_t rows[16];
6015+} __tilecfg __attribute__ ((aligned (64)));
6016+
6017+/* Initialize int8_t buffer */
6018+static inline void
6019+init_buffer (int8_t *buf, int8_t value)
6020+{
6021+ int rows, colsb, i, j;
6022+ rows = MAX_ROWS;
6023+ colsb = MAX_COLS;
6024+
6025+ for (i = 0; i < rows; i++)
6026+ for (j = 0; j < colsb; j++)
6027+ buf[i * colsb + j] = value;
6028+}
6029+
6030+#define BEFORE_TLSDESC_CALL() \
6031+ int8_t src[MAX]; \
6032+ int8_t res[MAX]; \
6033+ /* Initialize src with data */ \
6034+ init_buffer (src, 2); \
6035+ /* Load tile rows from memory. */ \
6036+ _tile_loadd (2, src, STRIDE);
6037+
6038+#define AFTER_TLSDESC_CALL() \
6039+ /* Store the tile data to memory. */ \
6040+ _tile_stored (2, res, STRIDE); \
6041+ _tile_release (); \
6042+ TEST_VERIFY_EXIT (memcmp (src, res, sizeof (res)) == 0);
6043diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
6044index 4d50b327b5..5311b594af 100644
6045--- a/sysdeps/x86/Makefile
6046+++ b/sysdeps/x86/Makefile
6047@@ -1,5 +1,5 @@
6048 ifeq ($(subdir),csu)
6049-gen-as-const-headers += cpu-features-offsets.sym
6050+gen-as-const-headers += cpu-features-offsets.sym features-offsets.sym
6051 endif
6052
6053 ifeq ($(subdir),elf)
6054@@ -15,18 +15,18 @@ CFLAGS-dl-get-cpu-features.os += $(rtld-early-cflags)
6055 CFLAGS-get-cpuid-feature-leaf.o += $(no-stack-protector)
6056
6057 tests += \
6058- tst-get-cpu-features \
6059- tst-get-cpu-features-static \
6060 tst-cpu-features-cpuinfo \
6061 tst-cpu-features-cpuinfo-static \
6062 tst-cpu-features-supports \
6063 tst-cpu-features-supports-static \
6064+ tst-get-cpu-features \
6065+ tst-get-cpu-features-static \
6066 tst-hwcap-tunables \
6067 # tests
6068 tests-static += \
6069- tst-get-cpu-features-static \
6070 tst-cpu-features-cpuinfo-static \
6071 tst-cpu-features-supports-static \
6072+ tst-get-cpu-features-static \
6073 # tests-static
6074 ifeq (yes,$(have-ifunc))
6075 ifeq (yes,$(have-gcc-ifunc))
6076@@ -86,6 +86,11 @@ endif
6077 tst-ifunc-isa-2-ENV = GLIBC_TUNABLES=glibc.cpu.hwcaps=-SSE4_2,-AVX,-AVX2,-AVX512F
6078 tst-ifunc-isa-2-static-ENV = $(tst-ifunc-isa-2-ENV)
6079 tst-hwcap-tunables-ARGS = -- $(host-test-program-cmd)
6080+
6081+CFLAGS-tst-gnu2-tls2.c += -msse
6082+CFLAGS-tst-gnu2-tls2mod0.c += -msse2 -mtune=haswell
6083+CFLAGS-tst-gnu2-tls2mod1.c += -msse2 -mtune=haswell
6084+CFLAGS-tst-gnu2-tls2mod2.c += -msse2 -mtune=haswell
6085 endif
6086
6087 ifeq ($(subdir),math)
6088diff --git a/sysdeps/x86/bits/wordsize.h b/sysdeps/x86/bits/wordsize.h
6089index 70f652bca1..3f40aa76f9 100644
6090--- a/sysdeps/x86/bits/wordsize.h
6091+++ b/sysdeps/x86/bits/wordsize.h
6092@@ -8,10 +8,9 @@
6093 #define __WORDSIZE32_PTRDIFF_LONG 0
6094 #endif
6095
6096+#define __WORDSIZE_TIME64_COMPAT32 1
6097+
6098 #ifdef __x86_64__
6099-# define __WORDSIZE_TIME64_COMPAT32 1
6100 /* Both x86-64 and x32 use the 64-bit system call interface. */
6101 # define __SYSCALL_WORDSIZE 64
6102-#else
6103-# define __WORDSIZE_TIME64_COMPAT32 0
6104 #endif
6105diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure
6106index 1f4c2d67fd..d28d9bcb29 100644
6107--- a/sysdeps/x86/configure
6108+++ b/sysdeps/x86/configure
6109@@ -98,6 +98,7 @@ printf "%s\n" "$libc_cv_have_x86_lahf_sahf" >&6; }
6110 if test $libc_cv_have_x86_lahf_sahf = yes; then
6111 printf "%s\n" "#define HAVE_X86_LAHF_SAHF 1" >>confdefs.h
6112
6113+ ISAFLAG="-DHAVE_X86_LAHF_SAHF"
6114 fi
6115 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for MOVBE instruction support" >&5
6116 printf %s "checking for MOVBE instruction support... " >&6; }
6117@@ -120,8 +121,47 @@ printf "%s\n" "$libc_cv_have_x86_movbe" >&6; }
6118 if test $libc_cv_have_x86_movbe = yes; then
6119 printf "%s\n" "#define HAVE_X86_MOVBE 1" >>confdefs.h
6120
6121+ ISAFLAG="$ISAFLAG -DHAVE_X86_MOVBE"
6122 fi
6123+
6124+ # Check for ISA level support.
6125+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ISA level support" >&5
6126+printf %s "checking for ISA level support... " >&6; }
6127+if test ${libc_cv_have_x86_isa_level+y}
6128+then :
6129+ printf %s "(cached) " >&6
6130+else $as_nop
6131+ cat > conftest.c <<EOF
6132+#include <sysdeps/x86/isa-level.h>
6133+#if MINIMUM_X86_ISA_LEVEL >= 4
6134+libc_cv_have_x86_isa_level=4
6135+#elif MINIMUM_X86_ISA_LEVEL == 3
6136+libc_cv_have_x86_isa_level=3
6137+#elif MINIMUM_X86_ISA_LEVEL == 2
6138+libc_cv_have_x86_isa_level=2
6139+#else
6140+libc_cv_have_x86_isa_level=baseline
6141+#endif
6142+EOF
6143+ eval `${CC-cc} $CFLAGS $CPPFLAGS $ISAFLAG -I$srcdir -E conftest.c | grep libc_cv_have_x86_isa_level`
6144+ rm -rf conftest*
6145 fi
6146+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_have_x86_isa_level" >&5
6147+printf "%s\n" "$libc_cv_have_x86_isa_level" >&6; }
6148+else
6149+ libc_cv_have_x86_isa_level=baseline
6150+fi
6151+if test $libc_cv_have_x86_isa_level = baseline; then
6152+ printf "%s\n" "#define MINIMUM_X86_ISA_LEVEL 1" >>confdefs.h
6153+
6154+else
6155+ printf "%s\n" "#define MINIMUM_X86_ISA_LEVEL $libc_cv_have_x86_isa_level" >>confdefs.h
6156+
6157+fi
6158+config_vars="$config_vars
6159+have-x86-isa-level = $libc_cv_have_x86_isa_level"
6160+config_vars="$config_vars
6161+x86-isa-level-3-or-above = 3 4"
6162 config_vars="$config_vars
6163 enable-x86-isa-level = $libc_cv_include_x86_isa_level"
6164
6165diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac
6166index 437a50623b..5b0acd03d2 100644
6167--- a/sysdeps/x86/configure.ac
6168+++ b/sysdeps/x86/configure.ac
6169@@ -72,6 +72,7 @@ if test $libc_cv_include_x86_isa_level = yes; then
6170 fi])
6171 if test $libc_cv_have_x86_lahf_sahf = yes; then
6172 AC_DEFINE(HAVE_X86_LAHF_SAHF)
6173+ ISAFLAG="-DHAVE_X86_LAHF_SAHF"
6174 fi
6175 AC_CACHE_CHECK([for MOVBE instruction support],
6176 libc_cv_have_x86_movbe, [dnl
6177@@ -81,8 +82,36 @@ if test $libc_cv_include_x86_isa_level = yes; then
6178 fi])
6179 if test $libc_cv_have_x86_movbe = yes; then
6180 AC_DEFINE(HAVE_X86_MOVBE)
6181+ ISAFLAG="$ISAFLAG -DHAVE_X86_MOVBE"
6182 fi
6183+
6184+ # Check for ISA level support.
6185+ AC_CACHE_CHECK([for ISA level support],
6186+ libc_cv_have_x86_isa_level, [dnl
6187+cat > conftest.c <<EOF
6188+#include <sysdeps/x86/isa-level.h>
6189+#if MINIMUM_X86_ISA_LEVEL >= 4
6190+libc_cv_have_x86_isa_level=4
6191+#elif MINIMUM_X86_ISA_LEVEL == 3
6192+libc_cv_have_x86_isa_level=3
6193+#elif MINIMUM_X86_ISA_LEVEL == 2
6194+libc_cv_have_x86_isa_level=2
6195+#else
6196+libc_cv_have_x86_isa_level=baseline
6197+#endif
6198+EOF
6199+ eval `${CC-cc} $CFLAGS $CPPFLAGS $ISAFLAG -I$srcdir -E conftest.c | grep libc_cv_have_x86_isa_level`
6200+ rm -rf conftest*])
6201+else
6202+ libc_cv_have_x86_isa_level=baseline
6203+fi
6204+if test $libc_cv_have_x86_isa_level = baseline; then
6205+ AC_DEFINE_UNQUOTED(MINIMUM_X86_ISA_LEVEL, 1)
6206+else
6207+ AC_DEFINE_UNQUOTED(MINIMUM_X86_ISA_LEVEL, $libc_cv_have_x86_isa_level)
6208 fi
6209+LIBC_CONFIG_VAR([have-x86-isa-level], [$libc_cv_have_x86_isa_level])
6210+LIBC_CONFIG_VAR([x86-isa-level-3-or-above], [3 4])
6211 LIBC_CONFIG_VAR([enable-x86-isa-level], [$libc_cv_include_x86_isa_level])
6212
6213 dnl Static PIE is supported.
6214diff --git a/sysdeps/x86/cpu-features-offsets.sym b/sysdeps/x86/cpu-features-offsets.sym
6215index 6a8fd29813..21fc88d651 100644
6216--- a/sysdeps/x86/cpu-features-offsets.sym
6217+++ b/sysdeps/x86/cpu-features-offsets.sym
6218@@ -3,3 +3,4 @@
6219 #include <ldsodefs.h>
6220
6221 XSAVE_STATE_SIZE_OFFSET offsetof (struct cpu_features, xsave_state_size)
6222+XSAVE_STATE_FULL_SIZE_OFFSET offsetof (struct cpu_features, xsave_state_full_size)
6223diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
6224index 25e6622a79..3d7c2819d7 100644
6225--- a/sysdeps/x86/cpu-features.c
6226+++ b/sysdeps/x86/cpu-features.c
6227@@ -18,6 +18,7 @@
6228
6229 #include <dl-hwcap.h>
6230 #include <libc-pointer-arith.h>
6231+#include <isa-level.h>
6232 #include <get-isa-level.h>
6233 #include <cacheinfo.h>
6234 #include <dl-cacheinfo.h>
6235@@ -27,8 +28,13 @@
6236 extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *)
6237 attribute_hidden;
6238
6239-#if defined SHARED && defined __x86_64__
6240-# include <dl-plt-rewrite.h>
6241+#if defined SHARED
6242+extern void _dl_tlsdesc_dynamic_fxsave (void) attribute_hidden;
6243+extern void _dl_tlsdesc_dynamic_xsave (void) attribute_hidden;
6244+extern void _dl_tlsdesc_dynamic_xsavec (void) attribute_hidden;
6245+
6246+# ifdef __x86_64__
6247+# include <dl-plt-rewrite.h>
6248
6249 static void
6250 TUNABLE_CALLBACK (set_plt_rewrite) (tunable_val_t *valp)
6251@@ -47,6 +53,15 @@ TUNABLE_CALLBACK (set_plt_rewrite) (tunable_val_t *valp)
6252 : plt_rewrite_jmp);
6253 }
6254 }
6255+# else
6256+extern void _dl_tlsdesc_dynamic_fnsave (void) attribute_hidden;
6257+# endif
6258+#endif
6259+
6260+#ifdef __x86_64__
6261+extern void _dl_runtime_resolve_fxsave (void) attribute_hidden;
6262+extern void _dl_runtime_resolve_xsave (void) attribute_hidden;
6263+extern void _dl_runtime_resolve_xsavec (void) attribute_hidden;
6264 #endif
6265
6266 #ifdef __LP64__
6267@@ -293,8 +308,10 @@ update_active (struct cpu_features *cpu_features)
6268 __cpuid_count (0xd, 0, eax, ebx, ecx, edx);
6269 if (ebx != 0)
6270 {
6271+ /* NB: On AMX capable processors, ebx always includes AMX
6272+ states. */
6273 unsigned int xsave_state_full_size
6274- = ALIGN_UP (ebx + STATE_SAVE_OFFSET, 64);
6275+ = ALIGN_UP (ebx + TLSDESC_CALL_REGISTER_SAVE_AREA, 64);
6276
6277 cpu_features->xsave_state_size
6278 = xsave_state_full_size;
6279@@ -306,6 +323,11 @@ update_active (struct cpu_features *cpu_features)
6280 {
6281 unsigned int xstate_comp_offsets[32];
6282 unsigned int xstate_comp_sizes[32];
6283+#ifdef __x86_64__
6284+ unsigned int xstate_amx_comp_offsets[32];
6285+ unsigned int xstate_amx_comp_sizes[32];
6286+ unsigned int amx_ecx;
6287+#endif
6288 unsigned int i;
6289
6290 xstate_comp_offsets[0] = 0;
6291@@ -313,16 +335,39 @@ update_active (struct cpu_features *cpu_features)
6292 xstate_comp_offsets[2] = 576;
6293 xstate_comp_sizes[0] = 160;
6294 xstate_comp_sizes[1] = 256;
6295+#ifdef __x86_64__
6296+ xstate_amx_comp_offsets[0] = 0;
6297+ xstate_amx_comp_offsets[1] = 160;
6298+ xstate_amx_comp_offsets[2] = 576;
6299+ xstate_amx_comp_sizes[0] = 160;
6300+ xstate_amx_comp_sizes[1] = 256;
6301+#endif
6302
6303 for (i = 2; i < 32; i++)
6304 {
6305- if ((STATE_SAVE_MASK & (1 << i)) != 0)
6306+ if ((FULL_STATE_SAVE_MASK & (1 << i)) != 0)
6307 {
6308 __cpuid_count (0xd, i, eax, ebx, ecx, edx);
6309- xstate_comp_sizes[i] = eax;
6310+#ifdef __x86_64__
6311+ /* Include this in xsave_state_full_size. */
6312+ amx_ecx = ecx;
6313+ xstate_amx_comp_sizes[i] = eax;
6314+ if ((AMX_STATE_SAVE_MASK & (1 << i)) != 0)
6315+ {
6316+ /* Exclude this from xsave_state_size. */
6317+ ecx = 0;
6318+ xstate_comp_sizes[i] = 0;
6319+ }
6320+ else
6321+#endif
6322+ xstate_comp_sizes[i] = eax;
6323 }
6324 else
6325 {
6326+#ifdef __x86_64__
6327+ amx_ecx = 0;
6328+ xstate_amx_comp_sizes[i] = 0;
6329+#endif
6330 ecx = 0;
6331 xstate_comp_sizes[i] = 0;
6332 }
6333@@ -335,6 +380,15 @@ update_active (struct cpu_features *cpu_features)
6334 if ((ecx & (1 << 1)) != 0)
6335 xstate_comp_offsets[i]
6336 = ALIGN_UP (xstate_comp_offsets[i], 64);
6337+#ifdef __x86_64__
6338+ xstate_amx_comp_offsets[i]
6339+ = (xstate_amx_comp_offsets[i - 1]
6340+ + xstate_amx_comp_sizes[i - 1]);
6341+ if ((amx_ecx & (1 << 1)) != 0)
6342+ xstate_amx_comp_offsets[i]
6343+ = ALIGN_UP (xstate_amx_comp_offsets[i],
6344+ 64);
6345+#endif
6346 }
6347 }
6348
6349@@ -343,8 +397,23 @@ update_active (struct cpu_features *cpu_features)
6350 = xstate_comp_offsets[31] + xstate_comp_sizes[31];
6351 if (size)
6352 {
6353+#ifdef __x86_64__
6354+ unsigned int amx_size
6355+ = (xstate_amx_comp_offsets[31]
6356+ + xstate_amx_comp_sizes[31]);
6357+ amx_size
6358+ = ALIGN_UP ((amx_size
6359+ + TLSDESC_CALL_REGISTER_SAVE_AREA),
6360+ 64);
6361+ /* Set xsave_state_full_size to the compact AMX
6362+ state size for XSAVEC. NB: xsave_state_full_size
6363+ is only used in _dl_tlsdesc_dynamic_xsave and
6364+ _dl_tlsdesc_dynamic_xsavec. */
6365+ cpu_features->xsave_state_full_size = amx_size;
6366+#endif
6367 cpu_features->xsave_state_size
6368- = ALIGN_UP (size + STATE_SAVE_OFFSET, 64);
6369+ = ALIGN_UP (size + TLSDESC_CALL_REGISTER_SAVE_AREA,
6370+ 64);
6371 CPU_FEATURE_SET (cpu_features, XSAVEC);
6372 }
6373 }
6374@@ -1130,6 +1199,45 @@ no_cpuid:
6375 TUNABLE_CALLBACK (set_x86_shstk));
6376 #endif
6377
6378+ if (MINIMUM_X86_ISA_LEVEL >= AVX_X86_ISA_LEVEL
6379+ || (GLRO(dl_x86_cpu_features).xsave_state_size != 0))
6380+ {
6381+ if (CPU_FEATURE_USABLE_P (cpu_features, XSAVEC))
6382+ {
6383+#ifdef __x86_64__
6384+ GLRO(dl_x86_64_runtime_resolve) = _dl_runtime_resolve_xsavec;
6385+#endif
6386+#ifdef SHARED
6387+ GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_xsavec;
6388+#endif
6389+ }
6390+ else
6391+ {
6392+#ifdef __x86_64__
6393+ GLRO(dl_x86_64_runtime_resolve) = _dl_runtime_resolve_xsave;
6394+#endif
6395+#ifdef SHARED
6396+ GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_xsave;
6397+#endif
6398+ }
6399+ }
6400+ else
6401+ {
6402+#ifdef __x86_64__
6403+ GLRO(dl_x86_64_runtime_resolve) = _dl_runtime_resolve_fxsave;
6404+# ifdef SHARED
6405+ GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fxsave;
6406+# endif
6407+#else
6408+# ifdef SHARED
6409+ if (CPU_FEATURE_USABLE_P (cpu_features, FXSR))
6410+ GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fxsave;
6411+ else
6412+ GLRO(dl_x86_tlsdesc_dynamic) = _dl_tlsdesc_dynamic_fnsave;
6413+# endif
6414+#endif
6415+ }
6416+
6417 #ifdef SHARED
6418 # ifdef __x86_64__
6419 TUNABLE_GET (plt_rewrite, tunable_val_t *,
6420diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
6421index d5101615e3..5a98f70364 100644
6422--- a/sysdeps/x86/dl-cacheinfo.h
6423+++ b/sysdeps/x86/dl-cacheinfo.h
6424@@ -791,7 +791,6 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
6425 long int data = -1;
6426 long int shared = -1;
6427 long int shared_per_thread = -1;
6428- long int core = -1;
6429 unsigned int threads = 0;
6430 unsigned long int level1_icache_size = -1;
6431 unsigned long int level1_icache_linesize = -1;
6432@@ -809,7 +808,6 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
6433 if (cpu_features->basic.kind == arch_kind_intel)
6434 {
6435 data = handle_intel (_SC_LEVEL1_DCACHE_SIZE, cpu_features);
6436- core = handle_intel (_SC_LEVEL2_CACHE_SIZE, cpu_features);
6437 shared = handle_intel (_SC_LEVEL3_CACHE_SIZE, cpu_features);
6438 shared_per_thread = shared;
6439
6440@@ -822,7 +820,8 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
6441 = handle_intel (_SC_LEVEL1_DCACHE_ASSOC, cpu_features);
6442 level1_dcache_linesize
6443 = handle_intel (_SC_LEVEL1_DCACHE_LINESIZE, cpu_features);
6444- level2_cache_size = core;
6445+ level2_cache_size
6446+ = handle_intel (_SC_LEVEL2_CACHE_SIZE, cpu_features);
6447 level2_cache_assoc
6448 = handle_intel (_SC_LEVEL2_CACHE_ASSOC, cpu_features);
6449 level2_cache_linesize
6450@@ -835,12 +834,12 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
6451 level4_cache_size
6452 = handle_intel (_SC_LEVEL4_CACHE_SIZE, cpu_features);
6453
6454- get_common_cache_info (&shared, &shared_per_thread, &threads, core);
6455+ get_common_cache_info (&shared, &shared_per_thread, &threads,
6456+ level2_cache_size);
6457 }
6458 else if (cpu_features->basic.kind == arch_kind_zhaoxin)
6459 {
6460 data = handle_zhaoxin (_SC_LEVEL1_DCACHE_SIZE);
6461- core = handle_zhaoxin (_SC_LEVEL2_CACHE_SIZE);
6462 shared = handle_zhaoxin (_SC_LEVEL3_CACHE_SIZE);
6463 shared_per_thread = shared;
6464
6465@@ -849,19 +848,19 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
6466 level1_dcache_size = data;
6467 level1_dcache_assoc = handle_zhaoxin (_SC_LEVEL1_DCACHE_ASSOC);
6468 level1_dcache_linesize = handle_zhaoxin (_SC_LEVEL1_DCACHE_LINESIZE);
6469- level2_cache_size = core;
6470+ level2_cache_size = handle_zhaoxin (_SC_LEVEL2_CACHE_SIZE);
6471 level2_cache_assoc = handle_zhaoxin (_SC_LEVEL2_CACHE_ASSOC);
6472 level2_cache_linesize = handle_zhaoxin (_SC_LEVEL2_CACHE_LINESIZE);
6473 level3_cache_size = shared;
6474 level3_cache_assoc = handle_zhaoxin (_SC_LEVEL3_CACHE_ASSOC);
6475 level3_cache_linesize = handle_zhaoxin (_SC_LEVEL3_CACHE_LINESIZE);
6476
6477- get_common_cache_info (&shared, &shared_per_thread, &threads, core);
6478+ get_common_cache_info (&shared, &shared_per_thread, &threads,
6479+ level2_cache_size);
6480 }
6481 else if (cpu_features->basic.kind == arch_kind_amd)
6482 {
6483 data = handle_amd (_SC_LEVEL1_DCACHE_SIZE);
6484- core = handle_amd (_SC_LEVEL2_CACHE_SIZE);
6485 shared = handle_amd (_SC_LEVEL3_CACHE_SIZE);
6486
6487 level1_icache_size = handle_amd (_SC_LEVEL1_ICACHE_SIZE);
6488@@ -869,7 +868,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
6489 level1_dcache_size = data;
6490 level1_dcache_assoc = handle_amd (_SC_LEVEL1_DCACHE_ASSOC);
6491 level1_dcache_linesize = handle_amd (_SC_LEVEL1_DCACHE_LINESIZE);
6492- level2_cache_size = core;
6493+ level2_cache_size = handle_amd (_SC_LEVEL2_CACHE_SIZE);;
6494 level2_cache_assoc = handle_amd (_SC_LEVEL2_CACHE_ASSOC);
6495 level2_cache_linesize = handle_amd (_SC_LEVEL2_CACHE_LINESIZE);
6496 level3_cache_size = shared;
6497@@ -880,12 +879,12 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
6498 if (shared <= 0)
6499 {
6500 /* No shared L3 cache. All we have is the L2 cache. */
6501- shared = core;
6502+ shared = level2_cache_size;
6503 }
6504 else if (cpu_features->basic.family < 0x17)
6505 {
6506 /* Account for exclusive L2 and L3 caches. */
6507- shared += core;
6508+ shared += level2_cache_size;
6509 }
6510
6511 shared_per_thread = shared;
6512@@ -987,6 +986,12 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
6513 if (CPU_FEATURE_USABLE_P (cpu_features, FSRM))
6514 rep_movsb_threshold = 2112;
6515
6516+ /* For AMD CPUs that support ERMS (Zen3+), REP MOVSB is in a lot of
6517+ cases slower than the vectorized path (and for some alignments,
6518+ it is really slow, check BZ #30994). */
6519+ if (cpu_features->basic.kind == arch_kind_amd)
6520+ rep_movsb_threshold = non_temporal_threshold;
6521+
6522 /* The default threshold to use Enhanced REP STOSB. */
6523 unsigned long int rep_stosb_threshold = 2048;
6524
6525@@ -1016,6 +1021,11 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
6526 minimum value is fixed. */
6527 rep_stosb_threshold = TUNABLE_GET (x86_rep_stosb_threshold,
6528 long int, NULL);
6529+ if (cpu_features->basic.kind == arch_kind_amd
6530+ && !TUNABLE_IS_INITIALIZED (x86_rep_stosb_threshold))
6531+ /* For AMD Zen3+ architecture, the performance of the vectorized loop is
6532+ slightly better than ERMS. */
6533+ rep_stosb_threshold = SIZE_MAX;
6534
6535 TUNABLE_SET_WITH_BOUNDS (x86_data_cache_size, data, 0, SIZE_MAX);
6536 TUNABLE_SET_WITH_BOUNDS (x86_shared_cache_size, shared, 0, SIZE_MAX);
6537@@ -1028,16 +1038,9 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
6538 SIZE_MAX);
6539
6540 unsigned long int rep_movsb_stop_threshold;
6541- /* ERMS feature is implemented from AMD Zen3 architecture and it is
6542- performing poorly for data above L2 cache size. Henceforth, adding
6543- an upper bound threshold parameter to limit the usage of Enhanced
6544- REP MOVSB operations and setting its value to L2 cache size. */
6545- if (cpu_features->basic.kind == arch_kind_amd)
6546- rep_movsb_stop_threshold = core;
6547 /* Setting the upper bound of ERMS to the computed value of
6548- non-temporal threshold for architectures other than AMD. */
6549- else
6550- rep_movsb_stop_threshold = non_temporal_threshold;
6551+ non-temporal threshold for all architectures. */
6552+ rep_movsb_stop_threshold = non_temporal_threshold;
6553
6554 cpu_features->data_cache_size = data;
6555 cpu_features->shared_cache_size = shared;
6556diff --git a/sysdeps/x86/dl-procinfo.c b/sysdeps/x86/dl-procinfo.c
6557index ee957b4d70..5920d4b320 100644
6558--- a/sysdeps/x86/dl-procinfo.c
6559+++ b/sysdeps/x86/dl-procinfo.c
6560@@ -86,3 +86,19 @@ PROCINFO_CLASS const char _dl_x86_platforms[4][9]
6561 #else
6562 ,
6563 #endif
6564+
6565+#if defined SHARED && !IS_IN (ldconfig)
6566+# if !defined PROCINFO_DECL
6567+ ._dl_x86_tlsdesc_dynamic
6568+# else
6569+PROCINFO_CLASS void * _dl_x86_tlsdesc_dynamic
6570+# endif
6571+# ifndef PROCINFO_DECL
6572+= NULL
6573+# endif
6574+# ifdef PROCINFO_DECL
6575+;
6576+# else
6577+,
6578+# endif
6579+#endif
6580diff --git a/sysdeps/x86_64/features-offsets.sym b/sysdeps/x86/features-offsets.sym
6581similarity index 89%
6582rename from sysdeps/x86_64/features-offsets.sym
6583rename to sysdeps/x86/features-offsets.sym
6584index 9e4be3393a..77e990c705 100644
6585--- a/sysdeps/x86_64/features-offsets.sym
6586+++ b/sysdeps/x86/features-offsets.sym
6587@@ -3,4 +3,6 @@
6588 #include <ldsodefs.h>
6589
6590 RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET offsetof (struct rtld_global_ro, _dl_x86_cpu_features)
6591+#ifdef __x86_64__
6592 RTLD_GLOBAL_DL_X86_FEATURE_1_OFFSET offsetof (struct rtld_global, _dl_x86_feature_1)
6593+#endif
6594diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h
6595index b9bf3115b6..cd7bd27cf3 100644
6596--- a/sysdeps/x86/include/cpu-features.h
6597+++ b/sysdeps/x86/include/cpu-features.h
6598@@ -934,6 +934,8 @@ struct cpu_features
6599 /* The full state size for XSAVE when XSAVEC is disabled by
6600
6601 GLIBC_TUNABLES=glibc.cpu.hwcaps=-XSAVEC
6602+
6603+ and the AMX state size when XSAVEC is available.
6604 */
6605 unsigned int xsave_state_full_size;
6606 /* Data cache size for use in memory and string routines, typically
6607diff --git a/sysdeps/x86/isa-level.h b/sysdeps/x86/isa-level.h
6608index 11fe1ca90c..2c7f74212b 100644
6609--- a/sysdeps/x86/isa-level.h
6610+++ b/sysdeps/x86/isa-level.h
6611@@ -61,8 +61,10 @@
6612 # define __X86_ISA_V4 0
6613 #endif
6614
6615-#define MINIMUM_X86_ISA_LEVEL \
6616+#ifndef MINIMUM_X86_ISA_LEVEL
6617+# define MINIMUM_X86_ISA_LEVEL \
6618 (__X86_ISA_V1 + __X86_ISA_V2 + __X86_ISA_V3 + __X86_ISA_V4)
6619+#endif
6620
6621 /* Depending on the minimum ISA level, a feature check result can be a
6622 compile-time constant.. */
6623diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h
6624index 85d0a8c943..7359149e17 100644
6625--- a/sysdeps/x86/sysdep.h
6626+++ b/sysdeps/x86/sysdep.h
6627@@ -21,14 +21,118 @@
6628
6629 #include <sysdeps/generic/sysdep.h>
6630
6631+/* The extended state feature IDs in the state component bitmap. */
6632+#define X86_XSTATE_X87_ID 0
6633+#define X86_XSTATE_SSE_ID 1
6634+#define X86_XSTATE_AVX_ID 2
6635+#define X86_XSTATE_BNDREGS_ID 3
6636+#define X86_XSTATE_BNDCFG_ID 4
6637+#define X86_XSTATE_K_ID 5
6638+#define X86_XSTATE_ZMM_H_ID 6
6639+#define X86_XSTATE_ZMM_ID 7
6640+#define X86_XSTATE_PKRU_ID 9
6641+#define X86_XSTATE_TILECFG_ID 17
6642+#define X86_XSTATE_TILEDATA_ID 18
6643+#define X86_XSTATE_APX_F_ID 19
6644+
6645+#ifdef __x86_64__
6646 /* Offset for fxsave/xsave area used by _dl_runtime_resolve. Also need
6647 space to preserve RCX, RDX, RSI, RDI, R8, R9 and RAX. It must be
6648- aligned to 16 bytes for fxsave and 64 bytes for xsave. */
6649-#define STATE_SAVE_OFFSET (8 * 7 + 8)
6650+ aligned to 16 bytes for fxsave and 64 bytes for xsave. It is non-zero
6651+ because MOV, instead of PUSH, is used to save registers onto stack.
6652+
6653+ +==================+<- stack frame start aligned at 8 or 16 bytes
6654+ | |<- paddings for stack realignment of 64 bytes
6655+ |------------------|<- xsave buffer end aligned at 64 bytes
6656+ | |<-
6657+ | |<-
6658+ | |<-
6659+ |------------------|<- xsave buffer start at STATE_SAVE_OFFSET(%rsp)
6660+ | |<- 8-byte padding for 64-byte alignment
6661+ | |<- R9
6662+ | |<- R8
6663+ | |<- RDI
6664+ | |<- RSI
6665+ | |<- RDX
6666+ | |<- RCX
6667+ | |<- RAX
6668+ +==================+<- RSP aligned at 64 bytes
6669+
6670+ */
6671+# define STATE_SAVE_OFFSET (8 * 7 + 8)
6672+
6673+/* _dl_tlsdesc_dynamic preserves RDI, RSI and RBX before realigning
6674+ stack. After realigning stack, it saves RCX, RDX, R8, R9, R10 and
6675+ R11. Allocate space for RDI, RSI and RBX to avoid clobbering saved
6676+ RDI, RSI and RBX values on stack by xsave.
6677+
6678+ +==================+<- stack frame start aligned at 8 or 16 bytes
6679+ | |<- RDI saved in the red zone
6680+ | |<- RSI saved in the red zone
6681+ | |<- RBX saved in the red zone
6682+ | |<- paddings for stack realignment of 64 bytes
6683+ |------------------|<- xsave buffer end aligned at 64 bytes
6684+ | |<-
6685+ | |<-
6686+ | |<-
6687+ |------------------|<- xsave buffer start at STATE_SAVE_OFFSET(%rsp)
6688+ | |<- 8-byte padding for 64-byte alignment
6689+ | |<- 8-byte padding for 64-byte alignment
6690+ | |<- R11
6691+ | |<- R10
6692+ | |<- R9
6693+ | |<- R8
6694+ | |<- RDX
6695+ | |<- RCX
6696+ +==================+<- RSP aligned at 64 bytes
6697+
6698+ Define the total register save area size for all integer registers by
6699+ adding 24 to STATE_SAVE_OFFSET since RDI, RSI and RBX are saved onto
6700+ stack without adjusting stack pointer first, using the red-zone. */
6701+# define TLSDESC_CALL_REGISTER_SAVE_AREA (STATE_SAVE_OFFSET + 24)
6702+
6703+/* Save SSE, AVX, AVX512, mask, bound and APX registers. Bound and APX
6704+ registers are mutually exclusive. */
6705+# define STATE_SAVE_MASK \
6706+ ((1 << X86_XSTATE_SSE_ID) \
6707+ | (1 << X86_XSTATE_AVX_ID) \
6708+ | (1 << X86_XSTATE_BNDREGS_ID) \
6709+ | (1 << X86_XSTATE_K_ID) \
6710+ | (1 << X86_XSTATE_ZMM_H_ID) \
6711+ | (1 << X86_XSTATE_ZMM_ID) \
6712+ | (1 << X86_XSTATE_APX_F_ID))
6713+
6714+/* AMX state mask. */
6715+# define AMX_STATE_SAVE_MASK \
6716+ ((1 << X86_XSTATE_TILECFG_ID) | (1 << X86_XSTATE_TILEDATA_ID))
6717+
6718+/* States to be included in xsave_state_full_size. */
6719+# define FULL_STATE_SAVE_MASK \
6720+ (STATE_SAVE_MASK | AMX_STATE_SAVE_MASK)
6721+#else
6722+/* Offset for fxsave/xsave area used by _dl_tlsdesc_dynamic. Since i386
6723+ uses PUSH to save registers onto stack, use 0 here. */
6724+# define STATE_SAVE_OFFSET 0
6725+# define TLSDESC_CALL_REGISTER_SAVE_AREA 0
6726+
6727+/* Save SSE, AVX, AXV512, mask and bound registers. */
6728+# define STATE_SAVE_MASK \
6729+ ((1 << X86_XSTATE_SSE_ID) \
6730+ | (1 << X86_XSTATE_AVX_ID) \
6731+ | (1 << X86_XSTATE_BNDREGS_ID) \
6732+ | (1 << X86_XSTATE_K_ID) \
6733+ | (1 << X86_XSTATE_ZMM_H_ID))
6734+
6735+/* States to be included in xsave_state_size. */
6736+# define FULL_STATE_SAVE_MASK STATE_SAVE_MASK
6737+#endif
6738
6739-/* Save SSE, AVX, AVX512, mask and bound registers. */
6740-#define STATE_SAVE_MASK \
6741- ((1 << 1) | (1 << 2) | (1 << 3) | (1 << 5) | (1 << 6) | (1 << 7))
6742+/* States which should be saved for TLSDESC_CALL and TLS_DESC_CALL.
6743+ Compiler assumes that all registers, including AMX and x87 FPU
6744+ stack registers, are unchanged after CALL, except for EFLAGS and
6745+ RAX/EAX. */
6746+#define TLSDESC_CALL_STATE_SAVE_MASK \
6747+ (FULL_STATE_SAVE_MASK | (1 << X86_XSTATE_X87_ID))
6748
6749 /* Constants for bits in __x86_string_control: */
6750
6751diff --git a/sysdeps/x86/tst-gnu2-tls2.c b/sysdeps/x86/tst-gnu2-tls2.c
6752new file mode 100644
6753index 0000000000..de900a423b
6754--- /dev/null
6755+++ b/sysdeps/x86/tst-gnu2-tls2.c
6756@@ -0,0 +1,20 @@
6757+#ifndef __x86_64__
6758+#include <sys/platform/x86.h>
6759+
6760+#define IS_SUPPORTED() CPU_FEATURE_ACTIVE (SSE2)
6761+#endif
6762+
6763+/* Clear XMM0...XMM7 */
6764+#define PREPARE_MALLOC() \
6765+{ \
6766+ asm volatile ("xorps %%xmm0, %%xmm0" : : : "xmm0" ); \
6767+ asm volatile ("xorps %%xmm1, %%xmm1" : : : "xmm1" ); \
6768+ asm volatile ("xorps %%xmm2, %%xmm2" : : : "xmm2" ); \
6769+ asm volatile ("xorps %%xmm3, %%xmm3" : : : "xmm3" ); \
6770+ asm volatile ("xorps %%xmm4, %%xmm4" : : : "xmm4" ); \
6771+ asm volatile ("xorps %%xmm5, %%xmm5" : : : "xmm5" ); \
6772+ asm volatile ("xorps %%xmm6, %%xmm6" : : : "xmm6" ); \
6773+ asm volatile ("xorps %%xmm7, %%xmm7" : : : "xmm7" ); \
6774+}
6775+
6776+#include <elf/tst-gnu2-tls2.c>
6777diff --git a/sysdeps/x86/utmp-size.h b/sysdeps/x86/utmp-size.h
6778new file mode 100644
6779index 0000000000..8f21ebe1b6
6780--- /dev/null
6781+++ b/sysdeps/x86/utmp-size.h
6782@@ -0,0 +1,2 @@
6783+#define UTMP_SIZE 384
6784+#define LASTLOG_SIZE 292
6785diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile
6786index 90f4ecfd26..0ede447405 100644
6787--- a/sysdeps/x86_64/Makefile
6788+++ b/sysdeps/x86_64/Makefile
6789@@ -10,7 +10,7 @@ LDFLAGS-rtld += -Wl,-z,nomark-plt
6790 endif
6791
6792 ifeq ($(subdir),csu)
6793-gen-as-const-headers += features-offsets.sym link-defines.sym
6794+gen-as-const-headers += link-defines.sym
6795 endif
6796
6797 ifeq ($(subdir),gmon)
6798@@ -210,6 +210,8 @@ tst-plt-rewrite2-ENV = GLIBC_TUNABLES=glibc.cpu.plt_rewrite=2
6799 $(objpfx)tst-plt-rewrite2: $(objpfx)tst-plt-rewritemod2.so
6800 endif
6801
6802+test-internal-extras += tst-gnu2-tls2mod1
6803+
6804 endif # $(subdir) == elf
6805
6806 ifeq ($(subdir),csu)
6807@@ -250,6 +252,10 @@ sysdep-dl-routines += dl-cet
6808
6809 tests += \
6810 tst-cet-legacy-1 \
6811+ tst-cet-legacy-10 \
6812+ tst-cet-legacy-10-static \
6813+ tst-cet-legacy-10a \
6814+ tst-cet-legacy-10a-static \
6815 tst-cet-legacy-1a \
6816 tst-cet-legacy-2 \
6817 tst-cet-legacy-2a \
6818@@ -261,15 +267,11 @@ tests += \
6819 tst-cet-legacy-8 \
6820 tst-cet-legacy-9 \
6821 tst-cet-legacy-9-static \
6822- tst-cet-legacy-10 \
6823- tst-cet-legacy-10-static \
6824- tst-cet-legacy-10a \
6825- tst-cet-legacy-10a-static \
6826 # tests
6827 tests-static += \
6828- tst-cet-legacy-9-static \
6829 tst-cet-legacy-10-static \
6830 tst-cet-legacy-10a-static \
6831+ tst-cet-legacy-9-static \
6832 # tests-static
6833 tst-cet-legacy-1a-ARGS = -- $(host-test-program-cmd)
6834
6835diff --git a/sysdeps/x86_64/configure b/sysdeps/x86_64/configure
6836index 418cc4a9b8..04a534fa12 100755
6837--- a/sysdeps/x86_64/configure
6838+++ b/sysdeps/x86_64/configure
6839@@ -134,6 +134,34 @@ fi
6840 config_vars="$config_vars
6841 enable-cet = $enable_cet"
6842
6843+# Check if -mamx-tile works properly.
6844+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -mamx-tile works properly" >&5
6845+printf %s "checking whether -mamx-tile works properly... " >&6; }
6846+if test ${libc_cv_x86_have_amx_tile+y}
6847+then :
6848+ printf %s "(cached) " >&6
6849+else $as_nop
6850+ cat > conftest.c <<EOF
6851+#include <x86intrin.h>
6852+EOF
6853+ libc_cv_x86_have_amx_tile=no
6854+ if { ac_try='${CC-cc} -E $CFLAGS -mamx-tile conftest.c > conftest.i'
6855+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
6856+ (eval $ac_try) 2>&5
6857+ ac_status=$?
6858+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
6859+ test $ac_status = 0; }; }; then
6860+ if grep -q __builtin_ia32_ldtilecfg conftest.i; then
6861+ libc_cv_x86_have_amx_tile=yes
6862+ fi
6863+ fi
6864+ rm -rf conftest*
6865+fi
6866+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_x86_have_amx_tile" >&5
6867+printf "%s\n" "$libc_cv_x86_have_amx_tile" >&6; }
6868+config_vars="$config_vars
6869+have-mamx-tile = $libc_cv_x86_have_amx_tile"
6870+
6871 test -n "$critic_missing" && as_fn_error $? "
6872 *** $critic_missing" "$LINENO" 5
6873
6874diff --git a/sysdeps/x86_64/configure.ac b/sysdeps/x86_64/configure.ac
6875index d1f803c02e..c714c47351 100644
6876--- a/sysdeps/x86_64/configure.ac
6877+++ b/sysdeps/x86_64/configure.ac
6878@@ -61,5 +61,20 @@ elif test $enable_cet = permissive; then
6879 fi
6880 LIBC_CONFIG_VAR([enable-cet], [$enable_cet])
6881
6882+# Check if -mamx-tile works properly.
6883+AC_CACHE_CHECK(whether -mamx-tile works properly,
6884+ libc_cv_x86_have_amx_tile, [dnl
6885+cat > conftest.c <<EOF
6886+#include <x86intrin.h>
6887+EOF
6888+ libc_cv_x86_have_amx_tile=no
6889+ if AC_TRY_COMMAND(${CC-cc} -E $CFLAGS -mamx-tile conftest.c > conftest.i); then
6890+ if grep -q __builtin_ia32_ldtilecfg conftest.i; then
6891+ libc_cv_x86_have_amx_tile=yes
6892+ fi
6893+ fi
6894+ rm -rf conftest*])
6895+LIBC_CONFIG_VAR([have-mamx-tile], [$libc_cv_x86_have_amx_tile])
6896+
6897 test -n "$critic_missing" && AC_MSG_ERROR([
6898 *** $critic_missing])
6899diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
6900index 6d605d0d32..ff5d45f7cb 100644
6901--- a/sysdeps/x86_64/dl-machine.h
6902+++ b/sysdeps/x86_64/dl-machine.h
6903@@ -71,9 +71,6 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
6904 int lazy, int profile)
6905 {
6906 Elf64_Addr *got;
6907- extern void _dl_runtime_resolve_fxsave (ElfW(Word)) attribute_hidden;
6908- extern void _dl_runtime_resolve_xsave (ElfW(Word)) attribute_hidden;
6909- extern void _dl_runtime_resolve_xsavec (ElfW(Word)) attribute_hidden;
6910 extern void _dl_runtime_profile_sse (ElfW(Word)) attribute_hidden;
6911 extern void _dl_runtime_profile_avx (ElfW(Word)) attribute_hidden;
6912 extern void _dl_runtime_profile_avx512 (ElfW(Word)) attribute_hidden;
6913@@ -96,8 +93,6 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
6914 /* Identify this shared object. */
6915 *(ElfW(Addr) *) (got + 1) = (ElfW(Addr)) l;
6916
6917- const struct cpu_features* cpu_features = __get_cpu_features ();
6918-
6919 #ifdef SHARED
6920 /* The got[2] entry contains the address of a function which gets
6921 called to get the address of a so far unresolved function and
6922@@ -107,6 +102,7 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
6923 end in this function. */
6924 if (__glibc_unlikely (profile))
6925 {
6926+ const struct cpu_features* cpu_features = __get_cpu_features ();
6927 if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512F))
6928 *(ElfW(Addr) *) (got + 2) = (ElfW(Addr)) &_dl_runtime_profile_avx512;
6929 else if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX))
6930@@ -126,15 +122,8 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
6931 /* This function will get called to fix up the GOT entry
6932 indicated by the offset on the stack, and then jump to
6933 the resolved address. */
6934- if (MINIMUM_X86_ISA_LEVEL >= AVX_X86_ISA_LEVEL
6935- || GLRO(dl_x86_cpu_features).xsave_state_size != 0)
6936- *(ElfW(Addr) *) (got + 2)
6937- = (CPU_FEATURE_USABLE_P (cpu_features, XSAVEC)
6938- ? (ElfW(Addr)) &_dl_runtime_resolve_xsavec
6939- : (ElfW(Addr)) &_dl_runtime_resolve_xsave);
6940- else
6941- *(ElfW(Addr) *) (got + 2)
6942- = (ElfW(Addr)) &_dl_runtime_resolve_fxsave;
6943+ *(ElfW(Addr) *) (got + 2)
6944+ = (ElfW(Addr)) GLRO(dl_x86_64_runtime_resolve);
6945 }
6946 }
6947
6948@@ -383,7 +372,7 @@ and creates an unsatisfiable circular dependency.\n",
6949 {
6950 td->arg = _dl_make_tlsdesc_dynamic
6951 (sym_map, sym->st_value + reloc->r_addend);
6952- td->entry = _dl_tlsdesc_dynamic;
6953+ td->entry = GLRO(dl_x86_tlsdesc_dynamic);
6954 }
6955 else
6956 # endif
6957diff --git a/sysdeps/x86_64/dl-procinfo.c b/sysdeps/x86_64/dl-procinfo.c
6958index 4d1d790fbb..06637a8154 100644
6959--- a/sysdeps/x86_64/dl-procinfo.c
6960+++ b/sysdeps/x86_64/dl-procinfo.c
6961@@ -41,5 +41,21 @@
6962
6963 #include <sysdeps/x86/dl-procinfo.c>
6964
6965+#if !IS_IN (ldconfig)
6966+# if !defined PROCINFO_DECL && defined SHARED
6967+ ._dl_x86_64_runtime_resolve
6968+# else
6969+PROCINFO_CLASS void * _dl_x86_64_runtime_resolve
6970+# endif
6971+# ifndef PROCINFO_DECL
6972+= NULL
6973+# endif
6974+# if !defined SHARED || defined PROCINFO_DECL
6975+;
6976+# else
6977+,
6978+# endif
6979+#endif
6980+
6981 #undef PROCINFO_DECL
6982 #undef PROCINFO_CLASS
6983diff --git a/sysdeps/x86_64/dl-tlsdesc-dynamic.h b/sysdeps/x86_64/dl-tlsdesc-dynamic.h
6984new file mode 100644
6985index 0000000000..9f02cfc3eb
6986--- /dev/null
6987+++ b/sysdeps/x86_64/dl-tlsdesc-dynamic.h
6988@@ -0,0 +1,166 @@
6989+/* Thread-local storage handling in the ELF dynamic linker. x86_64 version.
6990+ Copyright (C) 2004-2024 Free Software Foundation, Inc.
6991+ This file is part of the GNU C Library.
6992+
6993+ The GNU C Library is free software; you can redistribute it and/or
6994+ modify it under the terms of the GNU Lesser General Public
6995+ License as published by the Free Software Foundation; either
6996+ version 2.1 of the License, or (at your option) any later version.
6997+
6998+ The GNU C Library is distributed in the hope that it will be useful,
6999+ but WITHOUT ANY WARRANTY; without even the implied warranty of
7000+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7001+ Lesser General Public License for more details.
7002+
7003+ You should have received a copy of the GNU Lesser General Public
7004+ License along with the GNU C Library; if not, see
7005+ <https://www.gnu.org/licenses/>. */
7006+
7007+#ifndef SECTION
7008+# define SECTION(p) p
7009+#endif
7010+
7011+#undef REGISTER_SAVE_AREA
7012+#undef LOCAL_STORAGE_AREA
7013+#undef BASE
7014+
7015+#include "dl-trampoline-state.h"
7016+
7017+ .section SECTION(.text),"ax",@progbits
7018+
7019+ .hidden _dl_tlsdesc_dynamic
7020+ .global _dl_tlsdesc_dynamic
7021+ .type _dl_tlsdesc_dynamic,@function
7022+
7023+ /* %rax points to the TLS descriptor, such that 0(%rax) points to
7024+ _dl_tlsdesc_dynamic itself, and 8(%rax) points to a struct
7025+ tlsdesc_dynamic_arg object. It must return in %rax the offset
7026+ between the thread pointer and the object denoted by the
7027+ argument, without clobbering any registers.
7028+
7029+ The assembly code that follows is a rendition of the following
7030+ C code, hand-optimized a little bit.
7031+
7032+ptrdiff_t
7033+_dl_tlsdesc_dynamic (register struct tlsdesc *tdp asm ("%rax"))
7034+{
7035+ struct tlsdesc_dynamic_arg *td = tdp->arg;
7036+ dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer + DTV_OFFSET);
7037+ if (__builtin_expect (td->gen_count <= dtv[0].counter
7038+ && (dtv[td->tlsinfo.ti_module].pointer.val
7039+ != TLS_DTV_UNALLOCATED),
7040+ 1))
7041+ return dtv[td->tlsinfo.ti_module].pointer.val + td->tlsinfo.ti_offset
7042+ - __thread_pointer;
7043+
7044+ return __tls_get_addr_internal (&td->tlsinfo) - __thread_pointer;
7045+}
7046+*/
7047+ cfi_startproc
7048+ .align 16
7049+_dl_tlsdesc_dynamic:
7050+ _CET_ENDBR
7051+ /* Preserve call-clobbered registers that we modify.
7052+ We need two scratch regs anyway. */
7053+ movq %rsi, -16(%rsp)
7054+ mov %fs:DTV_OFFSET, %RSI_LP
7055+ movq %rdi, -8(%rsp)
7056+ movq TLSDESC_ARG(%rax), %rdi
7057+ movq (%rsi), %rax
7058+ cmpq %rax, TLSDESC_GEN_COUNT(%rdi)
7059+ ja 2f
7060+ movq TLSDESC_MODID(%rdi), %rax
7061+ salq $4, %rax
7062+ movq (%rax,%rsi), %rax
7063+ cmpq $-1, %rax
7064+ je 2f
7065+ addq TLSDESC_MODOFF(%rdi), %rax
7066+1:
7067+ movq -16(%rsp), %rsi
7068+ sub %fs:0, %RAX_LP
7069+ movq -8(%rsp), %rdi
7070+ ret
7071+2:
7072+#if DL_RUNTIME_RESOLVE_REALIGN_STACK
7073+ movq %rbx, -24(%rsp)
7074+ mov %RSP_LP, %RBX_LP
7075+ cfi_def_cfa_register(%rbx)
7076+ and $-STATE_SAVE_ALIGNMENT, %RSP_LP
7077+#endif
7078+#ifdef REGISTER_SAVE_AREA
7079+# if DL_RUNTIME_RESOLVE_REALIGN_STACK
7080+ /* STATE_SAVE_OFFSET has space for 8 integer registers. But we
7081+ need space for RCX, RDX, RSI, RDI, R8, R9, R10 and R11, plus
7082+ RBX above. */
7083+ sub $(REGISTER_SAVE_AREA + STATE_SAVE_ALIGNMENT), %RSP_LP
7084+# else
7085+ sub $REGISTER_SAVE_AREA, %RSP_LP
7086+ cfi_adjust_cfa_offset(REGISTER_SAVE_AREA)
7087+# endif
7088+#else
7089+ /* Allocate stack space of the required size to save the state. */
7090+ sub _rtld_local_ro+RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+XSAVE_STATE_FULL_SIZE_OFFSET(%rip), %RSP_LP
7091+#endif
7092+ /* Besides rdi and rsi, saved above, save rcx, rdx, r8, r9,
7093+ r10 and r11. */
7094+ movq %rcx, REGISTER_SAVE_RCX(%rsp)
7095+ movq %rdx, REGISTER_SAVE_RDX(%rsp)
7096+ movq %r8, REGISTER_SAVE_R8(%rsp)
7097+ movq %r9, REGISTER_SAVE_R9(%rsp)
7098+ movq %r10, REGISTER_SAVE_R10(%rsp)
7099+ movq %r11, REGISTER_SAVE_R11(%rsp)
7100+#ifdef USE_FXSAVE
7101+ fxsave STATE_SAVE_OFFSET(%rsp)
7102+#else
7103+ movl $TLSDESC_CALL_STATE_SAVE_MASK, %eax
7104+ xorl %edx, %edx
7105+ /* Clear the XSAVE Header. */
7106+# ifdef USE_XSAVE
7107+ movq %rdx, (STATE_SAVE_OFFSET + 512)(%rsp)
7108+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8)(%rsp)
7109+# endif
7110+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 2)(%rsp)
7111+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 3)(%rsp)
7112+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 4)(%rsp)
7113+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 5)(%rsp)
7114+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 6)(%rsp)
7115+ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 7)(%rsp)
7116+# ifdef USE_XSAVE
7117+ xsave STATE_SAVE_OFFSET(%rsp)
7118+# else
7119+ xsavec STATE_SAVE_OFFSET(%rsp)
7120+# endif
7121+#endif
7122+ /* %rdi already points to the tlsinfo data structure. */
7123+ call HIDDEN_JUMPTARGET (__tls_get_addr)
7124+ # Get register content back.
7125+#ifdef USE_FXSAVE
7126+ fxrstor STATE_SAVE_OFFSET(%rsp)
7127+#else
7128+ /* Save and retore __tls_get_addr return value stored in RAX. */
7129+ mov %RAX_LP, %RCX_LP
7130+ movl $TLSDESC_CALL_STATE_SAVE_MASK, %eax
7131+ xorl %edx, %edx
7132+ xrstor STATE_SAVE_OFFSET(%rsp)
7133+ mov %RCX_LP, %RAX_LP
7134+#endif
7135+ movq REGISTER_SAVE_R11(%rsp), %r11
7136+ movq REGISTER_SAVE_R10(%rsp), %r10
7137+ movq REGISTER_SAVE_R9(%rsp), %r9
7138+ movq REGISTER_SAVE_R8(%rsp), %r8
7139+ movq REGISTER_SAVE_RDX(%rsp), %rdx
7140+ movq REGISTER_SAVE_RCX(%rsp), %rcx
7141+#if DL_RUNTIME_RESOLVE_REALIGN_STACK
7142+ mov %RBX_LP, %RSP_LP
7143+ cfi_def_cfa_register(%rsp)
7144+ movq -24(%rsp), %rbx
7145+ cfi_restore(%rbx)
7146+#else
7147+ add $REGISTER_SAVE_AREA, %RSP_LP
7148+ cfi_adjust_cfa_offset(-REGISTER_SAVE_AREA)
7149+#endif
7150+ jmp 1b
7151+ cfi_endproc
7152+ .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic
7153+
7154+#undef STATE_SAVE_ALIGNMENT
7155diff --git a/sysdeps/x86_64/dl-tlsdesc.S b/sysdeps/x86_64/dl-tlsdesc.S
7156index f748af2ece..057a10862a 100644
7157--- a/sysdeps/x86_64/dl-tlsdesc.S
7158+++ b/sysdeps/x86_64/dl-tlsdesc.S
7159@@ -18,7 +18,20 @@
7160
7161 #include <sysdep.h>
7162 #include <tls.h>
7163+#include <cpu-features-offsets.h>
7164+#include <features-offsets.h>
7165+#include <isa-level.h>
7166 #include "tlsdesc.h"
7167+#include "dl-trampoline-save.h"
7168+
7169+/* Area on stack to save and restore registers used for parameter
7170+ passing when calling _dl_tlsdesc_dynamic. */
7171+#define REGISTER_SAVE_RCX 0
7172+#define REGISTER_SAVE_RDX (REGISTER_SAVE_RCX + 8)
7173+#define REGISTER_SAVE_R8 (REGISTER_SAVE_RDX + 8)
7174+#define REGISTER_SAVE_R9 (REGISTER_SAVE_R8 + 8)
7175+#define REGISTER_SAVE_R10 (REGISTER_SAVE_R9 + 8)
7176+#define REGISTER_SAVE_R11 (REGISTER_SAVE_R10 + 8)
7177
7178 .text
7179
7180@@ -67,80 +80,26 @@ _dl_tlsdesc_undefweak:
7181 .size _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak
7182
7183 #ifdef SHARED
7184- .hidden _dl_tlsdesc_dynamic
7185- .global _dl_tlsdesc_dynamic
7186- .type _dl_tlsdesc_dynamic,@function
7187-
7188- /* %rax points to the TLS descriptor, such that 0(%rax) points to
7189- _dl_tlsdesc_dynamic itself, and 8(%rax) points to a struct
7190- tlsdesc_dynamic_arg object. It must return in %rax the offset
7191- between the thread pointer and the object denoted by the
7192- argument, without clobbering any registers.
7193-
7194- The assembly code that follows is a rendition of the following
7195- C code, hand-optimized a little bit.
7196-
7197-ptrdiff_t
7198-_dl_tlsdesc_dynamic (register struct tlsdesc *tdp asm ("%rax"))
7199-{
7200- struct tlsdesc_dynamic_arg *td = tdp->arg;
7201- dtv_t *dtv = *(dtv_t **)((char *)__thread_pointer + DTV_OFFSET);
7202- if (__builtin_expect (td->gen_count <= dtv[0].counter
7203- && (dtv[td->tlsinfo.ti_module].pointer.val
7204- != TLS_DTV_UNALLOCATED),
7205- 1))
7206- return dtv[td->tlsinfo.ti_module].pointer.val + td->tlsinfo.ti_offset
7207- - __thread_pointer;
7208-
7209- return __tls_get_addr_internal (&td->tlsinfo) - __thread_pointer;
7210-}
7211-*/
7212- cfi_startproc
7213- .align 16
7214-_dl_tlsdesc_dynamic:
7215- _CET_ENDBR
7216- /* Preserve call-clobbered registers that we modify.
7217- We need two scratch regs anyway. */
7218- movq %rsi, -16(%rsp)
7219- mov %fs:DTV_OFFSET, %RSI_LP
7220- movq %rdi, -8(%rsp)
7221- movq TLSDESC_ARG(%rax), %rdi
7222- movq (%rsi), %rax
7223- cmpq %rax, TLSDESC_GEN_COUNT(%rdi)
7224- ja .Lslow
7225- movq TLSDESC_MODID(%rdi), %rax
7226- salq $4, %rax
7227- movq (%rax,%rsi), %rax
7228- cmpq $-1, %rax
7229- je .Lslow
7230- addq TLSDESC_MODOFF(%rdi), %rax
7231-.Lret:
7232- movq -16(%rsp), %rsi
7233- sub %fs:0, %RAX_LP
7234- movq -8(%rsp), %rdi
7235- ret
7236-.Lslow:
7237- /* Besides rdi and rsi, saved above, save rdx, rcx, r8, r9,
7238- r10 and r11. Also, align the stack, that's off by 8 bytes. */
7239- subq $72, %rsp
7240- cfi_adjust_cfa_offset (72)
7241- movq %rdx, 8(%rsp)
7242- movq %rcx, 16(%rsp)
7243- movq %r8, 24(%rsp)
7244- movq %r9, 32(%rsp)
7245- movq %r10, 40(%rsp)
7246- movq %r11, 48(%rsp)
7247- /* %rdi already points to the tlsinfo data structure. */
7248- call HIDDEN_JUMPTARGET (__tls_get_addr)
7249- movq 8(%rsp), %rdx
7250- movq 16(%rsp), %rcx
7251- movq 24(%rsp), %r8
7252- movq 32(%rsp), %r9
7253- movq 40(%rsp), %r10
7254- movq 48(%rsp), %r11
7255- addq $72, %rsp
7256- cfi_adjust_cfa_offset (-72)
7257- jmp .Lret
7258- cfi_endproc
7259- .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic
7260+# if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL
7261+# define USE_FXSAVE
7262+# define STATE_SAVE_ALIGNMENT 16
7263+# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_fxsave
7264+# include "dl-tlsdesc-dynamic.h"
7265+# undef _dl_tlsdesc_dynamic
7266+# undef USE_FXSAVE
7267+# endif
7268+
7269+# define USE_XSAVE
7270+# define STATE_SAVE_ALIGNMENT 64
7271+# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_xsave
7272+# include "dl-tlsdesc-dynamic.h"
7273+# undef _dl_tlsdesc_dynamic
7274+# undef USE_XSAVE
7275+
7276+# define USE_XSAVEC
7277+# define STATE_SAVE_ALIGNMENT 64
7278+# define _dl_tlsdesc_dynamic _dl_tlsdesc_dynamic_xsavec
7279+# include "dl-tlsdesc-dynamic.h"
7280+# undef _dl_tlsdesc_dynamic
7281+# undef USE_XSAVEC
7282 #endif /* SHARED */
7283diff --git a/sysdeps/x86_64/dl-trampoline-save.h b/sysdeps/x86_64/dl-trampoline-save.h
7284new file mode 100644
7285index 0000000000..84eac4a8ac
7286--- /dev/null
7287+++ b/sysdeps/x86_64/dl-trampoline-save.h
7288@@ -0,0 +1,34 @@
7289+/* x86-64 PLT trampoline register save macros.
7290+ Copyright (C) 2024 Free Software Foundation, Inc.
7291+ This file is part of the GNU C Library.
7292+
7293+ The GNU C Library is free software; you can redistribute it and/or
7294+ modify it under the terms of the GNU Lesser General Public
7295+ License as published by the Free Software Foundation; either
7296+ version 2.1 of the License, or (at your option) any later version.
7297+
7298+ The GNU C Library is distributed in the hope that it will be useful,
7299+ but WITHOUT ANY WARRANTY; without even the implied warranty of
7300+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7301+ Lesser General Public License for more details.
7302+
7303+ You should have received a copy of the GNU Lesser General Public
7304+ License along with the GNU C Library; if not, see
7305+ <https://www.gnu.org/licenses/>. */
7306+
7307+#ifndef DL_STACK_ALIGNMENT
7308+/* Due to GCC bug:
7309+
7310+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066
7311+
7312+ __tls_get_addr may be called with 8-byte stack alignment. Although
7313+ this bug has been fixed in GCC 4.9.4, 5.3 and 6, we can't assume
7314+ that stack will be always aligned at 16 bytes. */
7315+# define DL_STACK_ALIGNMENT 8
7316+#endif
7317+
7318+/* True if _dl_runtime_resolve should align stack for STATE_SAVE or align
7319+ stack to 16 bytes before calling _dl_fixup. */
7320+#define DL_RUNTIME_RESOLVE_REALIGN_STACK \
7321+ (STATE_SAVE_ALIGNMENT > DL_STACK_ALIGNMENT \
7322+ || 16 > DL_STACK_ALIGNMENT)
7323diff --git a/sysdeps/x86_64/dl-trampoline-state.h b/sysdeps/x86_64/dl-trampoline-state.h
7324new file mode 100644
7325index 0000000000..575f120797
7326--- /dev/null
7327+++ b/sysdeps/x86_64/dl-trampoline-state.h
7328@@ -0,0 +1,51 @@
7329+/* x86-64 PLT dl-trampoline state macros.
7330+ Copyright (C) 2024 Free Software Foundation, Inc.
7331+ This file is part of the GNU C Library.
7332+
7333+ The GNU C Library is free software; you can redistribute it and/or
7334+ modify it under the terms of the GNU Lesser General Public
7335+ License as published by the Free Software Foundation; either
7336+ version 2.1 of the License, or (at your option) any later version.
7337+
7338+ The GNU C Library is distributed in the hope that it will be useful,
7339+ but WITHOUT ANY WARRANTY; without even the implied warranty of
7340+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7341+ Lesser General Public License for more details.
7342+
7343+ You should have received a copy of the GNU Lesser General Public
7344+ License along with the GNU C Library; if not, see
7345+ <https://www.gnu.org/licenses/>. */
7346+
7347+#if (STATE_SAVE_ALIGNMENT % 16) != 0
7348+# error STATE_SAVE_ALIGNMENT must be multiple of 16
7349+#endif
7350+
7351+#if (STATE_SAVE_OFFSET % STATE_SAVE_ALIGNMENT) != 0
7352+# error STATE_SAVE_OFFSET must be multiple of STATE_SAVE_ALIGNMENT
7353+#endif
7354+
7355+#if DL_RUNTIME_RESOLVE_REALIGN_STACK
7356+/* Local stack area before jumping to function address: RBX. */
7357+# define LOCAL_STORAGE_AREA 8
7358+# define BASE rbx
7359+# ifdef USE_FXSAVE
7360+/* Use fxsave to save XMM registers. */
7361+# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET)
7362+# if (REGISTER_SAVE_AREA % 16) != 0
7363+# error REGISTER_SAVE_AREA must be multiple of 16
7364+# endif
7365+# endif
7366+#else
7367+# ifndef USE_FXSAVE
7368+# error USE_FXSAVE must be defined
7369+# endif
7370+/* Use fxsave to save XMM registers. */
7371+# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET + 8)
7372+/* Local stack area before jumping to function address: All saved
7373+ registers. */
7374+# define LOCAL_STORAGE_AREA REGISTER_SAVE_AREA
7375+# define BASE rsp
7376+# if (REGISTER_SAVE_AREA % 16) != 8
7377+# error REGISTER_SAVE_AREA must be odd multiple of 8
7378+# endif
7379+#endif
7380diff --git a/sysdeps/x86_64/dl-trampoline.S b/sysdeps/x86_64/dl-trampoline.S
7381index b2e7e0f69b..87c5137837 100644
7382--- a/sysdeps/x86_64/dl-trampoline.S
7383+++ b/sysdeps/x86_64/dl-trampoline.S
7384@@ -22,25 +22,7 @@
7385 #include <features-offsets.h>
7386 #include <link-defines.h>
7387 #include <isa-level.h>
7388-
7389-#ifndef DL_STACK_ALIGNMENT
7390-/* Due to GCC bug:
7391-
7392- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066
7393-
7394- __tls_get_addr may be called with 8-byte stack alignment. Although
7395- this bug has been fixed in GCC 4.9.4, 5.3 and 6, we can't assume
7396- that stack will be always aligned at 16 bytes. We use unaligned
7397- 16-byte move to load and store SSE registers, which has no penalty
7398- on modern processors if stack is 16-byte aligned. */
7399-# define DL_STACK_ALIGNMENT 8
7400-#endif
7401-
7402-/* True if _dl_runtime_resolve should align stack for STATE_SAVE or align
7403- stack to 16 bytes before calling _dl_fixup. */
7404-#define DL_RUNTIME_RESOLVE_REALIGN_STACK \
7405- (STATE_SAVE_ALIGNMENT > DL_STACK_ALIGNMENT \
7406- || 16 > DL_STACK_ALIGNMENT)
7407+#include "dl-trampoline-save.h"
7408
7409 /* Area on stack to save and restore registers used for parameter
7410 passing when calling _dl_fixup. */
7411diff --git a/sysdeps/x86_64/dl-trampoline.h b/sysdeps/x86_64/dl-trampoline.h
7412index f55c6ea040..d9ccfb40d4 100644
7413--- a/sysdeps/x86_64/dl-trampoline.h
7414+++ b/sysdeps/x86_64/dl-trampoline.h
7415@@ -27,39 +27,7 @@
7416 # undef LOCAL_STORAGE_AREA
7417 # undef BASE
7418
7419-# if (STATE_SAVE_ALIGNMENT % 16) != 0
7420-# error STATE_SAVE_ALIGNMENT must be multiple of 16
7421-# endif
7422-
7423-# if (STATE_SAVE_OFFSET % STATE_SAVE_ALIGNMENT) != 0
7424-# error STATE_SAVE_OFFSET must be multiple of STATE_SAVE_ALIGNMENT
7425-# endif
7426-
7427-# if DL_RUNTIME_RESOLVE_REALIGN_STACK
7428-/* Local stack area before jumping to function address: RBX. */
7429-# define LOCAL_STORAGE_AREA 8
7430-# define BASE rbx
7431-# ifdef USE_FXSAVE
7432-/* Use fxsave to save XMM registers. */
7433-# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET)
7434-# if (REGISTER_SAVE_AREA % 16) != 0
7435-# error REGISTER_SAVE_AREA must be multiple of 16
7436-# endif
7437-# endif
7438-# else
7439-# ifndef USE_FXSAVE
7440-# error USE_FXSAVE must be defined
7441-# endif
7442-/* Use fxsave to save XMM registers. */
7443-# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET + 8)
7444-/* Local stack area before jumping to function address: All saved
7445- registers. */
7446-# define LOCAL_STORAGE_AREA REGISTER_SAVE_AREA
7447-# define BASE rsp
7448-# if (REGISTER_SAVE_AREA % 16) != 8
7449-# error REGISTER_SAVE_AREA must be odd multiple of 8
7450-# endif
7451-# endif
7452+# include "dl-trampoline-state.h"
7453
7454 .globl _dl_runtime_resolve
7455 .hidden _dl_runtime_resolve
7456diff --git a/sysdeps/x86_64/fpu/multiarch/Makefile b/sysdeps/x86_64/fpu/multiarch/Makefile
7457index ea81753b70..6ddd50240c 100644
7458--- a/sysdeps/x86_64/fpu/multiarch/Makefile
7459+++ b/sysdeps/x86_64/fpu/multiarch/Makefile
7460@@ -1,49 +1,4 @@
7461 ifeq ($(subdir),math)
7462-libm-sysdep_routines += \
7463- s_ceil-c \
7464- s_ceilf-c \
7465- s_floor-c \
7466- s_floorf-c \
7467- s_rint-c \
7468- s_rintf-c \
7469- s_nearbyint-c \
7470- s_nearbyintf-c \
7471- s_roundeven-c \
7472- s_roundevenf-c \
7473- s_trunc-c \
7474- s_truncf-c \
7475-# libm-sysdep_routines
7476-
7477-libm-sysdep_routines += \
7478- s_ceil-sse4_1 \
7479- s_ceilf-sse4_1 \
7480- s_floor-sse4_1 \
7481- s_floorf-sse4_1 \
7482- s_nearbyint-sse4_1 \
7483- s_nearbyintf-sse4_1 \
7484- s_roundeven-sse4_1 \
7485- s_roundevenf-sse4_1 \
7486- s_rint-sse4_1 \
7487- s_rintf-sse4_1 \
7488- s_trunc-sse4_1 \
7489- s_truncf-sse4_1 \
7490-# libm-sysdep_routines
7491-
7492-libm-sysdep_routines += \
7493- e_asin-fma \
7494- e_atan2-fma \
7495- e_exp-fma \
7496- e_log-fma \
7497- e_log2-fma \
7498- e_pow-fma \
7499- s_atan-fma \
7500- s_expm1-fma \
7501- s_log1p-fma \
7502- s_sin-fma \
7503- s_sincos-fma \
7504- s_tan-fma \
7505-# libm-sysdep_routines
7506-
7507 CFLAGS-e_asin-fma.c = -mfma -mavx2
7508 CFLAGS-e_atan2-fma.c = -mfma -mavx2
7509 CFLAGS-e_exp-fma.c = -mfma -mavx2
7510@@ -57,23 +12,6 @@ CFLAGS-s_sin-fma.c = -mfma -mavx2
7511 CFLAGS-s_tan-fma.c = -mfma -mavx2
7512 CFLAGS-s_sincos-fma.c = -mfma -mavx2
7513
7514-libm-sysdep_routines += \
7515- s_cosf-sse2 \
7516- s_sincosf-sse2 \
7517- s_sinf-sse2 \
7518-# libm-sysdep_routines
7519-
7520-libm-sysdep_routines += \
7521- e_exp2f-fma \
7522- e_expf-fma \
7523- e_log2f-fma \
7524- e_logf-fma \
7525- e_powf-fma \
7526- s_cosf-fma \
7527- s_sincosf-fma \
7528- s_sinf-fma \
7529-# libm-sysdep_routines
7530-
7531 CFLAGS-e_exp2f-fma.c = -mfma -mavx2
7532 CFLAGS-e_expf-fma.c = -mfma -mavx2
7533 CFLAGS-e_log2f-fma.c = -mfma -mavx2
7534@@ -83,17 +21,93 @@ CFLAGS-s_sinf-fma.c = -mfma -mavx2
7535 CFLAGS-s_cosf-fma.c = -mfma -mavx2
7536 CFLAGS-s_sincosf-fma.c = -mfma -mavx2
7537
7538+# Check if ISA level is 3 or above.
7539+ifneq (,$(filter $(have-x86-isa-level),$(x86-isa-level-3-or-above)))
7540+libm-sysdep_routines += \
7541+ s_ceil-avx \
7542+ s_ceilf-avx \
7543+ s_floor-avx \
7544+ s_floorf-avx \
7545+ s_nearbyint-avx \
7546+ s_nearbyintf-avx \
7547+ s_rint-avx \
7548+ s_rintf-avx \
7549+ s_roundeven-avx \
7550+ s_roundevenf-avx \
7551+ s_trunc-avx \
7552+ s_truncf-avx \
7553+# libm-sysdep_routines
7554+else
7555 libm-sysdep_routines += \
7556+ e_asin-fma \
7557+ e_asin-fma4 \
7558+ e_atan2-avx \
7559+ e_atan2-fma \
7560+ e_atan2-fma4 \
7561+ e_exp-avx \
7562+ e_exp-fma \
7563 e_exp-fma4 \
7564+ e_exp2f-fma \
7565+ e_expf-fma \
7566+ e_log-avx \
7567+ e_log-fma \
7568 e_log-fma4 \
7569+ e_log2-fma \
7570+ e_log2f-fma \
7571+ e_logf-fma \
7572+ e_pow-fma \
7573 e_pow-fma4 \
7574- e_asin-fma4 \
7575+ e_powf-fma \
7576+ s_atan-avx \
7577+ s_atan-fma \
7578 s_atan-fma4 \
7579- e_atan2-fma4 \
7580+ s_ceil-sse4_1 \
7581+ s_ceilf-sse4_1 \
7582+ s_cosf-fma \
7583+ s_cosf-sse2 \
7584+ s_expm1-fma \
7585+ s_floor-sse4_1 \
7586+ s_floorf-sse4_1 \
7587+ s_log1p-fma \
7588+ s_nearbyint-sse4_1 \
7589+ s_nearbyintf-sse4_1 \
7590+ s_rint-sse4_1 \
7591+ s_rintf-sse4_1 \
7592+ s_roundeven-sse4_1 \
7593+ s_roundevenf-sse4_1 \
7594+ s_sin-avx \
7595+ s_sin-fma \
7596 s_sin-fma4 \
7597+ s_sincos-avx \
7598+ s_sincos-fma \
7599 s_sincos-fma4 \
7600+ s_sincosf-fma \
7601+ s_sincosf-sse2 \
7602+ s_sinf-fma \
7603+ s_sinf-sse2 \
7604+ s_tan-avx \
7605+ s_tan-fma \
7606 s_tan-fma4 \
7607+ s_trunc-sse4_1 \
7608+ s_truncf-sse4_1 \
7609+# libm-sysdep_routines
7610+ifeq ($(have-x86-isa-level),baseline)
7611+libm-sysdep_routines += \
7612+ s_ceil-c \
7613+ s_ceilf-c \
7614+ s_floor-c \
7615+ s_floorf-c \
7616+ s_nearbyint-c \
7617+ s_nearbyintf-c \
7618+ s_rint-c \
7619+ s_rintf-c \
7620+ s_roundeven-c \
7621+ s_roundevenf-c \
7622+ s_trunc-c \
7623+ s_truncf-c \
7624 # libm-sysdep_routines
7625+endif
7626+endif
7627
7628 CFLAGS-e_asin-fma4.c = -mfma4
7629 CFLAGS-e_atan2-fma4.c = -mfma4
7630@@ -105,16 +119,6 @@ CFLAGS-s_sin-fma4.c = -mfma4
7631 CFLAGS-s_tan-fma4.c = -mfma4
7632 CFLAGS-s_sincos-fma4.c = -mfma4
7633
7634-libm-sysdep_routines += \
7635- e_exp-avx \
7636- e_log-avx \
7637- s_atan-avx \
7638- e_atan2-avx \
7639- s_sin-avx \
7640- s_sincos-avx \
7641- s_tan-avx \
7642-# libm-sysdep_routines
7643-
7644 CFLAGS-e_atan2-avx.c = -msse2avx -DSSE2AVX
7645 CFLAGS-e_exp-avx.c = -msse2avx -DSSE2AVX
7646 CFLAGS-e_log-avx.c = -msse2avx -DSSE2AVX
7647diff --git a/sysdeps/x86_64/fpu/multiarch/e_asin.c b/sysdeps/x86_64/fpu/multiarch/e_asin.c
7648index 2eaa6c2c04..d64fca2586 100644
7649--- a/sysdeps/x86_64/fpu/multiarch/e_asin.c
7650+++ b/sysdeps/x86_64/fpu/multiarch/e_asin.c
7651@@ -16,26 +16,29 @@
7652 License along with the GNU C Library; if not, see
7653 <https://www.gnu.org/licenses/>. */
7654
7655-#include <libm-alias-finite.h>
7656+#include <sysdeps/x86/isa-level.h>
7657+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
7658+# include <libm-alias-finite.h>
7659
7660 extern double __redirect_ieee754_asin (double);
7661 extern double __redirect_ieee754_acos (double);
7662
7663-#define SYMBOL_NAME ieee754_asin
7664-#include "ifunc-fma4.h"
7665+# define SYMBOL_NAME ieee754_asin
7666+# include "ifunc-fma4.h"
7667
7668 libc_ifunc_redirected (__redirect_ieee754_asin, __ieee754_asin,
7669 IFUNC_SELECTOR ());
7670 libm_alias_finite (__ieee754_asin, __asin)
7671
7672-#undef SYMBOL_NAME
7673-#define SYMBOL_NAME ieee754_acos
7674-#include "ifunc-fma4.h"
7675+# undef SYMBOL_NAME
7676+# define SYMBOL_NAME ieee754_acos
7677+# include "ifunc-fma4.h"
7678
7679 libc_ifunc_redirected (__redirect_ieee754_acos, __ieee754_acos,
7680 IFUNC_SELECTOR ());
7681 libm_alias_finite (__ieee754_acos, __acos)
7682
7683-#define __ieee754_acos __ieee754_acos_sse2
7684-#define __ieee754_asin __ieee754_asin_sse2
7685+# define __ieee754_acos __ieee754_acos_sse2
7686+# define __ieee754_asin __ieee754_asin_sse2
7687+#endif
7688 #include <sysdeps/ieee754/dbl-64/e_asin.c>
7689diff --git a/sysdeps/x86_64/fpu/multiarch/e_atan2.c b/sysdeps/x86_64/fpu/multiarch/e_atan2.c
7690index 17ee4f3c36..8a86c14ded 100644
7691--- a/sysdeps/x86_64/fpu/multiarch/e_atan2.c
7692+++ b/sysdeps/x86_64/fpu/multiarch/e_atan2.c
7693@@ -16,16 +16,19 @@
7694 License along with the GNU C Library; if not, see
7695 <https://www.gnu.org/licenses/>. */
7696
7697-#include <libm-alias-finite.h>
7698+#include <sysdeps/x86/isa-level.h>
7699+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
7700+# include <libm-alias-finite.h>
7701
7702 extern double __redirect_ieee754_atan2 (double, double);
7703
7704-#define SYMBOL_NAME ieee754_atan2
7705-#include "ifunc-avx-fma4.h"
7706+# define SYMBOL_NAME ieee754_atan2
7707+# include "ifunc-avx-fma4.h"
7708
7709 libc_ifunc_redirected (__redirect_ieee754_atan2,
7710 __ieee754_atan2, IFUNC_SELECTOR ());
7711 libm_alias_finite (__ieee754_atan2, __atan2)
7712
7713-#define __ieee754_atan2 __ieee754_atan2_sse2
7714+# define __ieee754_atan2 __ieee754_atan2_sse2
7715+#endif
7716 #include <sysdeps/ieee754/dbl-64/e_atan2.c>
7717diff --git a/sysdeps/x86_64/fpu/multiarch/e_exp.c b/sysdeps/x86_64/fpu/multiarch/e_exp.c
7718index 406b7ebd44..d56329291a 100644
7719--- a/sysdeps/x86_64/fpu/multiarch/e_exp.c
7720+++ b/sysdeps/x86_64/fpu/multiarch/e_exp.c
7721@@ -16,17 +16,20 @@
7722 License along with the GNU C Library; if not, see
7723 <https://www.gnu.org/licenses/>. */
7724
7725-#include <math.h>
7726-#include <libm-alias-finite.h>
7727+#include <sysdeps/x86/isa-level.h>
7728+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
7729+# include <math.h>
7730+# include <libm-alias-finite.h>
7731
7732 extern double __redirect_ieee754_exp (double);
7733
7734-#define SYMBOL_NAME ieee754_exp
7735-#include "ifunc-avx-fma4.h"
7736+# define SYMBOL_NAME ieee754_exp
7737+# include "ifunc-avx-fma4.h"
7738
7739 libc_ifunc_redirected (__redirect_ieee754_exp, __ieee754_exp,
7740 IFUNC_SELECTOR ());
7741 libm_alias_finite (__ieee754_exp, __exp)
7742
7743-#define __exp __ieee754_exp_sse2
7744+# define __exp __ieee754_exp_sse2
7745+#endif
7746 #include <sysdeps/ieee754/dbl-64/e_exp.c>
7747diff --git a/sysdeps/x86_64/fpu/multiarch/e_exp2f.c b/sysdeps/x86_64/fpu/multiarch/e_exp2f.c
7748index 804fd6be85..06fe5028d6 100644
7749--- a/sysdeps/x86_64/fpu/multiarch/e_exp2f.c
7750+++ b/sysdeps/x86_64/fpu/multiarch/e_exp2f.c
7751@@ -16,25 +16,28 @@
7752 License along with the GNU C Library; if not, see
7753 <https://www.gnu.org/licenses/>. */
7754
7755-#include <libm-alias-float.h>
7756-#include <libm-alias-finite.h>
7757+#include <sysdeps/x86/isa-level.h>
7758+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
7759+# include <libm-alias-float.h>
7760+# include <libm-alias-finite.h>
7761
7762 extern float __redirect_exp2f (float);
7763
7764-#define SYMBOL_NAME exp2f
7765-#include "ifunc-fma.h"
7766+# define SYMBOL_NAME exp2f
7767+# include "ifunc-fma.h"
7768
7769 libc_ifunc_redirected (__redirect_exp2f, __exp2f, IFUNC_SELECTOR ());
7770
7771-#ifdef SHARED
7772+# ifdef SHARED
7773 versioned_symbol (libm, __ieee754_exp2f, exp2f, GLIBC_2_27);
7774 libm_alias_float_other (__exp2, exp2)
7775-#else
7776+# else
7777 libm_alias_float (__exp2, exp2)
7778-#endif
7779+# endif
7780
7781 strong_alias (__exp2f, __ieee754_exp2f)
7782 libm_alias_finite (__exp2f, __exp2f)
7783
7784-#define __exp2f __exp2f_sse2
7785+# define __exp2f __exp2f_sse2
7786+#endif
7787 #include <sysdeps/ieee754/flt-32/e_exp2f.c>
7788diff --git a/sysdeps/x86_64/fpu/multiarch/e_expf.c b/sysdeps/x86_64/fpu/multiarch/e_expf.c
7789index 4a7e2a5bce..19d767f636 100644
7790--- a/sysdeps/x86_64/fpu/multiarch/e_expf.c
7791+++ b/sysdeps/x86_64/fpu/multiarch/e_expf.c
7792@@ -16,28 +16,31 @@
7793 License along with the GNU C Library; if not, see
7794 <https://www.gnu.org/licenses/>. */
7795
7796-#include <libm-alias-float.h>
7797-#include <libm-alias-finite.h>
7798+#include <sysdeps/x86/isa-level.h>
7799+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
7800+# include <libm-alias-float.h>
7801+# include <libm-alias-finite.h>
7802
7803 extern float __redirect_expf (float);
7804
7805-#define SYMBOL_NAME expf
7806-#include "ifunc-fma.h"
7807+# define SYMBOL_NAME expf
7808+# include "ifunc-fma.h"
7809
7810 libc_ifunc_redirected (__redirect_expf, __expf, IFUNC_SELECTOR ());
7811
7812-#ifdef SHARED
7813+# ifdef SHARED
7814 __hidden_ver1 (__expf, __GI___expf, __redirect_expf)
7815 __attribute__ ((visibility ("hidden")));
7816
7817 versioned_symbol (libm, __ieee754_expf, expf, GLIBC_2_27);
7818 libm_alias_float_other (__exp, exp)
7819-#else
7820+# else
7821 libm_alias_float (__exp, exp)
7822-#endif
7823+# endif
7824
7825 strong_alias (__expf, __ieee754_expf)
7826 libm_alias_finite (__expf, __expf)
7827
7828-#define __expf __expf_sse2
7829+# define __expf __expf_sse2
7830+#endif
7831 #include <sysdeps/ieee754/flt-32/e_expf.c>
7832diff --git a/sysdeps/x86_64/fpu/multiarch/e_log.c b/sysdeps/x86_64/fpu/multiarch/e_log.c
7833index 067fbf58c3..d80c1b1463 100644
7834--- a/sysdeps/x86_64/fpu/multiarch/e_log.c
7835+++ b/sysdeps/x86_64/fpu/multiarch/e_log.c
7836@@ -16,17 +16,20 @@
7837 License along with the GNU C Library; if not, see
7838 <https://www.gnu.org/licenses/>. */
7839
7840-#include <math.h>
7841-#include <libm-alias-finite.h>
7842+#include <sysdeps/x86/isa-level.h>
7843+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
7844+# include <math.h>
7845+# include <libm-alias-finite.h>
7846
7847 extern double __redirect_ieee754_log (double);
7848
7849-#define SYMBOL_NAME ieee754_log
7850-#include "ifunc-avx-fma4.h"
7851+# define SYMBOL_NAME ieee754_log
7852+# include "ifunc-avx-fma4.h"
7853
7854 libc_ifunc_redirected (__redirect_ieee754_log, __ieee754_log,
7855 IFUNC_SELECTOR ());
7856 libm_alias_finite (__ieee754_log, __log)
7857
7858-#define __log __ieee754_log_sse2
7859+# define __log __ieee754_log_sse2
7860+#endif
7861 #include <sysdeps/ieee754/dbl-64/e_log.c>
7862diff --git a/sysdeps/x86_64/fpu/multiarch/e_log2.c b/sysdeps/x86_64/fpu/multiarch/e_log2.c
7863index 9c57a2f6cc..9686782c09 100644
7864--- a/sysdeps/x86_64/fpu/multiarch/e_log2.c
7865+++ b/sysdeps/x86_64/fpu/multiarch/e_log2.c
7866@@ -16,28 +16,31 @@
7867 License along with the GNU C Library; if not, see
7868 <https://www.gnu.org/licenses/>. */
7869
7870-#include <libm-alias-double.h>
7871-#include <libm-alias-finite.h>
7872+#include <sysdeps/x86/isa-level.h>
7873+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
7874+# include <libm-alias-double.h>
7875+# include <libm-alias-finite.h>
7876
7877 extern double __redirect_log2 (double);
7878
7879-#define SYMBOL_NAME log2
7880-#include "ifunc-fma.h"
7881+# define SYMBOL_NAME log2
7882+# include "ifunc-fma.h"
7883
7884 libc_ifunc_redirected (__redirect_log2, __log2, IFUNC_SELECTOR ());
7885
7886-#ifdef SHARED
7887+# ifdef SHARED
7888 __hidden_ver1 (__log2, __GI___log2, __redirect_log2)
7889 __attribute__ ((visibility ("hidden")));
7890
7891 versioned_symbol (libm, __ieee754_log2, log2, GLIBC_2_29);
7892 libm_alias_double_other (__log2, log2)
7893-#else
7894+# else
7895 libm_alias_double (__log2, log2)
7896-#endif
7897+# endif
7898
7899 strong_alias (__log2, __ieee754_log2)
7900 libm_alias_finite (__log2, __log2)
7901
7902-#define __log2 __log2_sse2
7903+# define __log2 __log2_sse2
7904+#endif
7905 #include <sysdeps/ieee754/dbl-64/e_log2.c>
7906diff --git a/sysdeps/x86_64/fpu/multiarch/e_log2f.c b/sysdeps/x86_64/fpu/multiarch/e_log2f.c
7907index 2b45c87f38..8ada46e11e 100644
7908--- a/sysdeps/x86_64/fpu/multiarch/e_log2f.c
7909+++ b/sysdeps/x86_64/fpu/multiarch/e_log2f.c
7910@@ -16,28 +16,31 @@
7911 License along with the GNU C Library; if not, see
7912 <https://www.gnu.org/licenses/>. */
7913
7914-#include <libm-alias-float.h>
7915-#include <libm-alias-finite.h>
7916+#include <sysdeps/x86/isa-level.h>
7917+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
7918+# include <libm-alias-float.h>
7919+# include <libm-alias-finite.h>
7920
7921 extern float __redirect_log2f (float);
7922
7923-#define SYMBOL_NAME log2f
7924-#include "ifunc-fma.h"
7925+# define SYMBOL_NAME log2f
7926+# include "ifunc-fma.h"
7927
7928 libc_ifunc_redirected (__redirect_log2f, __log2f, IFUNC_SELECTOR ());
7929
7930-#ifdef SHARED
7931+# ifdef SHARED
7932 __hidden_ver1 (__log2f, __GI___log2f, __redirect_log2f)
7933 __attribute__ ((visibility ("hidden")));
7934
7935 versioned_symbol (libm, __ieee754_log2f, log2f, GLIBC_2_27);
7936 libm_alias_float_other (__log2, log2)
7937-#else
7938+# else
7939 libm_alias_float (__log2, log2)
7940-#endif
7941+# endif
7942
7943 strong_alias (__log2f, __ieee754_log2f)
7944 libm_alias_finite (__log2f, __log2f)
7945
7946-#define __log2f __log2f_sse2
7947+# define __log2f __log2f_sse2
7948+#endif
7949 #include <sysdeps/ieee754/flt-32/e_log2f.c>
7950diff --git a/sysdeps/x86_64/fpu/multiarch/e_logf.c b/sysdeps/x86_64/fpu/multiarch/e_logf.c
7951index 97e23c8fea..a3978d9a8e 100644
7952--- a/sysdeps/x86_64/fpu/multiarch/e_logf.c
7953+++ b/sysdeps/x86_64/fpu/multiarch/e_logf.c
7954@@ -16,28 +16,31 @@
7955 License along with the GNU C Library; if not, see
7956 <https://www.gnu.org/licenses/>. */
7957
7958-#include <libm-alias-float.h>
7959-#include <libm-alias-finite.h>
7960+#include <sysdeps/x86/isa-level.h>
7961+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
7962+# include <libm-alias-float.h>
7963+# include <libm-alias-finite.h>
7964
7965 extern float __redirect_logf (float);
7966
7967-#define SYMBOL_NAME logf
7968-#include "ifunc-fma.h"
7969+# define SYMBOL_NAME logf
7970+# include "ifunc-fma.h"
7971
7972 libc_ifunc_redirected (__redirect_logf, __logf, IFUNC_SELECTOR ());
7973
7974-#ifdef SHARED
7975+# ifdef SHARED
7976 __hidden_ver1 (__logf, __GI___logf, __redirect_logf)
7977 __attribute__ ((visibility ("hidden")));
7978
7979 versioned_symbol (libm, __ieee754_logf, logf, GLIBC_2_27);
7980 libm_alias_float_other (__log, log)
7981-#else
7982+# else
7983 libm_alias_float (__log, log)
7984-#endif
7985+# endif
7986
7987 strong_alias (__logf, __ieee754_logf)
7988 libm_alias_finite (__logf, __logf)
7989
7990-#define __logf __logf_sse2
7991+# define __logf __logf_sse2
7992+#endif
7993 #include <sysdeps/ieee754/flt-32/e_logf.c>
7994diff --git a/sysdeps/x86_64/fpu/multiarch/e_pow.c b/sysdeps/x86_64/fpu/multiarch/e_pow.c
7995index 42618e7112..f8f17aff9f 100644
7996--- a/sysdeps/x86_64/fpu/multiarch/e_pow.c
7997+++ b/sysdeps/x86_64/fpu/multiarch/e_pow.c
7998@@ -16,17 +16,20 @@
7999 License along with the GNU C Library; if not, see
8000 <https://www.gnu.org/licenses/>. */
8001
8002-#include <math.h>
8003-#include <libm-alias-finite.h>
8004+#include <sysdeps/x86/isa-level.h>
8005+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
8006+# include <math.h>
8007+# include <libm-alias-finite.h>
8008
8009 extern double __redirect_ieee754_pow (double, double);
8010
8011-#define SYMBOL_NAME ieee754_pow
8012-#include "ifunc-fma4.h"
8013+# define SYMBOL_NAME ieee754_pow
8014+# include "ifunc-fma4.h"
8015
8016 libc_ifunc_redirected (__redirect_ieee754_pow,
8017 __ieee754_pow, IFUNC_SELECTOR ());
8018 libm_alias_finite (__ieee754_pow, __pow)
8019
8020-#define __pow __ieee754_pow_sse2
8021+# define __pow __ieee754_pow_sse2
8022+#endif
8023 #include <sysdeps/ieee754/dbl-64/e_pow.c>
8024diff --git a/sysdeps/x86_64/fpu/multiarch/e_powf.c b/sysdeps/x86_64/fpu/multiarch/e_powf.c
8025index 8e6ce13cc1..8b1a4c7d04 100644
8026--- a/sysdeps/x86_64/fpu/multiarch/e_powf.c
8027+++ b/sysdeps/x86_64/fpu/multiarch/e_powf.c
8028@@ -16,31 +16,34 @@
8029 License along with the GNU C Library; if not, see
8030 <https://www.gnu.org/licenses/>. */
8031
8032-#include <libm-alias-float.h>
8033-#include <libm-alias-finite.h>
8034+#include <sysdeps/x86/isa-level.h>
8035+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
8036+# include <libm-alias-float.h>
8037+# include <libm-alias-finite.h>
8038
8039-#define powf __redirect_powf
8040-#define __DECL_SIMD___redirect_powf
8041-#include <math.h>
8042-#undef powf
8043+# define powf __redirect_powf
8044+# define __DECL_SIMD___redirect_powf
8045+# include <math.h>
8046+# undef powf
8047
8048-#define SYMBOL_NAME powf
8049-#include "ifunc-fma.h"
8050+# define SYMBOL_NAME powf
8051+# include "ifunc-fma.h"
8052
8053 libc_ifunc_redirected (__redirect_powf, __powf, IFUNC_SELECTOR ());
8054
8055-#ifdef SHARED
8056+# ifdef SHARED
8057 __hidden_ver1 (__powf, __GI___powf, __redirect_powf)
8058 __attribute__ ((visibility ("hidden")));
8059
8060 versioned_symbol (libm, __ieee754_powf, powf, GLIBC_2_27);
8061 libm_alias_float_other (__pow, pow)
8062-#else
8063+# else
8064 libm_alias_float (__pow, pow)
8065-#endif
8066+# endif
8067
8068 strong_alias (__powf, __ieee754_powf)
8069 libm_alias_finite (__powf, __powf)
8070
8071-#define __powf __powf_sse2
8072+# define __powf __powf_sse2
8073+#endif
8074 #include <sysdeps/ieee754/flt-32/e_powf.c>
8075diff --git a/sysdeps/x86_64/fpu/multiarch/s_atan.c b/sysdeps/x86_64/fpu/multiarch/s_atan.c
8076index 71bad096a9..4d2c6ce006 100644
8077--- a/sysdeps/x86_64/fpu/multiarch/s_atan.c
8078+++ b/sysdeps/x86_64/fpu/multiarch/s_atan.c
8079@@ -16,15 +16,18 @@
8080 License along with the GNU C Library; if not, see
8081 <https://www.gnu.org/licenses/>. */
8082
8083-#include <libm-alias-double.h>
8084+#include <sysdeps/x86/isa-level.h>
8085+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
8086+# include <libm-alias-double.h>
8087
8088 extern double __redirect_atan (double);
8089
8090-#define SYMBOL_NAME atan
8091-#include "ifunc-avx-fma4.h"
8092+# define SYMBOL_NAME atan
8093+# include "ifunc-avx-fma4.h"
8094
8095 libc_ifunc_redirected (__redirect_atan, __atan, IFUNC_SELECTOR ());
8096 libm_alias_double (__atan, atan)
8097
8098-#define __atan __atan_sse2
8099+# define __atan __atan_sse2
8100+#endif
8101 #include <sysdeps/ieee754/dbl-64/s_atan.c>
8102diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceil-avx.S b/sysdeps/x86_64/fpu/multiarch/s_ceil-avx.S
8103new file mode 100644
8104index 0000000000..e6c1106753
8105--- /dev/null
8106+++ b/sysdeps/x86_64/fpu/multiarch/s_ceil-avx.S
8107@@ -0,0 +1,28 @@
8108+/* AVX implementation of ceil function.
8109+ Copyright (C) 2024 Free Software Foundation, Inc.
8110+ This file is part of the GNU C Library.
8111+
8112+ The GNU C Library is free software; you can redistribute it and/or
8113+ modify it under the terms of the GNU Lesser General Public
8114+ License as published by the Free Software Foundation; either
8115+ version 2.1 of the License, or (at your option) any later version.
8116+
8117+ The GNU C Library is distributed in the hope that it will be useful,
8118+ but WITHOUT ANY WARRANTY; without even the implied warranty of
8119+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8120+ Lesser General Public License for more details.
8121+
8122+ You should have received a copy of the GNU Lesser General Public
8123+ License along with the GNU C Library; if not, see
8124+ <https://www.gnu.org/licenses/>. */
8125+
8126+#include <sysdep.h>
8127+#include <libm-alias-double.h>
8128+
8129+ .text
8130+ENTRY(__ceil)
8131+ vroundsd $10, %xmm0, %xmm0, %xmm0
8132+ ret
8133+END(__ceil)
8134+
8135+libm_alias_double (__ceil, ceil)
8136diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceil-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_ceil-sse4_1.S
8137index 64119011ad..dba756c38f 100644
8138--- a/sysdeps/x86_64/fpu/multiarch/s_ceil-sse4_1.S
8139+++ b/sysdeps/x86_64/fpu/multiarch/s_ceil-sse4_1.S
8140@@ -17,8 +17,20 @@
8141
8142 #include <sysdep.h>
8143
8144+#include <sysdeps/x86/isa-level.h>
8145+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8146+# include <libm-alias-double.h>
8147+# define __ceil_sse41 __ceil
8148+ .text
8149+#else
8150 .section .text.sse4.1,"ax",@progbits
8151+#endif
8152+
8153 ENTRY(__ceil_sse41)
8154 roundsd $10, %xmm0, %xmm0
8155 ret
8156 END(__ceil_sse41)
8157+
8158+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8159+libm_alias_double (__ceil, ceil)
8160+#endif
8161diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceil.c b/sysdeps/x86_64/fpu/multiarch/s_ceil.c
8162index cc028addee..46c8e91e19 100644
8163--- a/sysdeps/x86_64/fpu/multiarch/s_ceil.c
8164+++ b/sysdeps/x86_64/fpu/multiarch/s_ceil.c
8165@@ -16,17 +16,20 @@
8166 License along with the GNU C Library; if not, see
8167 <https://www.gnu.org/licenses/>. */
8168
8169-#define NO_MATH_REDIRECT
8170-#include <libm-alias-double.h>
8171+#include <sysdeps/x86/isa-level.h>
8172+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
8173+# define NO_MATH_REDIRECT
8174+# include <libm-alias-double.h>
8175
8176-#define ceil __redirect_ceil
8177-#define __ceil __redirect___ceil
8178-#include <math.h>
8179-#undef ceil
8180-#undef __ceil
8181+# define ceil __redirect_ceil
8182+# define __ceil __redirect___ceil
8183+# include <math.h>
8184+# undef ceil
8185+# undef __ceil
8186
8187-#define SYMBOL_NAME ceil
8188-#include "ifunc-sse4_1.h"
8189+# define SYMBOL_NAME ceil
8190+# include "ifunc-sse4_1.h"
8191
8192 libc_ifunc_redirected (__redirect_ceil, __ceil, IFUNC_SELECTOR ());
8193 libm_alias_double (__ceil, ceil)
8194+#endif
8195diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceilf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_ceilf-avx.S
8196new file mode 100644
8197index 0000000000..b4d8ac0455
8198--- /dev/null
8199+++ b/sysdeps/x86_64/fpu/multiarch/s_ceilf-avx.S
8200@@ -0,0 +1,28 @@
8201+/* AVX implementation of ceilf function.
8202+ Copyright (C) 2024 Free Software Foundation, Inc.
8203+ This file is part of the GNU C Library.
8204+
8205+ The GNU C Library is free software; you can redistribute it and/or
8206+ modify it under the terms of the GNU Lesser General Public
8207+ License as published by the Free Software Foundation; either
8208+ version 2.1 of the License, or (at your option) any later version.
8209+
8210+ The GNU C Library is distributed in the hope that it will be useful,
8211+ but WITHOUT ANY WARRANTY; without even the implied warranty of
8212+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8213+ Lesser General Public License for more details.
8214+
8215+ You should have received a copy of the GNU Lesser General Public
8216+ License along with the GNU C Library; if not, see
8217+ <https://www.gnu.org/licenses/>. */
8218+
8219+#include <sysdep.h>
8220+#include <libm-alias-float.h>
8221+
8222+ .text
8223+ENTRY(__ceilf)
8224+ vroundss $10, %xmm0, %xmm0, %xmm0
8225+ ret
8226+END(__ceilf)
8227+
8228+libm_alias_float (__ceil, ceil)
8229diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceilf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_ceilf-sse4_1.S
8230index dd9a9f6b71..9abc87b91a 100644
8231--- a/sysdeps/x86_64/fpu/multiarch/s_ceilf-sse4_1.S
8232+++ b/sysdeps/x86_64/fpu/multiarch/s_ceilf-sse4_1.S
8233@@ -17,8 +17,20 @@
8234
8235 #include <sysdep.h>
8236
8237+#include <sysdeps/x86/isa-level.h>
8238+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8239+# include <libm-alias-float.h>
8240+# define __ceilf_sse41 __ceilf
8241+ .text
8242+#else
8243 .section .text.sse4.1,"ax",@progbits
8244+#endif
8245+
8246 ENTRY(__ceilf_sse41)
8247 roundss $10, %xmm0, %xmm0
8248 ret
8249 END(__ceilf_sse41)
8250+
8251+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8252+libm_alias_float (__ceil, ceil)
8253+#endif
8254diff --git a/sysdeps/x86_64/fpu/multiarch/s_ceilf.c b/sysdeps/x86_64/fpu/multiarch/s_ceilf.c
8255index 97a0ca7d19..bb53108f73 100644
8256--- a/sysdeps/x86_64/fpu/multiarch/s_ceilf.c
8257+++ b/sysdeps/x86_64/fpu/multiarch/s_ceilf.c
8258@@ -16,17 +16,20 @@
8259 License along with the GNU C Library; if not, see
8260 <https://www.gnu.org/licenses/>. */
8261
8262-#define NO_MATH_REDIRECT
8263-#include <libm-alias-float.h>
8264+#include <sysdeps/x86/isa-level.h>
8265+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
8266+# define NO_MATH_REDIRECT
8267+# include <libm-alias-float.h>
8268
8269-#define ceilf __redirect_ceilf
8270-#define __ceilf __redirect___ceilf
8271-#include <math.h>
8272-#undef ceilf
8273-#undef __ceilf
8274+# define ceilf __redirect_ceilf
8275+# define __ceilf __redirect___ceilf
8276+# include <math.h>
8277+# undef ceilf
8278+# undef __ceilf
8279
8280-#define SYMBOL_NAME ceilf
8281-#include "ifunc-sse4_1.h"
8282+# define SYMBOL_NAME ceilf
8283+# include "ifunc-sse4_1.h"
8284
8285 libc_ifunc_redirected (__redirect_ceilf, __ceilf, IFUNC_SELECTOR ());
8286 libm_alias_float (__ceil, ceil)
8287+#endif
8288diff --git a/sysdeps/x86_64/fpu/multiarch/s_cosf.c b/sysdeps/x86_64/fpu/multiarch/s_cosf.c
8289index 2703c576df..8a02e04538 100644
8290--- a/sysdeps/x86_64/fpu/multiarch/s_cosf.c
8291+++ b/sysdeps/x86_64/fpu/multiarch/s_cosf.c
8292@@ -16,13 +16,18 @@
8293 License along with the GNU C Library; if not, see
8294 <https://www.gnu.org/licenses/>. */
8295
8296-#include <libm-alias-float.h>
8297+#include <sysdeps/x86/isa-level.h>
8298+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
8299+# include <libm-alias-float.h>
8300
8301 extern float __redirect_cosf (float);
8302
8303-#define SYMBOL_NAME cosf
8304-#include "ifunc-fma.h"
8305+# define SYMBOL_NAME cosf
8306+# include "ifunc-fma.h"
8307
8308 libc_ifunc_redirected (__redirect_cosf, __cosf, IFUNC_SELECTOR ());
8309
8310 libm_alias_float (__cos, cos)
8311+#else
8312+# include <sysdeps/ieee754/flt-32/s_cosf.c>
8313+#endif
8314diff --git a/sysdeps/x86_64/fpu/multiarch/s_expm1.c b/sysdeps/x86_64/fpu/multiarch/s_expm1.c
8315index 8a2d69f9b2..d58ef3d8f5 100644
8316--- a/sysdeps/x86_64/fpu/multiarch/s_expm1.c
8317+++ b/sysdeps/x86_64/fpu/multiarch/s_expm1.c
8318@@ -16,21 +16,24 @@
8319 License along with the GNU C Library; if not, see
8320 <https://www.gnu.org/licenses/>. */
8321
8322-#include <libm-alias-double.h>
8323+#include <sysdeps/x86/isa-level.h>
8324+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
8325+# include <libm-alias-double.h>
8326
8327 extern double __redirect_expm1 (double);
8328
8329-#define SYMBOL_NAME expm1
8330-#include "ifunc-fma.h"
8331+# define SYMBOL_NAME expm1
8332+# include "ifunc-fma.h"
8333
8334 libc_ifunc_redirected (__redirect_expm1, __expm1, IFUNC_SELECTOR ());
8335 libm_alias_double (__expm1, expm1)
8336
8337-#define __expm1 __expm1_sse2
8338+# define __expm1 __expm1_sse2
8339
8340 /* NB: __expm1 may be expanded to __expm1_sse2 in the following
8341 prototypes. */
8342 extern long double __expm1l (long double);
8343 extern long double __expm1f128 (long double);
8344
8345+#endif
8346 #include <sysdeps/ieee754/dbl-64/s_expm1.c>
8347diff --git a/sysdeps/x86_64/fpu/multiarch/s_floor-avx.S b/sysdeps/x86_64/fpu/multiarch/s_floor-avx.S
8348new file mode 100644
8349index 0000000000..ff74b5a8bf
8350--- /dev/null
8351+++ b/sysdeps/x86_64/fpu/multiarch/s_floor-avx.S
8352@@ -0,0 +1,28 @@
8353+/* AVX implementation of floor function.
8354+ Copyright (C) 2024 Free Software Foundation, Inc.
8355+ This file is part of the GNU C Library.
8356+
8357+ The GNU C Library is free software; you can redistribute it and/or
8358+ modify it under the terms of the GNU Lesser General Public
8359+ License as published by the Free Software Foundation; either
8360+ version 2.1 of the License, or (at your option) any later version.
8361+
8362+ The GNU C Library is distributed in the hope that it will be useful,
8363+ but WITHOUT ANY WARRANTY; without even the implied warranty of
8364+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8365+ Lesser General Public License for more details.
8366+
8367+ You should have received a copy of the GNU Lesser General Public
8368+ License along with the GNU C Library; if not, see
8369+ <https://www.gnu.org/licenses/>. */
8370+
8371+#include <sysdep.h>
8372+#include <libm-alias-double.h>
8373+
8374+ .text
8375+ENTRY(__floor)
8376+ vroundsd $9, %xmm0, %xmm0, %xmm0
8377+ ret
8378+END(__floor)
8379+
8380+libm_alias_double (__floor, floor)
8381diff --git a/sysdeps/x86_64/fpu/multiarch/s_floor-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_floor-sse4_1.S
8382index 2f7521f39f..c9b9b0639b 100644
8383--- a/sysdeps/x86_64/fpu/multiarch/s_floor-sse4_1.S
8384+++ b/sysdeps/x86_64/fpu/multiarch/s_floor-sse4_1.S
8385@@ -17,8 +17,20 @@
8386
8387 #include <sysdep.h>
8388
8389+#include <sysdeps/x86/isa-level.h>
8390+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8391+# include <libm-alias-double.h>
8392+# define __floor_sse41 __floor
8393+ .text
8394+#else
8395 .section .text.sse4.1,"ax",@progbits
8396+#endif
8397+
8398 ENTRY(__floor_sse41)
8399 roundsd $9, %xmm0, %xmm0
8400 ret
8401 END(__floor_sse41)
8402+
8403+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8404+libm_alias_double (__floor, floor)
8405+#endif
8406diff --git a/sysdeps/x86_64/fpu/multiarch/s_floor.c b/sysdeps/x86_64/fpu/multiarch/s_floor.c
8407index 8cebd48e10..2c87dd0056 100644
8408--- a/sysdeps/x86_64/fpu/multiarch/s_floor.c
8409+++ b/sysdeps/x86_64/fpu/multiarch/s_floor.c
8410@@ -16,17 +16,20 @@
8411 License along with the GNU C Library; if not, see
8412 <https://www.gnu.org/licenses/>. */
8413
8414-#define NO_MATH_REDIRECT
8415-#include <libm-alias-double.h>
8416+#include <sysdeps/x86/isa-level.h>
8417+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
8418+# define NO_MATH_REDIRECT
8419+# include <libm-alias-double.h>
8420
8421-#define floor __redirect_floor
8422-#define __floor __redirect___floor
8423-#include <math.h>
8424-#undef floor
8425-#undef __floor
8426+# define floor __redirect_floor
8427+# define __floor __redirect___floor
8428+# include <math.h>
8429+# undef floor
8430+# undef __floor
8431
8432-#define SYMBOL_NAME floor
8433-#include "ifunc-sse4_1.h"
8434+# define SYMBOL_NAME floor
8435+# include "ifunc-sse4_1.h"
8436
8437 libc_ifunc_redirected (__redirect_floor, __floor, IFUNC_SELECTOR ());
8438 libm_alias_double (__floor, floor)
8439+#endif
8440diff --git a/sysdeps/x86_64/fpu/multiarch/s_floorf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_floorf-avx.S
8441new file mode 100644
8442index 0000000000..c378baae8e
8443--- /dev/null
8444+++ b/sysdeps/x86_64/fpu/multiarch/s_floorf-avx.S
8445@@ -0,0 +1,28 @@
8446+/* AVX implementation of floorf function.
8447+ Copyright (C) 2024 Free Software Foundation, Inc.
8448+ This file is part of the GNU C Library.
8449+
8450+ The GNU C Library is free software; you can redistribute it and/or
8451+ modify it under the terms of the GNU Lesser General Public
8452+ License as published by the Free Software Foundation; either
8453+ version 2.1 of the License, or (at your option) any later version.
8454+
8455+ The GNU C Library is distributed in the hope that it will be useful,
8456+ but WITHOUT ANY WARRANTY; without even the implied warranty of
8457+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8458+ Lesser General Public License for more details.
8459+
8460+ You should have received a copy of the GNU Lesser General Public
8461+ License along with the GNU C Library; if not, see
8462+ <https://www.gnu.org/licenses/>. */
8463+
8464+#include <sysdep.h>
8465+#include <libm-alias-float.h>
8466+
8467+ .text
8468+ENTRY(__floorf)
8469+ vroundss $9, %xmm0, %xmm0, %xmm0
8470+ ret
8471+END(__floorf)
8472+
8473+libm_alias_float (__floor, floor)
8474diff --git a/sysdeps/x86_64/fpu/multiarch/s_floorf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_floorf-sse4_1.S
8475index 5f6020d27d..c2216899db 100644
8476--- a/sysdeps/x86_64/fpu/multiarch/s_floorf-sse4_1.S
8477+++ b/sysdeps/x86_64/fpu/multiarch/s_floorf-sse4_1.S
8478@@ -17,8 +17,20 @@
8479
8480 #include <sysdep.h>
8481
8482+#include <sysdeps/x86/isa-level.h>
8483+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8484+# include <libm-alias-float.h>
8485+# define __floorf_sse41 __floorf
8486+ .text
8487+#else
8488 .section .text.sse4.1,"ax",@progbits
8489+#endif
8490+
8491 ENTRY(__floorf_sse41)
8492 roundss $9, %xmm0, %xmm0
8493 ret
8494 END(__floorf_sse41)
8495+
8496+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8497+libm_alias_float (__floor, floor)
8498+#endif
8499diff --git a/sysdeps/x86_64/fpu/multiarch/s_floorf.c b/sysdeps/x86_64/fpu/multiarch/s_floorf.c
8500index a14e18b03c..a277802b6d 100644
8501--- a/sysdeps/x86_64/fpu/multiarch/s_floorf.c
8502+++ b/sysdeps/x86_64/fpu/multiarch/s_floorf.c
8503@@ -16,17 +16,20 @@
8504 License along with the GNU C Library; if not, see
8505 <https://www.gnu.org/licenses/>. */
8506
8507-#define NO_MATH_REDIRECT
8508-#include <libm-alias-float.h>
8509+#include <sysdeps/x86/isa-level.h>
8510+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
8511+# define NO_MATH_REDIRECT
8512+# include <libm-alias-float.h>
8513
8514-#define floorf __redirect_floorf
8515-#define __floorf __redirect___floorf
8516-#include <math.h>
8517-#undef floorf
8518-#undef __floorf
8519+# define floorf __redirect_floorf
8520+# define __floorf __redirect___floorf
8521+# include <math.h>
8522+# undef floorf
8523+# undef __floorf
8524
8525-#define SYMBOL_NAME floorf
8526-#include "ifunc-sse4_1.h"
8527+# define SYMBOL_NAME floorf
8528+# include "ifunc-sse4_1.h"
8529
8530 libc_ifunc_redirected (__redirect_floorf, __floorf, IFUNC_SELECTOR ());
8531 libm_alias_float (__floor, floor)
8532+#endif
8533diff --git a/sysdeps/x86_64/fpu/multiarch/s_log1p.c b/sysdeps/x86_64/fpu/multiarch/s_log1p.c
8534index a8e1a3f21b..3fa1185d81 100644
8535--- a/sysdeps/x86_64/fpu/multiarch/s_log1p.c
8536+++ b/sysdeps/x86_64/fpu/multiarch/s_log1p.c
8537@@ -16,14 +16,17 @@
8538 License along with the GNU C Library; if not, see
8539 <https://www.gnu.org/licenses/>. */
8540
8541-#include <libm-alias-double.h>
8542+#include <sysdeps/x86/isa-level.h>
8543+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
8544+# include <libm-alias-double.h>
8545
8546 extern double __redirect_log1p (double);
8547
8548-#define SYMBOL_NAME log1p
8549-#include "ifunc-fma.h"
8550+# define SYMBOL_NAME log1p
8551+# include "ifunc-fma.h"
8552
8553 libc_ifunc_redirected (__redirect_log1p, __log1p, IFUNC_SELECTOR ());
8554
8555-#define __log1p __log1p_sse2
8556+# define __log1p __log1p_sse2
8557+#endif
8558 #include <sysdeps/ieee754/dbl-64/s_log1p.c>
8559diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyint-avx.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyint-avx.S
8560new file mode 100644
8561index 0000000000..5bfdf73c28
8562--- /dev/null
8563+++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyint-avx.S
8564@@ -0,0 +1,28 @@
8565+/* AVX implementation of nearbyint function.
8566+ Copyright (C) 2024 Free Software Foundation, Inc.
8567+ This file is part of the GNU C Library.
8568+
8569+ The GNU C Library is free software; you can redistribute it and/or
8570+ modify it under the terms of the GNU Lesser General Public
8571+ License as published by the Free Software Foundation; either
8572+ version 2.1 of the License, or (at your option) any later version.
8573+
8574+ The GNU C Library is distributed in the hope that it will be useful,
8575+ but WITHOUT ANY WARRANTY; without even the implied warranty of
8576+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8577+ Lesser General Public License for more details.
8578+
8579+ You should have received a copy of the GNU Lesser General Public
8580+ License along with the GNU C Library; if not, see
8581+ <https://www.gnu.org/licenses/>. */
8582+
8583+#include <sysdep.h>
8584+#include <libm-alias-double.h>
8585+
8586+ .text
8587+ENTRY(__nearbyint)
8588+ vroundsd $0xc, %xmm0, %xmm0, %xmm0
8589+ ret
8590+END(__nearbyint)
8591+
8592+libm_alias_double (__nearbyint, nearbyint)
8593diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyint-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyint-sse4_1.S
8594index 674f7eb40a..9d84410a1f 100644
8595--- a/sysdeps/x86_64/fpu/multiarch/s_nearbyint-sse4_1.S
8596+++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyint-sse4_1.S
8597@@ -17,8 +17,20 @@
8598
8599 #include <sysdep.h>
8600
8601+#include <sysdeps/x86/isa-level.h>
8602+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8603+# include <libm-alias-double.h>
8604+# define __nearbyint_sse41 __nearbyint
8605+ .text
8606+#else
8607 .section .text.sse4.1,"ax",@progbits
8608+#endif
8609+
8610 ENTRY(__nearbyint_sse41)
8611 roundsd $0xc, %xmm0, %xmm0
8612 ret
8613 END(__nearbyint_sse41)
8614+
8615+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8616+libm_alias_double (__nearbyint, nearbyint)
8617+#endif
8618diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyint.c b/sysdeps/x86_64/fpu/multiarch/s_nearbyint.c
8619index 693e42dd4e..057a7ca60f 100644
8620--- a/sysdeps/x86_64/fpu/multiarch/s_nearbyint.c
8621+++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyint.c
8622@@ -16,17 +16,20 @@
8623 License along with the GNU C Library; if not, see
8624 <https://www.gnu.org/licenses/>. */
8625
8626-#include <libm-alias-double.h>
8627+#include <sysdeps/x86/isa-level.h>
8628+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
8629+# include <libm-alias-double.h>
8630
8631-#define nearbyint __redirect_nearbyint
8632-#define __nearbyint __redirect___nearbyint
8633-#include <math.h>
8634-#undef nearbyint
8635-#undef __nearbyint
8636+# define nearbyint __redirect_nearbyint
8637+# define __nearbyint __redirect___nearbyint
8638+# include <math.h>
8639+# undef nearbyint
8640+# undef __nearbyint
8641
8642-#define SYMBOL_NAME nearbyint
8643-#include "ifunc-sse4_1.h"
8644+# define SYMBOL_NAME nearbyint
8645+# include "ifunc-sse4_1.h"
8646
8647 libc_ifunc_redirected (__redirect_nearbyint, __nearbyint,
8648 IFUNC_SELECTOR ());
8649 libm_alias_double (__nearbyint, nearbyint)
8650+#endif
8651diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-avx.S
8652new file mode 100644
8653index 0000000000..1dbaed0324
8654--- /dev/null
8655+++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-avx.S
8656@@ -0,0 +1,28 @@
8657+/* AVX implmentation of nearbyintf function.
8658+ Copyright (C) 2024 Free Software Foundation, Inc.
8659+ This file is part of the GNU C Library.
8660+
8661+ The GNU C Library is free software; you can redistribute it and/or
8662+ modify it under the terms of the GNU Lesser General Public
8663+ License as published by the Free Software Foundation; either
8664+ version 2.1 of the License, or (at your option) any later version.
8665+
8666+ The GNU C Library is distributed in the hope that it will be useful,
8667+ but WITHOUT ANY WARRANTY; without even the implied warranty of
8668+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8669+ Lesser General Public License for more details.
8670+
8671+ You should have received a copy of the GNU Lesser General Public
8672+ License along with the GNU C Library; if not, see
8673+ <https://www.gnu.org/licenses/>. */
8674+
8675+#include <sysdep.h>
8676+#include <libm-alias-float.h>
8677+
8678+ .text
8679+ENTRY(__nearbyintf)
8680+ vroundss $0xc, %xmm0, %xmm0, %xmm0
8681+ ret
8682+END(__nearbyintf)
8683+
8684+libm_alias_float (__nearbyint, nearbyint)
8685diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-sse4_1.S
8686index 5892bd7563..3cf35f92d6 100644
8687--- a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-sse4_1.S
8688+++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf-sse4_1.S
8689@@ -17,8 +17,20 @@
8690
8691 #include <sysdep.h>
8692
8693+#include <sysdeps/x86/isa-level.h>
8694+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8695+# include <libm-alias-float.h>
8696+# define __nearbyintf_sse41 __nearbyintf
8697+ .text
8698+#else
8699 .section .text.sse4.1,"ax",@progbits
8700+#endif
8701+
8702 ENTRY(__nearbyintf_sse41)
8703 roundss $0xc, %xmm0, %xmm0
8704 ret
8705 END(__nearbyintf_sse41)
8706+
8707+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8708+libm_alias_float (__nearbyint, nearbyint)
8709+#endif
8710diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.c b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.c
8711index a0ac009f4b..41f374ba72 100644
8712--- a/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.c
8713+++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.c
8714@@ -16,17 +16,20 @@
8715 License along with the GNU C Library; if not, see
8716 <https://www.gnu.org/licenses/>. */
8717
8718-#include <libm-alias-float.h>
8719+#include <sysdeps/x86/isa-level.h>
8720+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
8721+# include <libm-alias-float.h>
8722
8723-#define nearbyintf __redirect_nearbyintf
8724-#define __nearbyintf __redirect___nearbyintf
8725-#include <math.h>
8726-#undef nearbyintf
8727-#undef __nearbyintf
8728+# define nearbyintf __redirect_nearbyintf
8729+# define __nearbyintf __redirect___nearbyintf
8730+# include <math.h>
8731+# undef nearbyintf
8732+# undef __nearbyintf
8733
8734-#define SYMBOL_NAME nearbyintf
8735-#include "ifunc-sse4_1.h"
8736+# define SYMBOL_NAME nearbyintf
8737+# include "ifunc-sse4_1.h"
8738
8739 libc_ifunc_redirected (__redirect_nearbyintf, __nearbyintf,
8740 IFUNC_SELECTOR ());
8741 libm_alias_float (__nearbyint, nearbyint)
8742+#endif
8743diff --git a/sysdeps/x86_64/fpu/multiarch/s_rint-avx.S b/sysdeps/x86_64/fpu/multiarch/s_rint-avx.S
8744new file mode 100644
8745index 0000000000..2b403b331f
8746--- /dev/null
8747+++ b/sysdeps/x86_64/fpu/multiarch/s_rint-avx.S
8748@@ -0,0 +1,28 @@
8749+/* AVX implementation of rint function.
8750+ Copyright (C) 2024 Free Software Foundation, Inc.
8751+ This file is part of the GNU C Library.
8752+
8753+ The GNU C Library is free software; you can redistribute it and/or
8754+ modify it under the terms of the GNU Lesser General Public
8755+ License as published by the Free Software Foundation; either
8756+ version 2.1 of the License, or (at your option) any later version.
8757+
8758+ The GNU C Library is distributed in the hope that it will be useful,
8759+ but WITHOUT ANY WARRANTY; without even the implied warranty of
8760+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8761+ Lesser General Public License for more details.
8762+
8763+ You should have received a copy of the GNU Lesser General Public
8764+ License along with the GNU C Library; if not, see
8765+ <https://www.gnu.org/licenses/>. */
8766+
8767+#include <sysdep.h>
8768+#include <libm-alias-double.h>
8769+
8770+ .text
8771+ENTRY(__rint)
8772+ vroundsd $4, %xmm0, %xmm0, %xmm0
8773+ ret
8774+END(__rint)
8775+
8776+libm_alias_double (__rint, rint)
8777diff --git a/sysdeps/x86_64/fpu/multiarch/s_rint-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_rint-sse4_1.S
8778index 405372991b..8cd9cf759f 100644
8779--- a/sysdeps/x86_64/fpu/multiarch/s_rint-sse4_1.S
8780+++ b/sysdeps/x86_64/fpu/multiarch/s_rint-sse4_1.S
8781@@ -17,8 +17,20 @@
8782
8783 #include <sysdep.h>
8784
8785+#include <sysdeps/x86/isa-level.h>
8786+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8787+# include <libm-alias-double.h>
8788+# define __rint_sse41 __rint
8789+ .text
8790+#else
8791 .section .text.sse4.1,"ax",@progbits
8792+#endif
8793+
8794 ENTRY(__rint_sse41)
8795 roundsd $4, %xmm0, %xmm0
8796 ret
8797 END(__rint_sse41)
8798+
8799+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8800+libm_alias_double (__rint, rint)
8801+#endif
8802diff --git a/sysdeps/x86_64/fpu/multiarch/s_rint.c b/sysdeps/x86_64/fpu/multiarch/s_rint.c
8803index 754c87e004..18623b7d99 100644
8804--- a/sysdeps/x86_64/fpu/multiarch/s_rint.c
8805+++ b/sysdeps/x86_64/fpu/multiarch/s_rint.c
8806@@ -16,17 +16,20 @@
8807 License along with the GNU C Library; if not, see
8808 <https://www.gnu.org/licenses/>. */
8809
8810-#define NO_MATH_REDIRECT
8811-#include <libm-alias-double.h>
8812+#include <sysdeps/x86/isa-level.h>
8813+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
8814+# define NO_MATH_REDIRECT
8815+# include <libm-alias-double.h>
8816
8817-#define rint __redirect_rint
8818-#define __rint __redirect___rint
8819-#include <math.h>
8820-#undef rint
8821-#undef __rint
8822+# define rint __redirect_rint
8823+# define __rint __redirect___rint
8824+# include <math.h>
8825+# undef rint
8826+# undef __rint
8827
8828-#define SYMBOL_NAME rint
8829-#include "ifunc-sse4_1.h"
8830+# define SYMBOL_NAME rint
8831+# include "ifunc-sse4_1.h"
8832
8833 libc_ifunc_redirected (__redirect_rint, __rint, IFUNC_SELECTOR ());
8834 libm_alias_double (__rint, rint)
8835+#endif
8836diff --git a/sysdeps/x86_64/fpu/multiarch/s_rintf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_rintf-avx.S
8837new file mode 100644
8838index 0000000000..171c2867f4
8839--- /dev/null
8840+++ b/sysdeps/x86_64/fpu/multiarch/s_rintf-avx.S
8841@@ -0,0 +1,28 @@
8842+/* AVX implementation of rintf function.
8843+ Copyright (C) 2024 Free Software Foundation, Inc.
8844+ This file is part of the GNU C Library.
8845+
8846+ The GNU C Library is free software; you can redistribute it and/or
8847+ modify it under the terms of the GNU Lesser General Public
8848+ License as published by the Free Software Foundation; either
8849+ version 2.1 of the License, or (at your option) any later version.
8850+
8851+ The GNU C Library is distributed in the hope that it will be useful,
8852+ but WITHOUT ANY WARRANTY; without even the implied warranty of
8853+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8854+ Lesser General Public License for more details.
8855+
8856+ You should have received a copy of the GNU Lesser General Public
8857+ License along with the GNU C Library; if not, see
8858+ <https://www.gnu.org/licenses/>. */
8859+
8860+#include <sysdep.h>
8861+#include <libm-alias-float.h>
8862+
8863+ .text
8864+ENTRY(__rintf)
8865+ vroundss $4, %xmm0, %xmm0, %xmm0
8866+ ret
8867+END(__rintf)
8868+
8869+libm_alias_float (__rint, rint)
8870diff --git a/sysdeps/x86_64/fpu/multiarch/s_rintf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_rintf-sse4_1.S
8871index 8ac67ce767..fc1e70f0c9 100644
8872--- a/sysdeps/x86_64/fpu/multiarch/s_rintf-sse4_1.S
8873+++ b/sysdeps/x86_64/fpu/multiarch/s_rintf-sse4_1.S
8874@@ -17,8 +17,20 @@
8875
8876 #include <sysdep.h>
8877
8878+#include <sysdeps/x86/isa-level.h>
8879+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8880+# include <libm-alias-float.h>
8881+# define __rintf_sse41 __rintf
8882+ .text
8883+#else
8884 .section .text.sse4.1,"ax",@progbits
8885+#endif
8886+
8887 ENTRY(__rintf_sse41)
8888 roundss $4, %xmm0, %xmm0
8889 ret
8890 END(__rintf_sse41)
8891+
8892+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8893+libm_alias_float (__rint, rint)
8894+#endif
8895diff --git a/sysdeps/x86_64/fpu/multiarch/s_rintf.c b/sysdeps/x86_64/fpu/multiarch/s_rintf.c
8896index e9d6b7a5f2..e275368dec 100644
8897--- a/sysdeps/x86_64/fpu/multiarch/s_rintf.c
8898+++ b/sysdeps/x86_64/fpu/multiarch/s_rintf.c
8899@@ -16,17 +16,20 @@
8900 License along with the GNU C Library; if not, see
8901 <https://www.gnu.org/licenses/>. */
8902
8903-#define NO_MATH_REDIRECT
8904-#include <libm-alias-float.h>
8905+#include <sysdeps/x86/isa-level.h>
8906+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
8907+# define NO_MATH_REDIRECT
8908+# include <libm-alias-float.h>
8909
8910-#define rintf __redirect_rintf
8911-#define __rintf __redirect___rintf
8912-#include <math.h>
8913-#undef rintf
8914-#undef __rintf
8915+# define rintf __redirect_rintf
8916+# define __rintf __redirect___rintf
8917+# include <math.h>
8918+# undef rintf
8919+# undef __rintf
8920
8921-#define SYMBOL_NAME rintf
8922-#include "ifunc-sse4_1.h"
8923+# define SYMBOL_NAME rintf
8924+# include "ifunc-sse4_1.h"
8925
8926 libc_ifunc_redirected (__redirect_rintf, __rintf, IFUNC_SELECTOR ());
8927 libm_alias_float (__rint, rint)
8928+#endif
8929diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven-avx.S b/sysdeps/x86_64/fpu/multiarch/s_roundeven-avx.S
8930new file mode 100644
8931index 0000000000..576790355c
8932--- /dev/null
8933+++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven-avx.S
8934@@ -0,0 +1,28 @@
8935+/* AVX implementation of roundeven function.
8936+ Copyright (C) 2024 Free Software Foundation, Inc.
8937+ This file is part of the GNU C Library.
8938+
8939+ The GNU C Library is free software; you can redistribute it and/or
8940+ modify it under the terms of the GNU Lesser General Public
8941+ License as published by the Free Software Foundation; either
8942+ version 2.1 of the License, or (at your option) any later version.
8943+
8944+ The GNU C Library is distributed in the hope that it will be useful,
8945+ but WITHOUT ANY WARRANTY; without even the implied warranty of
8946+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8947+ Lesser General Public License for more details.
8948+
8949+ You should have received a copy of the GNU Lesser General Public
8950+ License along with the GNU C Library; if not, see
8951+ <https://www.gnu.org/licenses/>. */
8952+
8953+#include <sysdep.h>
8954+#include <libm-alias-double.h>
8955+
8956+ .text
8957+ENTRY(__roundeven)
8958+ vroundsd $8, %xmm0, %xmm0, %xmm0
8959+ ret
8960+END(__roundeven)
8961+
8962+libm_alias_double (__roundeven, roundeven)
8963diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S
8964index 5ef102336b..f00be56c59 100644
8965--- a/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S
8966+++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S
8967@@ -17,8 +17,20 @@
8968
8969 #include <sysdep.h>
8970
8971+#include <sysdeps/x86/isa-level.h>
8972+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8973+# include <libm-alias-double.h>
8974+# define __roundeven_sse41 __roundeven
8975+ .text
8976+#else
8977 .section .text.sse4.1,"ax",@progbits
8978+#endif
8979+
8980 ENTRY(__roundeven_sse41)
8981 roundsd $8, %xmm0, %xmm0
8982 ret
8983 END(__roundeven_sse41)
8984+
8985+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
8986+libm_alias_double (__roundeven, roundeven)
8987+#endif
8988diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven.c b/sysdeps/x86_64/fpu/multiarch/s_roundeven.c
8989index 8737b32e26..139aad088f 100644
8990--- a/sysdeps/x86_64/fpu/multiarch/s_roundeven.c
8991+++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven.c
8992@@ -16,16 +16,19 @@
8993 License along with the GNU C Library; if not, see
8994 <https://www.gnu.org/licenses/>. */
8995
8996-#include <libm-alias-double.h>
8997+#include <sysdeps/x86/isa-level.h>
8998+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
8999+# include <libm-alias-double.h>
9000
9001-#define roundeven __redirect_roundeven
9002-#define __roundeven __redirect___roundeven
9003-#include <math.h>
9004-#undef roundeven
9005-#undef __roundeven
9006+# define roundeven __redirect_roundeven
9007+# define __roundeven __redirect___roundeven
9008+# include <math.h>
9009+# undef roundeven
9010+# undef __roundeven
9011
9012-#define SYMBOL_NAME roundeven
9013-#include "ifunc-sse4_1.h"
9014+# define SYMBOL_NAME roundeven
9015+# include "ifunc-sse4_1.h"
9016
9017 libc_ifunc_redirected (__redirect_roundeven, __roundeven, IFUNC_SELECTOR ());
9018 libm_alias_double (__roundeven, roundeven)
9019+#endif
9020diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-avx.S
9021new file mode 100644
9022index 0000000000..42c359f4cd
9023--- /dev/null
9024+++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-avx.S
9025@@ -0,0 +1,28 @@
9026+/* AVX implementation of roundevenf function.
9027+ Copyright (C) 2024 Free Software Foundation, Inc.
9028+ This file is part of the GNU C Library.
9029+
9030+ The GNU C Library is free software; you can redistribute it and/or
9031+ modify it under the terms of the GNU Lesser General Public
9032+ License as published by the Free Software Foundation; either
9033+ version 2.1 of the License, or (at your option) any later version.
9034+
9035+ The GNU C Library is distributed in the hope that it will be useful,
9036+ but WITHOUT ANY WARRANTY; without even the implied warranty of
9037+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9038+ Lesser General Public License for more details.
9039+
9040+ You should have received a copy of the GNU Lesser General Public
9041+ License along with the GNU C Library; if not, see
9042+ <https://www.gnu.org/licenses/>. */
9043+
9044+#include <sysdep.h>
9045+#include <libm-alias-float.h>
9046+
9047+ .text
9048+ENTRY(__roundevenf)
9049+ vroundss $8, %xmm0, %xmm0, %xmm0
9050+ ret
9051+END(__roundevenf)
9052+
9053+libm_alias_float (__roundeven, roundeven)
9054diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S
9055index 792c90ba07..6b148e4353 100644
9056--- a/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S
9057+++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S
9058@@ -17,8 +17,20 @@
9059
9060 #include <sysdep.h>
9061
9062+#include <sysdeps/x86/isa-level.h>
9063+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
9064+# include <libm-alias-float.h>
9065+# define __roundevenf_sse41 __roundevenf
9066+ .text
9067+#else
9068 .section .text.sse4.1,"ax",@progbits
9069+#endif
9070+
9071 ENTRY(__roundevenf_sse41)
9072 roundss $8, %xmm0, %xmm0
9073 ret
9074 END(__roundevenf_sse41)
9075+
9076+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
9077+libm_alias_float (__roundeven, roundeven)
9078+#endif
9079diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c b/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c
9080index e96016a4d5..2fb090075d 100644
9081--- a/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c
9082+++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c
9083@@ -16,16 +16,19 @@
9084 License along with the GNU C Library; if not, see
9085 <https://www.gnu.org/licenses/>. */
9086
9087-#include <libm-alias-float.h>
9088+#include <sysdeps/x86/isa-level.h>
9089+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
9090+# include <libm-alias-float.h>
9091
9092-#define roundevenf __redirect_roundevenf
9093-#define __roundevenf __redirect___roundevenf
9094-#include <math.h>
9095-#undef roundevenf
9096-#undef __roundevenf
9097+# define roundevenf __redirect_roundevenf
9098+# define __roundevenf __redirect___roundevenf
9099+# include <math.h>
9100+# undef roundevenf
9101+# undef __roundevenf
9102
9103-#define SYMBOL_NAME roundevenf
9104-#include "ifunc-sse4_1.h"
9105+# define SYMBOL_NAME roundevenf
9106+# include "ifunc-sse4_1.h"
9107
9108 libc_ifunc_redirected (__redirect_roundevenf, __roundevenf, IFUNC_SELECTOR ());
9109 libm_alias_float (__roundeven, roundeven)
9110+#endif
9111diff --git a/sysdeps/x86_64/fpu/multiarch/s_sin.c b/sysdeps/x86_64/fpu/multiarch/s_sin.c
9112index 355cc0092e..21e77943a3 100644
9113--- a/sysdeps/x86_64/fpu/multiarch/s_sin.c
9114+++ b/sysdeps/x86_64/fpu/multiarch/s_sin.c
9115@@ -16,24 +16,27 @@
9116 License along with the GNU C Library; if not, see
9117 <https://www.gnu.org/licenses/>. */
9118
9119-#include <libm-alias-double.h>
9120+#include <sysdeps/x86/isa-level.h>
9121+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
9122+# include <libm-alias-double.h>
9123
9124 extern double __redirect_sin (double);
9125 extern double __redirect_cos (double);
9126
9127-#define SYMBOL_NAME sin
9128-#include "ifunc-avx-fma4.h"
9129+# define SYMBOL_NAME sin
9130+# include "ifunc-avx-fma4.h"
9131
9132 libc_ifunc_redirected (__redirect_sin, __sin, IFUNC_SELECTOR ());
9133 libm_alias_double (__sin, sin)
9134
9135-#undef SYMBOL_NAME
9136-#define SYMBOL_NAME cos
9137-#include "ifunc-avx-fma4.h"
9138+# undef SYMBOL_NAME
9139+# define SYMBOL_NAME cos
9140+# include "ifunc-avx-fma4.h"
9141
9142 libc_ifunc_redirected (__redirect_cos, __cos, IFUNC_SELECTOR ());
9143 libm_alias_double (__cos, cos)
9144
9145-#define __cos __cos_sse2
9146-#define __sin __sin_sse2
9147+# define __cos __cos_sse2
9148+# define __sin __sin_sse2
9149+#endif
9150 #include <sysdeps/ieee754/dbl-64/s_sin.c>
9151diff --git a/sysdeps/x86_64/fpu/multiarch/s_sincos.c b/sysdeps/x86_64/fpu/multiarch/s_sincos.c
9152index 70107e999c..b35757f8de 100644
9153--- a/sysdeps/x86_64/fpu/multiarch/s_sincos.c
9154+++ b/sysdeps/x86_64/fpu/multiarch/s_sincos.c
9155@@ -16,15 +16,18 @@
9156 License along with the GNU C Library; if not, see
9157 <https://www.gnu.org/licenses/>. */
9158
9159-#include <libm-alias-double.h>
9160+#include <sysdeps/x86/isa-level.h>
9161+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
9162+# include <libm-alias-double.h>
9163
9164 extern void __redirect_sincos (double, double *, double *);
9165
9166-#define SYMBOL_NAME sincos
9167-#include "ifunc-fma4.h"
9168+# define SYMBOL_NAME sincos
9169+# include "ifunc-fma4.h"
9170
9171 libc_ifunc_redirected (__redirect_sincos, __sincos, IFUNC_SELECTOR ());
9172 libm_alias_double (__sincos, sincos)
9173
9174-#define __sincos __sincos_sse2
9175+# define __sincos __sincos_sse2
9176+#endif
9177 #include <sysdeps/ieee754/dbl-64/s_sincos.c>
9178diff --git a/sysdeps/x86_64/fpu/multiarch/s_sincosf.c b/sysdeps/x86_64/fpu/multiarch/s_sincosf.c
9179index 80bc028451..0ea9b40e84 100644
9180--- a/sysdeps/x86_64/fpu/multiarch/s_sincosf.c
9181+++ b/sysdeps/x86_64/fpu/multiarch/s_sincosf.c
9182@@ -16,13 +16,18 @@
9183 License along with the GNU C Library; if not, see
9184 <https://www.gnu.org/licenses/>. */
9185
9186-#include <libm-alias-float.h>
9187+#include <sysdeps/x86/isa-level.h>
9188+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
9189+# include <libm-alias-float.h>
9190
9191 extern void __redirect_sincosf (float, float *, float *);
9192
9193-#define SYMBOL_NAME sincosf
9194-#include "ifunc-fma.h"
9195+# define SYMBOL_NAME sincosf
9196+# include "ifunc-fma.h"
9197
9198 libc_ifunc_redirected (__redirect_sincosf, __sincosf, IFUNC_SELECTOR ());
9199
9200 libm_alias_float (__sincos, sincos)
9201+#else
9202+# include <sysdeps/ieee754/flt-32/s_sincosf.c>
9203+#endif
9204diff --git a/sysdeps/x86_64/fpu/multiarch/s_sinf.c b/sysdeps/x86_64/fpu/multiarch/s_sinf.c
9205index a32b9e9550..c61624e3ee 100644
9206--- a/sysdeps/x86_64/fpu/multiarch/s_sinf.c
9207+++ b/sysdeps/x86_64/fpu/multiarch/s_sinf.c
9208@@ -16,13 +16,18 @@
9209 License along with the GNU C Library; if not, see
9210 <https://www.gnu.org/licenses/>. */
9211
9212-#include <libm-alias-float.h>
9213+#include <sysdeps/x86/isa-level.h>
9214+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
9215+# include <libm-alias-float.h>
9216
9217 extern float __redirect_sinf (float);
9218
9219-#define SYMBOL_NAME sinf
9220-#include "ifunc-fma.h"
9221+# define SYMBOL_NAME sinf
9222+# include "ifunc-fma.h"
9223
9224 libc_ifunc_redirected (__redirect_sinf, __sinf, IFUNC_SELECTOR ());
9225
9226 libm_alias_float (__sin, sin)
9227+#else
9228+# include <sysdeps/ieee754/flt-32/s_sinf.c>
9229+#endif
9230diff --git a/sysdeps/x86_64/fpu/multiarch/s_tan.c b/sysdeps/x86_64/fpu/multiarch/s_tan.c
9231index f9a2474a13..125d992ba1 100644
9232--- a/sysdeps/x86_64/fpu/multiarch/s_tan.c
9233+++ b/sysdeps/x86_64/fpu/multiarch/s_tan.c
9234@@ -16,15 +16,18 @@
9235 License along with the GNU C Library; if not, see
9236 <https://www.gnu.org/licenses/>. */
9237
9238-#include <libm-alias-double.h>
9239+#include <sysdeps/x86/isa-level.h>
9240+#if MINIMUM_X86_ISA_LEVEL < AVX2_X86_ISA_LEVEL
9241+# include <libm-alias-double.h>
9242
9243 extern double __redirect_tan (double);
9244
9245-#define SYMBOL_NAME tan
9246-#include "ifunc-avx-fma4.h"
9247+# define SYMBOL_NAME tan
9248+# include "ifunc-avx-fma4.h"
9249
9250 libc_ifunc_redirected (__redirect_tan, __tan, IFUNC_SELECTOR ());
9251 libm_alias_double (__tan, tan)
9252
9253-#define __tan __tan_sse2
9254+# define __tan __tan_sse2
9255+#endif
9256 #include <sysdeps/ieee754/dbl-64/s_tan.c>
9257diff --git a/sysdeps/x86_64/fpu/multiarch/s_trunc-avx.S b/sysdeps/x86_64/fpu/multiarch/s_trunc-avx.S
9258new file mode 100644
9259index 0000000000..b3e87e9606
9260--- /dev/null
9261+++ b/sysdeps/x86_64/fpu/multiarch/s_trunc-avx.S
9262@@ -0,0 +1,28 @@
9263+/* AVX implementation of trunc function.
9264+ Copyright (C) 2024 Free Software Foundation, Inc.
9265+ This file is part of the GNU C Library.
9266+
9267+ The GNU C Library is free software; you can redistribute it and/or
9268+ modify it under the terms of the GNU Lesser General Public
9269+ License as published by the Free Software Foundation; either
9270+ version 2.1 of the License, or (at your option) any later version.
9271+
9272+ The GNU C Library is distributed in the hope that it will be useful,
9273+ but WITHOUT ANY WARRANTY; without even the implied warranty of
9274+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9275+ Lesser General Public License for more details.
9276+
9277+ You should have received a copy of the GNU Lesser General Public
9278+ License along with the GNU C Library; if not, see
9279+ <https://www.gnu.org/licenses/>. */
9280+
9281+#include <sysdep.h>
9282+#include <libm-alias-double.h>
9283+
9284+ .text
9285+ENTRY(__trunc)
9286+ vroundsd $11, %xmm0, %xmm0, %xmm0
9287+ ret
9288+END(__trunc)
9289+
9290+libm_alias_double (__trunc, trunc)
9291diff --git a/sysdeps/x86_64/fpu/multiarch/s_trunc-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_trunc-sse4_1.S
9292index b496a6ef49..2b79174eed 100644
9293--- a/sysdeps/x86_64/fpu/multiarch/s_trunc-sse4_1.S
9294+++ b/sysdeps/x86_64/fpu/multiarch/s_trunc-sse4_1.S
9295@@ -18,8 +18,20 @@
9296
9297 #include <sysdep.h>
9298
9299+#include <sysdeps/x86/isa-level.h>
9300+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
9301+# include <libm-alias-double.h>
9302+# define __trunc_sse41 __trunc
9303+ .text
9304+#else
9305 .section .text.sse4.1,"ax",@progbits
9306+#endif
9307+
9308 ENTRY(__trunc_sse41)
9309 roundsd $11, %xmm0, %xmm0
9310 ret
9311 END(__trunc_sse41)
9312+
9313+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
9314+libm_alias_double (__trunc, trunc)
9315+#endif
9316diff --git a/sysdeps/x86_64/fpu/multiarch/s_trunc.c b/sysdeps/x86_64/fpu/multiarch/s_trunc.c
9317index 9bc9df8744..ea89c4f85d 100644
9318--- a/sysdeps/x86_64/fpu/multiarch/s_trunc.c
9319+++ b/sysdeps/x86_64/fpu/multiarch/s_trunc.c
9320@@ -16,17 +16,20 @@
9321 License along with the GNU C Library; if not, see
9322 <https://www.gnu.org/licenses/>. */
9323
9324-#define NO_MATH_REDIRECT
9325-#include <libm-alias-double.h>
9326+#include <sysdeps/x86/isa-level.h>
9327+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
9328+# define NO_MATH_REDIRECT
9329+# include <libm-alias-double.h>
9330
9331-#define trunc __redirect_trunc
9332-#define __trunc __redirect___trunc
9333-#include <math.h>
9334-#undef trunc
9335-#undef __trunc
9336+# define trunc __redirect_trunc
9337+# define __trunc __redirect___trunc
9338+# include <math.h>
9339+# undef trunc
9340+# undef __trunc
9341
9342-#define SYMBOL_NAME trunc
9343-#include "ifunc-sse4_1.h"
9344+# define SYMBOL_NAME trunc
9345+# include "ifunc-sse4_1.h"
9346
9347 libc_ifunc_redirected (__redirect_trunc, __trunc, IFUNC_SELECTOR ());
9348 libm_alias_double (__trunc, trunc)
9349+#endif
9350diff --git a/sysdeps/x86_64/fpu/multiarch/s_truncf-avx.S b/sysdeps/x86_64/fpu/multiarch/s_truncf-avx.S
9351new file mode 100644
9352index 0000000000..f31ac7d7f7
9353--- /dev/null
9354+++ b/sysdeps/x86_64/fpu/multiarch/s_truncf-avx.S
9355@@ -0,0 +1,28 @@
9356+/* AVX implementation of truncf function.
9357+ Copyright (C) 2024 Free Software Foundation, Inc.
9358+ This file is part of the GNU C Library.
9359+
9360+ The GNU C Library is free software; you can redistribute it and/or
9361+ modify it under the terms of the GNU Lesser General Public
9362+ License as published by the Free Software Foundation; either
9363+ version 2.1 of the License, or (at your option) any later version.
9364+
9365+ The GNU C Library is distributed in the hope that it will be useful,
9366+ but WITHOUT ANY WARRANTY; without even the implied warranty of
9367+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9368+ Lesser General Public License for more details.
9369+
9370+ You should have received a copy of the GNU Lesser General Public
9371+ License along with the GNU C Library; if not, see
9372+ <https://www.gnu.org/licenses/>. */
9373+
9374+#include <sysdep.h>
9375+#include <libm-alias-float.h>
9376+
9377+ .text
9378+ENTRY(__truncf)
9379+ vroundss $11, %xmm0, %xmm0, %xmm0
9380+ ret
9381+END(__truncf)
9382+
9383+libm_alias_float (__trunc, trunc)
9384diff --git a/sysdeps/x86_64/fpu/multiarch/s_truncf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_truncf-sse4_1.S
9385index 22e9a83307..60498b2cb2 100644
9386--- a/sysdeps/x86_64/fpu/multiarch/s_truncf-sse4_1.S
9387+++ b/sysdeps/x86_64/fpu/multiarch/s_truncf-sse4_1.S
9388@@ -18,8 +18,20 @@
9389
9390 #include <sysdep.h>
9391
9392+#include <sysdeps/x86/isa-level.h>
9393+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
9394+# include <libm-alias-float.h>
9395+# define __truncf_sse41 __truncf
9396+ .text
9397+#else
9398 .section .text.sse4.1,"ax",@progbits
9399+#endif
9400+
9401 ENTRY(__truncf_sse41)
9402 roundss $11, %xmm0, %xmm0
9403 ret
9404 END(__truncf_sse41)
9405+
9406+#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
9407+libm_alias_float (__trunc, trunc)
9408+#endif
9409diff --git a/sysdeps/x86_64/fpu/multiarch/s_truncf.c b/sysdeps/x86_64/fpu/multiarch/s_truncf.c
9410index dae01d166a..92435ce39d 100644
9411--- a/sysdeps/x86_64/fpu/multiarch/s_truncf.c
9412+++ b/sysdeps/x86_64/fpu/multiarch/s_truncf.c
9413@@ -16,17 +16,20 @@
9414 License along with the GNU C Library; if not, see
9415 <https://www.gnu.org/licenses/>. */
9416
9417-#define NO_MATH_REDIRECT
9418-#include <libm-alias-float.h>
9419+#include <sysdeps/x86/isa-level.h>
9420+#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
9421+# define NO_MATH_REDIRECT
9422+# include <libm-alias-float.h>
9423
9424-#define truncf __redirect_truncf
9425-#define __truncf __redirect___truncf
9426-#include <math.h>
9427-#undef truncf
9428-#undef __truncf
9429+# define truncf __redirect_truncf
9430+# define __truncf __redirect___truncf
9431+# include <math.h>
9432+# undef truncf
9433+# undef __truncf
9434
9435-#define SYMBOL_NAME truncf
9436-#include "ifunc-sse4_1.h"
9437+# define SYMBOL_NAME truncf
9438+# include "ifunc-sse4_1.h"
9439
9440 libc_ifunc_redirected (__redirect_truncf, __truncf, IFUNC_SELECTOR ());
9441 libm_alias_float (__trunc, trunc)
9442+#endif
9443diff --git a/sysdeps/x86_64/fpu/multiarch/w_exp.c b/sysdeps/x86_64/fpu/multiarch/w_exp.c
9444index 27eee98a0a..3584187e0e 100644
9445--- a/sysdeps/x86_64/fpu/multiarch/w_exp.c
9446+++ b/sysdeps/x86_64/fpu/multiarch/w_exp.c
9447@@ -1 +1,6 @@
9448-#include <sysdeps/../math/w_exp.c>
9449+#include <sysdeps/x86/isa-level.h>
9450+#if MINIMUM_X86_ISA_LEVEL >= AVX2_X86_ISA_LEVEL
9451+# include <sysdeps/ieee754/dbl-64/w_exp.c>
9452+#else
9453+# include <sysdeps/../math/w_exp.c>
9454+#endif
9455diff --git a/sysdeps/x86_64/fpu/multiarch/w_log.c b/sysdeps/x86_64/fpu/multiarch/w_log.c
9456index 9b2b018711..414ca3ca3d 100644
9457--- a/sysdeps/x86_64/fpu/multiarch/w_log.c
9458+++ b/sysdeps/x86_64/fpu/multiarch/w_log.c
9459@@ -1 +1,6 @@
9460-#include <sysdeps/../math/w_log.c>
9461+#include <sysdeps/x86/isa-level.h>
9462+#if MINIMUM_X86_ISA_LEVEL >= AVX2_X86_ISA_LEVEL
9463+# include <sysdeps/ieee754/dbl-64/w_log.c>
9464+#else
9465+# include <sysdeps/../math/w_log.c>
9466+#endif
9467diff --git a/sysdeps/x86_64/fpu/multiarch/w_pow.c b/sysdeps/x86_64/fpu/multiarch/w_pow.c
9468index b50c1988de..d5fcc4f871 100644
9469--- a/sysdeps/x86_64/fpu/multiarch/w_pow.c
9470+++ b/sysdeps/x86_64/fpu/multiarch/w_pow.c
9471@@ -1 +1,6 @@
9472-#include <sysdeps/../math/w_pow.c>
9473+#include <sysdeps/x86/isa-level.h>
9474+#if MINIMUM_X86_ISA_LEVEL >= AVX2_X86_ISA_LEVEL
9475+# include <sysdeps/ieee754/dbl-64/w_pow.c>
9476+#else
9477+# include <sysdeps/../math/w_pow.c>
9478+#endif
9479diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile
9480index e1e894c963..d3d2270394 100644
9481--- a/sysdeps/x86_64/multiarch/Makefile
9482+++ b/sysdeps/x86_64/multiarch/Makefile
9483@@ -4,8 +4,8 @@ sysdep_routines += \
9484 memchr-avx2 \
9485 memchr-avx2-rtm \
9486 memchr-evex \
9487- memchr-evex512 \
9488 memchr-evex-rtm \
9489+ memchr-evex512 \
9490 memchr-sse2 \
9491 memcmp-avx2-movbe \
9492 memcmp-avx2-movbe-rtm \
9493@@ -37,8 +37,8 @@ sysdep_routines += \
9494 rawmemchr-avx2 \
9495 rawmemchr-avx2-rtm \
9496 rawmemchr-evex \
9497- rawmemchr-evex512 \
9498 rawmemchr-evex-rtm \
9499+ rawmemchr-evex512 \
9500 rawmemchr-sse2 \
9501 stpcpy-avx2 \
9502 stpcpy-avx2-rtm \
9503diff --git a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S
9504index 9984c3ca0f..97839a2248 100644
9505--- a/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S
9506+++ b/sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S
9507@@ -21,7 +21,9 @@
9508 2. If size is less than VEC, use integer register stores.
9509 3. If size is from VEC_SIZE to 2 * VEC_SIZE, use 2 VEC stores.
9510 4. If size is from 2 * VEC_SIZE to 4 * VEC_SIZE, use 4 VEC stores.
9511- 5. If size is more to 4 * VEC_SIZE, align to 4 * VEC_SIZE with
9512+ 5. On machines ERMS feature, if size is greater or equal than
9513+ __x86_rep_stosb_threshold then REP STOSB will be used.
9514+ 6. If size is more to 4 * VEC_SIZE, align to 4 * VEC_SIZE with
9515 4 VEC stores and store 4 * VEC at a time until done. */
9516
9517 #include <sysdep.h>
9518diff --git a/sysdeps/x86_64/multiarch/wcsncat-evex.S b/sysdeps/x86_64/multiarch/wcsncat-evex.S
9519index 392215950a..10bfb0a531 100644
9520--- a/sysdeps/x86_64/multiarch/wcsncat-evex.S
9521+++ b/sysdeps/x86_64/multiarch/wcsncat-evex.S
9522@@ -1,9 +1,9 @@
9523-#ifndef WCSCAT
9524-# define WCSCAT __wcsncat_evex
9525+#ifndef WCSNCAT
9526+# define WCSNCAT __wcsncat_evex
9527 #endif
9528
9529 #define USE_AS_WCSCPY
9530 #define USE_AS_STRCAT
9531
9532-#define STRNCAT WCSCAT
9533+#define STRNCAT WCSNCAT
9534 #include "strncat-evex.S"
9535diff --git a/sysdeps/x86_64/tst-gnu2-tls2mod1.S b/sysdeps/x86_64/tst-gnu2-tls2mod1.S
9536new file mode 100644
9537index 0000000000..1d636669ba
9538--- /dev/null
9539+++ b/sysdeps/x86_64/tst-gnu2-tls2mod1.S
9540@@ -0,0 +1,87 @@
9541+/* Check if TLSDESC relocation preserves %rdi, %rsi and %rbx.
9542+ Copyright (C) 2024 Free Software Foundation, Inc.
9543+ This file is part of the GNU C Library.
9544+
9545+ The GNU C Library is free software; you can redistribute it and/or
9546+ modify it under the terms of the GNU Lesser General Public
9547+ License as published by the Free Software Foundation; either
9548+ version 2.1 of the License, or (at your option) any later version.
9549+
9550+ The GNU C Library is distributed in the hope that it will be useful,
9551+ but WITHOUT ANY WARRANTY; without even the implied warranty of
9552+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9553+ Lesser General Public License for more details.
9554+
9555+ You should have received a copy of the GNU Lesser General Public
9556+ License along with the GNU C Library; if not, see
9557+ <http://www.gnu.org/licenses/>. */
9558+
9559+#include <sysdep.h>
9560+
9561+/* On AVX512 machines, OFFSET == 40 caused _dl_tlsdesc_dynamic_xsavec
9562+ to clobber %rdi, %rsi and %rbx. On Intel AVX CPUs, the state size
9563+ is 960 bytes and this test didn't fail. It may be due to the unused
9564+ last 128 bytes. On AMD AVX CPUs, the state size is 832 bytes and
9565+ this test might fail without the fix. */
9566+#ifndef OFFSET
9567+# define OFFSET 40
9568+#endif
9569+
9570+ .text
9571+ .p2align 4
9572+ .globl apply_tls
9573+ .type apply_tls, @function
9574+apply_tls:
9575+ cfi_startproc
9576+ _CET_ENDBR
9577+ pushq %rbp
9578+ cfi_def_cfa_offset (16)
9579+ cfi_offset (6, -16)
9580+ movdqu (%RDI_LP), %xmm0
9581+ lea tls_var1@TLSDESC(%rip), %RAX_LP
9582+ mov %RSP_LP, %RBP_LP
9583+ cfi_def_cfa_register (6)
9584+ /* Align stack to 64 bytes. */
9585+ and $-64, %RSP_LP
9586+ sub $OFFSET, %RSP_LP
9587+ pushq %rbx
9588+ /* Set %ebx to 0xbadbeef. */
9589+ movl $0xbadbeef, %ebx
9590+ movl $0xbadbeef, %esi
9591+ movq %rdi, saved_rdi(%rip)
9592+ movq %rsi, saved_rsi(%rip)
9593+ call *tls_var1@TLSCALL(%RAX_LP)
9594+ /* Check if _dl_tlsdesc_dynamic preserves %rdi, %rsi and %rbx. */
9595+ cmpq saved_rdi(%rip), %rdi
9596+ jne L(hlt)
9597+ cmpq saved_rsi(%rip), %rsi
9598+ jne L(hlt)
9599+ cmpl $0xbadbeef, %ebx
9600+ jne L(hlt)
9601+ add %fs:0, %RAX_LP
9602+ movups %xmm0, 32(%RAX_LP)
9603+ movdqu 16(%RDI_LP), %xmm1
9604+ mov %RAX_LP, %RBX_LP
9605+ movups %xmm1, 48(%RAX_LP)
9606+ lea 32(%RBX_LP), %RAX_LP
9607+ pop %rbx
9608+ leave
9609+ cfi_def_cfa (7, 8)
9610+ ret
9611+L(hlt):
9612+ hlt
9613+ cfi_endproc
9614+ .size apply_tls, .-apply_tls
9615+ .hidden tls_var1
9616+ .globl tls_var1
9617+ .section .tbss,"awT",@nobits
9618+ .align 16
9619+ .type tls_var1, @object
9620+ .size tls_var1, 3200
9621+tls_var1:
9622+ .zero 3200
9623+ .local saved_rdi
9624+ .comm saved_rdi,8,8
9625+ .local saved_rsi
9626+ .comm saved_rsi,8,8
9627+ .section .note.GNU-stack,"",@progbits
9628diff --git a/time/timespec_get.c b/time/timespec_get.c
9629index b031e42ca2..26a044bca6 100644
9630--- a/time/timespec_get.c
9631+++ b/time/timespec_get.c
9632@@ -4,7 +4,7 @@
9633 The GNU C Library is free software; you can redistribute it and/or
9634 modify it under the terms of the GNU Lesser General Public
9635 License as published by the Free Software Foundation; either
9636- version 2.1 of the License.
9637+ version 2.1 of the License, or (at your option) any later version.
9638
9639 The GNU C Library is distributed in the hope that it will be useful,
9640 but WITHOUT ANY WARRANTY; without even the implied warranty of
9641diff --git a/time/timespec_getres.c b/time/timespec_getres.c
9642index edb397507c..2e18b8bcac 100644
9643--- a/time/timespec_getres.c
9644+++ b/time/timespec_getres.c
9645@@ -5,7 +5,7 @@
9646 The GNU C Library is free software; you can redistribute it and/or
9647 modify it under the terms of the GNU Lesser General Public
9648 License as published by the Free Software Foundation; either
9649- version 2.1 of the License.
9650+ version 2.1 of the License, or (at your option) any later version.
9651
9652 The GNU C Library is distributed in the hope that it will be useful,
9653 but WITHOUT ANY WARRANTY; without even the implied warranty of