[PATCH 4/4] alpha: add multiarch IFUNC dispatchers
Matt Turner
mattst88@gmail.com
Sun Sep 6 19:06:09 GMT 2026
Dispatch at runtime between the generic implementations and the
EV6/EV67-optimized ones for nine functions:
memset: generic (EV4/EV5) vs EV6 assembly (dispatch on implver)
memcpy: generic (C) vs EV6 assembly (dispatch on implver)
strlen: generic vs EV67 CIX assembly (dispatch on amask CIX)
stpcpy: generic vs EV67 CIX assembly
stpncpy: generic vs EV67 CIX assembly
strcat: generic vs EV67 CIX assembly
strchr: generic vs EV67 CIX assembly
rawmemchr: generic vs EV67 CIX assembly
strncat: generic vs EV67 CIX assembly
Each function gets a resolver in a .c file and two assembly wrappers
(_ev5/_ev6 or _ev5/_ev67) that include the original source with renamed
entry points. The mem* functions have no generic alpha assembly, so they
use C generic wrappers for EV4/EV5.
The internal aliases are defined in the dispatchers, against the
redirected type, so that calls from inside libc go through the IFUNC
too. Defining them in the _ev5 variants instead, as the assembly they
include does, would point __GI_strlen and the rest at the ev5
implementation and every caller inside libc would get that one whatever
the CPU.
string.h needs care in these files. It defines __stpcpy as a macro
calling the corresponding builtin and, in the static library, redirects
that builtin back to the __ name, which collides with the redirection
the multiarch files set up; they define __NO_STRING_INLINES and
NO_MEMPCPY_STPCPY_REDIRECT first, as the x86_64 and s390 versions do.
ifunc-impl-list.c enumerates the implementations for the string tests,
which run each one in turn rather than only whichever the resolver
picks.
The dynamic linker cannot dispatch through an IFUNC before it has
relocated itself, so dl-symbol-redir-ifunc.h names an implementation
directly for the functions it needs while bootstrapping, for the static
case. The real ld.so pulls in the same multiarch objects as libc does,
though, so each _ev6/_ev67 wrapper here renames its entry point
unconditionally -- in both IS_IN(libc) and IS_IN(rtld) -- leaving only
the intended safe baseline (_ev5/generic) to define the plain public
name for rtld's own internal calls. Getting this wrong is silent and
CPU-dependent: whichever wrapper's object the static rtld link happens
to pick wins, with no runtime check at all, since rtld runs before any
ifunc resolver exists. Verified under qemu-alpha across
ev4/ev56/ev6/ev67/ev68 that ld.so's own memcpy/memset/strlen/stpcpy/
strchr calls all resolve to the safe baseline, and that dispatch to the
fast paths on ev56+ is unaffected.
With --enable-multi-arch a single binary selects the implementation the
processor wants at load time.
---
sysdeps/alpha/multiarch/Makefile | 22 ++++++++
sysdeps/alpha/multiarch/dl-symbol-redir-ifunc.h | 35 +++++++++++++
sysdeps/alpha/multiarch/ifunc-impl-list.c | 68 +++++++++++++++++++++++++
sysdeps/alpha/multiarch/memcpy.c | 49 ++++++++++++++++++
sysdeps/alpha/multiarch/memcpy_ev6.S | 34 +++++++++++++
sysdeps/alpha/multiarch/memcpy_generic.c | 26 ++++++++++
sysdeps/alpha/multiarch/memset.c | 49 ++++++++++++++++++
sysdeps/alpha/multiarch/memset_ev5.S | 33 ++++++++++++
sysdeps/alpha/multiarch/memset_ev6.S | 34 +++++++++++++
sysdeps/alpha/multiarch/rawmemchr.c | 55 ++++++++++++++++++++
sysdeps/alpha/multiarch/rawmemchr_ev5.S | 36 +++++++++++++
sysdeps/alpha/multiarch/rawmemchr_ev67.S | 37 ++++++++++++++
sysdeps/alpha/multiarch/stpcpy.c | 62 ++++++++++++++++++++++
sysdeps/alpha/multiarch/stpcpy_ev5.S | 39 ++++++++++++++
sysdeps/alpha/multiarch/stpcpy_ev67.S | 40 +++++++++++++++
sysdeps/alpha/multiarch/stpncpy.c | 55 ++++++++++++++++++++
sysdeps/alpha/multiarch/stpncpy_ev5.S | 36 +++++++++++++
sysdeps/alpha/multiarch/stpncpy_ev67.S | 37 ++++++++++++++
sysdeps/alpha/multiarch/strcat.c | 49 ++++++++++++++++++
sysdeps/alpha/multiarch/strcat_ev5.S | 33 ++++++++++++
sysdeps/alpha/multiarch/strcat_ev67.S | 34 +++++++++++++
sysdeps/alpha/multiarch/strchr.c | 50 ++++++++++++++++++
sysdeps/alpha/multiarch/strchr_ev5.S | 36 +++++++++++++
sysdeps/alpha/multiarch/strchr_ev67.S | 37 ++++++++++++++
sysdeps/alpha/multiarch/strlen.c | 49 ++++++++++++++++++
sysdeps/alpha/multiarch/strlen_ev5.S | 33 ++++++++++++
sysdeps/alpha/multiarch/strlen_ev67.S | 34 +++++++++++++
sysdeps/alpha/multiarch/strncat.c | 49 ++++++++++++++++++
sysdeps/alpha/multiarch/strncat_ev5.S | 30 +++++++++++
sysdeps/alpha/multiarch/strncat_ev67.S | 29 +++++++++++
30 files changed, 1210 insertions(+)
diff --git a/sysdeps/alpha/multiarch/Makefile b/sysdeps/alpha/multiarch/Makefile
new file mode 100644
index 0000000000..fb92fecb93
--- /dev/null
+++ b/sysdeps/alpha/multiarch/Makefile
@@ -0,0 +1,22 @@
+ifeq ($(subdir),string)
+sysdep_routines += \
+ memcpy_ev6 \
+ memcpy_generic \
+ memset_ev5 \
+ memset_ev6 \
+ rawmemchr_ev5 \
+ rawmemchr_ev67 \
+ stpcpy_ev5 \
+ stpcpy_ev67 \
+ stpncpy_ev5 \
+ stpncpy_ev67 \
+ strcat_ev5 \
+ strcat_ev67 \
+ strchr_ev5 \
+ strchr_ev67 \
+ strlen_ev5 \
+ strlen_ev67 \
+ strncat_ev5 \
+ strncat_ev67 \
+# sysdep_routines
+endif
diff --git a/sysdeps/alpha/multiarch/dl-symbol-redir-ifunc.h b/sysdeps/alpha/multiarch/dl-symbol-redir-ifunc.h
new file mode 100644
index 0000000000..3fb11f5511
--- /dev/null
+++ b/sysdeps/alpha/multiarch/dl-symbol-redir-ifunc.h
@@ -0,0 +1,35 @@
+/* Symbol redirection for loader/static initialization code.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _DL_IFUNC_GENERIC_H
+#define _DL_IFUNC_GENERIC_H
+
+/* Only the static dynamic linker needs these: the real ld.so pulls the
+ same multiarch objects in as libc does, and each _ev6/_ev67 wrapper
+ never defines the plain name in that case, leaving it to the safe
+ baseline (_ev5/generic). Redirecting here too would just be
+ redundant for the shared build. */
+#ifndef SHARED
+
+asm ("memcpy = __memcpy_generic");
+asm ("memset = __memset_ev5");
+asm ("strlen = __strlen_ev5");
+
+#endif /* !SHARED */
+
+#endif
diff --git a/sysdeps/alpha/multiarch/ifunc-impl-list.c b/sysdeps/alpha/multiarch/ifunc-impl-list.c
new file mode 100644
index 0000000000..dfa0ddfb5d
--- /dev/null
+++ b/sysdeps/alpha/multiarch/ifunc-impl-list.c
@@ -0,0 +1,68 @@
+/* Enumerate available IFUNC implementations of a function. Alpha version.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <string.h>
+#include <wchar.h>
+#include <ifunc-impl-list.h>
+#include <init-arch.h>
+
+size_t
+__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ size_t max)
+{
+ size_t i = max;
+
+ IFUNC_IMPL (i, name, memcpy,
+ IFUNC_IMPL_ADD (array, i, memcpy, IS_EV6_OR_LATER, __memcpy_ev6)
+ IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_generic));
+
+ IFUNC_IMPL (i, name, memset,
+ IFUNC_IMPL_ADD (array, i, memset, IS_EV6_OR_LATER, __memset_ev6)
+ IFUNC_IMPL_ADD (array, i, memset, 1, __memset_ev5));
+
+ IFUNC_IMPL (i, name, rawmemchr,
+ IFUNC_IMPL_ADD (array, i, rawmemchr, HAS_CIX, ___rawmemchr_ev67)
+ IFUNC_IMPL_ADD (array, i, rawmemchr, 1, ___rawmemchr_ev5));
+
+ IFUNC_IMPL (i, name, stpcpy,
+ IFUNC_IMPL_ADD (array, i, stpcpy, HAS_CIX, ___stpcpy_ev67)
+ IFUNC_IMPL_ADD (array, i, stpcpy, 1, ___stpcpy_ev5));
+
+ IFUNC_IMPL (i, name, stpncpy,
+ IFUNC_IMPL_ADD (array, i, stpncpy, HAS_CIX, ___stpncpy_ev67)
+ IFUNC_IMPL_ADD (array, i, stpncpy, 1, ___stpncpy_ev5));
+
+ IFUNC_IMPL (i, name, strcat,
+ IFUNC_IMPL_ADD (array, i, strcat, HAS_CIX, __strcat_ev67)
+ IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_ev5));
+
+ IFUNC_IMPL (i, name, strchr,
+ IFUNC_IMPL_ADD (array, i, strchr, HAS_CIX, __strchr_ev67)
+ IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_ev5));
+
+ IFUNC_IMPL (i, name, strlen,
+ IFUNC_IMPL_ADD (array, i, strlen, HAS_CIX, __strlen_ev67)
+ IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_ev5));
+
+ IFUNC_IMPL (i, name, strncat,
+ IFUNC_IMPL_ADD (array, i, strncat, HAS_CIX, __strncat_ev67)
+ IFUNC_IMPL_ADD (array, i, strncat, 1, __strncat_ev5));
+
+ return 0;
+}
diff --git a/sysdeps/alpha/multiarch/memcpy.c b/sysdeps/alpha/multiarch/memcpy.c
new file mode 100644
index 0000000000..2592706ede
--- /dev/null
+++ b/sysdeps/alpha/multiarch/memcpy.c
@@ -0,0 +1,49 @@
+/* Multiple versions of memcpy. Alpha version.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#if IS_IN (libc)
+# undef memcpy
+# define memcpy __redirect_memcpy
+# include <string.h>
+# include <init-arch.h>
+
+extern __typeof (__redirect_memcpy) __libc_memcpy;
+
+extern __typeof (__redirect_memcpy) __memcpy_generic attribute_hidden;
+extern __typeof (__redirect_memcpy) __memcpy_ev6 attribute_hidden;
+
+static inline __typeof (__redirect_memcpy) *
+select_memcpy_ifunc (void)
+{
+ if (IS_EV6_OR_LATER)
+ return __memcpy_ev6;
+
+ return __memcpy_generic;
+}
+
+libc_ifunc (__libc_memcpy, select_memcpy_ifunc ());
+
+# undef memcpy
+strong_alias (__libc_memcpy, memcpy);
+/* Internal callers use __GI_memcpy, which libc_hidden_builtin_def would
+ normally define; the name is redirected here, so define it by hand. */
+# ifdef SHARED
+__hidden_ver1 (__libc_memcpy, __GI_memcpy, __redirect_memcpy)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memcpy);
+# endif
+#endif
diff --git a/sysdeps/alpha/multiarch/memcpy_ev6.S b/sysdeps/alpha/multiarch/memcpy_ev6.S
new file mode 100644
index 0000000000..31673014ef
--- /dev/null
+++ b/sysdeps/alpha/multiarch/memcpy_ev6.S
@@ -0,0 +1,34 @@
+/* memcpy for Alpha, EV6 version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* Rename unconditionally, in both the libc and rtld builds: the plain
+ "memcpy" name is reserved for whichever wrapper is the safe rtld
+ bootstrap default (memcpy_generic.c), so this file must never define
+ it, in either build. */
+#if IS_IN (libc) || IS_IN (rtld)
+# define memcpy __memcpy_ev6
+#endif
+
+#if IS_IN (libc)
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+#endif
+
+#include <sysdeps/alpha/alphaev6/memcpy.S>
diff --git a/sysdeps/alpha/multiarch/memcpy_generic.c b/sysdeps/alpha/multiarch/memcpy_generic.c
new file mode 100644
index 0000000000..1c5e3a96ee
--- /dev/null
+++ b/sysdeps/alpha/multiarch/memcpy_generic.c
@@ -0,0 +1,26 @@
+/* memcpy for Alpha, generic C version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#if IS_IN (libc)
+# define MEMCPY __memcpy_generic
+
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+#endif
+
+#include <string/memcpy.c>
diff --git a/sysdeps/alpha/multiarch/memset.c b/sysdeps/alpha/multiarch/memset.c
new file mode 100644
index 0000000000..7dc4c3f52f
--- /dev/null
+++ b/sysdeps/alpha/multiarch/memset.c
@@ -0,0 +1,49 @@
+/* Multiple versions of memset. Alpha version.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#if IS_IN (libc)
+# undef memset
+# define memset __redirect_memset
+# include <string.h>
+# include <init-arch.h>
+
+extern __typeof (__redirect_memset) __libc_memset;
+
+extern __typeof (__redirect_memset) __memset_ev5 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_ev6 attribute_hidden;
+
+static inline __typeof (__redirect_memset) *
+select_memset_ifunc (void)
+{
+ if (IS_EV6_OR_LATER)
+ return __memset_ev6;
+
+ return __memset_ev5;
+}
+
+libc_ifunc (__libc_memset, select_memset_ifunc ());
+
+# undef memset
+strong_alias (__libc_memset, memset);
+/* Internal callers reach this through __GI_memset. Alias it to the IFUNC
+ so that they get the implementation chosen for this CPU too. */
+# ifdef SHARED
+__hidden_ver1 (__libc_memset, __GI_memset, __redirect_memset)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memset);
+# endif
+#endif
diff --git a/sysdeps/alpha/multiarch/memset_ev5.S b/sysdeps/alpha/multiarch/memset_ev5.S
new file mode 100644
index 0000000000..d6844d086a
--- /dev/null
+++ b/sysdeps/alpha/multiarch/memset_ev5.S
@@ -0,0 +1,33 @@
+/* memset for Alpha, EV4/EV5 version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#if IS_IN (libc)
+# define memset __memset_ev5
+
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+
+#endif
+
+#include <sysdeps/alpha/memset.S>
+
+#if IS_IN (rtld)
+strong_alias (memset, __memset_ev5)
+#endif
diff --git a/sysdeps/alpha/multiarch/memset_ev6.S b/sysdeps/alpha/multiarch/memset_ev6.S
new file mode 100644
index 0000000000..6bd1ea502f
--- /dev/null
+++ b/sysdeps/alpha/multiarch/memset_ev6.S
@@ -0,0 +1,34 @@
+/* memset for Alpha, EV6 version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* Rename unconditionally, in both the libc and rtld builds: the plain
+ "memset" name is reserved for whichever wrapper is the safe rtld
+ bootstrap default (memset_ev5.S), so this file must never define it,
+ in either build. */
+#if IS_IN (libc) || IS_IN (rtld)
+# define memset __memset_ev6
+#endif
+
+#if IS_IN (libc)
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+#endif
+
+#include <sysdeps/alpha/alphaev6/memset.S>
diff --git a/sysdeps/alpha/multiarch/rawmemchr.c b/sysdeps/alpha/multiarch/rawmemchr.c
new file mode 100644
index 0000000000..0235d5c7c3
--- /dev/null
+++ b/sysdeps/alpha/multiarch/rawmemchr.c
@@ -0,0 +1,55 @@
+/* Multiple versions of rawmemchr. Alpha version.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#if IS_IN (libc)
+# undef rawmemchr
+# define rawmemchr __redirect_rawmemchr
+# undef __rawmemchr
+# define __rawmemchr __redirect___rawmemchr
+# include <string.h>
+# include <init-arch.h>
+
+extern __typeof (__redirect___rawmemchr) __libc___rawmemchr;
+
+extern __typeof (__redirect___rawmemchr) ___rawmemchr_ev5 attribute_hidden;
+extern __typeof (__redirect___rawmemchr) ___rawmemchr_ev67 attribute_hidden;
+
+static inline __typeof (__redirect___rawmemchr) *
+select_rawmemchr_ifunc (void)
+{
+ if (HAS_CIX)
+ return ___rawmemchr_ev67;
+
+ return ___rawmemchr_ev5;
+}
+
+libc_ifunc (__libc___rawmemchr, select_rawmemchr_ifunc ());
+
+# undef rawmemchr
+# undef __rawmemchr
+strong_alias (__libc___rawmemchr, __rawmemchr);
+weak_alias (__rawmemchr, rawmemchr);
+/* Not libc_hidden_def: string.h declared the hidden prototype under the
+ redirected name, so that would alias to a __GI_ symbol nothing defines.
+ Alias it to the IFUNC so internal callers also get the implementation
+ chosen for this CPU. */
+# ifdef SHARED
+__hidden_ver1 (__rawmemchr, __GI___rawmemchr, __redirect___rawmemchr)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (rawmemchr);
+# endif
+#endif
diff --git a/sysdeps/alpha/multiarch/rawmemchr_ev5.S b/sysdeps/alpha/multiarch/rawmemchr_ev5.S
new file mode 100644
index 0000000000..8bbc83a525
--- /dev/null
+++ b/sysdeps/alpha/multiarch/rawmemchr_ev5.S
@@ -0,0 +1,36 @@
+/* rawmemchr for Alpha, generic version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#if IS_IN (libc)
+# define __rawmemchr ___rawmemchr_ev5
+
+# undef weak_alias
+# define weak_alias(a, b)
+
+# undef libc_hidden_def
+# define libc_hidden_def(name)
+
+#endif
+
+#include <sysdeps/alpha/rawmemchr.S>
+
+#if IS_IN (rtld)
+strong_alias (__rawmemchr, ___rawmemchr_ev5)
+#endif
diff --git a/sysdeps/alpha/multiarch/rawmemchr_ev67.S b/sysdeps/alpha/multiarch/rawmemchr_ev67.S
new file mode 100644
index 0000000000..d23466aec8
--- /dev/null
+++ b/sysdeps/alpha/multiarch/rawmemchr_ev67.S
@@ -0,0 +1,37 @@
+/* rawmemchr for Alpha, EV67 version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* Rename unconditionally, in both the libc and rtld builds: the plain
+ "__rawmemchr" name is reserved for whichever wrapper is the safe rtld
+ bootstrap default (rawmemchr_ev5.S), so this file must never define
+ it, in either build. */
+#if IS_IN (libc) || IS_IN (rtld)
+# define __rawmemchr ___rawmemchr_ev67
+#endif
+
+#if IS_IN (libc)
+# undef weak_alias
+# define weak_alias(a, b)
+
+# undef libc_hidden_def
+# define libc_hidden_def(name)
+#endif
+
+#include <sysdeps/alpha/alphaev67/rawmemchr.S>
diff --git a/sysdeps/alpha/multiarch/stpcpy.c b/sysdeps/alpha/multiarch/stpcpy.c
new file mode 100644
index 0000000000..de4c3ee38b
--- /dev/null
+++ b/sysdeps/alpha/multiarch/stpcpy.c
@@ -0,0 +1,62 @@
+/* Multiple versions of stpcpy. Alpha version.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#if IS_IN (libc)
+# undef stpcpy
+# define stpcpy __redirect_stpcpy
+# undef __stpcpy
+# define __stpcpy __redirect___stpcpy
+/* string.h defines __stpcpy as a macro calling __builtin_stpcpy, and
+ redirects __builtin_stpcpy back to __stpcpy in the static library;
+ both get in the way of redirecting the name here. */
+# define __NO_STRING_INLINES
+# define NO_MEMPCPY_STPCPY_REDIRECT
+# include <string.h>
+# include <init-arch.h>
+
+extern __typeof (__redirect___stpcpy) __libc___stpcpy;
+
+extern __typeof (__redirect___stpcpy) ___stpcpy_ev5 attribute_hidden;
+extern __typeof (__redirect___stpcpy) ___stpcpy_ev67 attribute_hidden;
+
+static inline __typeof (__redirect___stpcpy) *
+select_stpcpy_ifunc (void)
+{
+ if (HAS_CIX)
+ return ___stpcpy_ev67;
+
+ return ___stpcpy_ev5;
+}
+
+libc_ifunc (__libc___stpcpy, select_stpcpy_ifunc ());
+
+# undef stpcpy
+# undef __stpcpy
+strong_alias (__libc___stpcpy, __stpcpy);
+weak_alias (__stpcpy, stpcpy);
+/* Not libc_hidden_def: string.h declared the hidden prototype under the
+ redirected name, so that would alias to a __GI_ symbol nothing defines.
+ Alias both internal names to the IFUNC so internal callers also get the
+ implementation chosen for this CPU. */
+# ifdef SHARED
+__hidden_ver1 (__stpcpy, __GI___stpcpy, __redirect___stpcpy)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (stpcpy);
+__hidden_ver1 (__stpcpy, __GI_stpcpy, __redirect_stpcpy)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (stpcpy);
+# endif
+#endif
diff --git a/sysdeps/alpha/multiarch/stpcpy_ev5.S b/sysdeps/alpha/multiarch/stpcpy_ev5.S
new file mode 100644
index 0000000000..9525d46a8d
--- /dev/null
+++ b/sysdeps/alpha/multiarch/stpcpy_ev5.S
@@ -0,0 +1,39 @@
+/* stpcpy for Alpha, generic version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#if IS_IN (libc)
+# define __stpcpy ___stpcpy_ev5
+
+# undef weak_alias
+# define weak_alias(a, b)
+
+# undef libc_hidden_def
+# define libc_hidden_def(name)
+
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+
+#endif
+
+#include <sysdeps/alpha/stpcpy.S>
+
+#if IS_IN (rtld)
+strong_alias (__stpcpy, ___stpcpy_ev5)
+#endif
diff --git a/sysdeps/alpha/multiarch/stpcpy_ev67.S b/sysdeps/alpha/multiarch/stpcpy_ev67.S
new file mode 100644
index 0000000000..eb125ed502
--- /dev/null
+++ b/sysdeps/alpha/multiarch/stpcpy_ev67.S
@@ -0,0 +1,40 @@
+/* stpcpy for Alpha, EV67 version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* Rename unconditionally, in both the libc and rtld builds: the plain
+ "__stpcpy" name is reserved for whichever wrapper is the safe rtld
+ bootstrap default (stpcpy_ev5.S), so this file must never define it,
+ in either build. */
+#if IS_IN (libc) || IS_IN (rtld)
+# define __stpcpy ___stpcpy_ev67
+#endif
+
+#if IS_IN (libc)
+# undef weak_alias
+# define weak_alias(a, b)
+
+# undef libc_hidden_def
+# define libc_hidden_def(name)
+
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+#endif
+
+#include <sysdeps/alpha/alphaev67/stpcpy.S>
diff --git a/sysdeps/alpha/multiarch/stpncpy.c b/sysdeps/alpha/multiarch/stpncpy.c
new file mode 100644
index 0000000000..e6d58a4754
--- /dev/null
+++ b/sysdeps/alpha/multiarch/stpncpy.c
@@ -0,0 +1,55 @@
+/* Multiple versions of stpncpy. Alpha version.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#if IS_IN (libc)
+# undef stpncpy
+# define stpncpy __redirect_stpncpy
+# undef __stpncpy
+# define __stpncpy __redirect___stpncpy
+# include <string.h>
+# include <init-arch.h>
+
+extern __typeof (__redirect___stpncpy) __libc___stpncpy;
+
+extern __typeof (__redirect___stpncpy) ___stpncpy_ev5 attribute_hidden;
+extern __typeof (__redirect___stpncpy) ___stpncpy_ev67 attribute_hidden;
+
+static inline __typeof (__redirect___stpncpy) *
+select_stpncpy_ifunc (void)
+{
+ if (HAS_CIX)
+ return ___stpncpy_ev67;
+
+ return ___stpncpy_ev5;
+}
+
+libc_ifunc (__libc___stpncpy, select_stpncpy_ifunc ());
+
+# undef stpncpy
+# undef __stpncpy
+strong_alias (__libc___stpncpy, __stpncpy);
+weak_alias (__stpncpy, stpncpy);
+/* Not libc_hidden_def: string.h declared the hidden prototype under the
+ redirected name, so that would alias to a __GI_ symbol nothing defines.
+ Alias it to the IFUNC so internal callers also get the implementation
+ chosen for this CPU. */
+# ifdef SHARED
+__hidden_ver1 (__stpncpy, __GI___stpncpy, __redirect___stpncpy)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (stpncpy);
+# endif
+#endif
diff --git a/sysdeps/alpha/multiarch/stpncpy_ev5.S b/sysdeps/alpha/multiarch/stpncpy_ev5.S
new file mode 100644
index 0000000000..e9995a517e
--- /dev/null
+++ b/sysdeps/alpha/multiarch/stpncpy_ev5.S
@@ -0,0 +1,36 @@
+/* stpncpy for Alpha, generic version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#if IS_IN (libc)
+# define __stpncpy ___stpncpy_ev5
+
+# undef weak_alias
+# define weak_alias(a, b)
+
+# undef libc_hidden_def
+# define libc_hidden_def(name)
+
+#endif
+
+#include <sysdeps/alpha/stpncpy.S>
+
+#if IS_IN (rtld)
+strong_alias (__stpncpy, ___stpncpy_ev5)
+#endif
diff --git a/sysdeps/alpha/multiarch/stpncpy_ev67.S b/sysdeps/alpha/multiarch/stpncpy_ev67.S
new file mode 100644
index 0000000000..725126d484
--- /dev/null
+++ b/sysdeps/alpha/multiarch/stpncpy_ev67.S
@@ -0,0 +1,37 @@
+/* stpncpy for Alpha, EV67 version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* Rename unconditionally, in both the libc and rtld builds: the plain
+ "__stpncpy" name is reserved for whichever wrapper is the safe rtld
+ bootstrap default (stpncpy_ev5.S), so this file must never define it,
+ in either build. */
+#if IS_IN (libc) || IS_IN (rtld)
+# define __stpncpy ___stpncpy_ev67
+#endif
+
+#if IS_IN (libc)
+# undef weak_alias
+# define weak_alias(a, b)
+
+# undef libc_hidden_def
+# define libc_hidden_def(name)
+#endif
+
+#include <sysdeps/alpha/alphaev67/stpncpy.S>
diff --git a/sysdeps/alpha/multiarch/strcat.c b/sysdeps/alpha/multiarch/strcat.c
new file mode 100644
index 0000000000..bbba7bfa33
--- /dev/null
+++ b/sysdeps/alpha/multiarch/strcat.c
@@ -0,0 +1,49 @@
+/* Multiple versions of strcat. Alpha version.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#if IS_IN (libc)
+# undef strcat
+# define strcat __redirect_strcat
+# include <string.h>
+# include <init-arch.h>
+
+extern __typeof (__redirect_strcat) __libc_strcat;
+
+extern __typeof (__redirect_strcat) __strcat_ev5 attribute_hidden;
+extern __typeof (__redirect_strcat) __strcat_ev67 attribute_hidden;
+
+static inline __typeof (__redirect_strcat) *
+select_strcat_ifunc (void)
+{
+ if (HAS_CIX)
+ return __strcat_ev67;
+
+ return __strcat_ev5;
+}
+
+libc_ifunc (__libc_strcat, select_strcat_ifunc ());
+
+# undef strcat
+strong_alias (__libc_strcat, strcat);
+/* Internal callers reach this through __GI_strcat. Alias it to the IFUNC
+ so that they get the implementation chosen for this CPU too. */
+# ifdef SHARED
+__hidden_ver1 (__libc_strcat, __GI_strcat, __redirect_strcat)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strcat);
+# endif
+#endif
diff --git a/sysdeps/alpha/multiarch/strcat_ev5.S b/sysdeps/alpha/multiarch/strcat_ev5.S
new file mode 100644
index 0000000000..5b0c421381
--- /dev/null
+++ b/sysdeps/alpha/multiarch/strcat_ev5.S
@@ -0,0 +1,33 @@
+/* strcat for Alpha, generic version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#if IS_IN (libc)
+# define strcat __strcat_ev5
+
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+
+#endif
+
+#include <sysdeps/alpha/strcat.S>
+
+#if IS_IN (rtld)
+strong_alias (strcat, __strcat_ev5)
+#endif
diff --git a/sysdeps/alpha/multiarch/strcat_ev67.S b/sysdeps/alpha/multiarch/strcat_ev67.S
new file mode 100644
index 0000000000..c9614176e9
--- /dev/null
+++ b/sysdeps/alpha/multiarch/strcat_ev67.S
@@ -0,0 +1,34 @@
+/* strcat for Alpha, EV67 version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* Rename unconditionally, in both the libc and rtld builds: the plain
+ "strcat" name is reserved for whichever wrapper is the safe rtld
+ bootstrap default (strcat_ev5.S), so this file must never define it,
+ in either build. */
+#if IS_IN (libc) || IS_IN (rtld)
+# define strcat __strcat_ev67
+#endif
+
+#if IS_IN (libc)
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+#endif
+
+#include <sysdeps/alpha/alphaev67/strcat.S>
diff --git a/sysdeps/alpha/multiarch/strchr.c b/sysdeps/alpha/multiarch/strchr.c
new file mode 100644
index 0000000000..57ca43ab81
--- /dev/null
+++ b/sysdeps/alpha/multiarch/strchr.c
@@ -0,0 +1,50 @@
+/* Multiple versions of strchr. Alpha version.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#if IS_IN (libc)
+# undef strchr
+# define strchr __redirect_strchr
+# include <string.h>
+# include <init-arch.h>
+
+extern __typeof (__redirect_strchr) __libc_strchr;
+
+extern __typeof (__redirect_strchr) __strchr_ev5 attribute_hidden;
+extern __typeof (__redirect_strchr) __strchr_ev67 attribute_hidden;
+
+static inline __typeof (__redirect_strchr) *
+select_strchr_ifunc (void)
+{
+ if (HAS_CIX)
+ return __strchr_ev67;
+
+ return __strchr_ev5;
+}
+
+libc_ifunc (__libc_strchr, select_strchr_ifunc ());
+
+# undef strchr
+strong_alias (__libc_strchr, strchr);
+weak_alias (strchr, index);
+/* Internal callers reach this through __GI_strchr. Alias it to the IFUNC
+ so that they get the implementation chosen for this CPU too. */
+# ifdef SHARED
+__hidden_ver1 (__libc_strchr, __GI_strchr, __redirect_strchr)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strchr);
+# endif
+#endif
diff --git a/sysdeps/alpha/multiarch/strchr_ev5.S b/sysdeps/alpha/multiarch/strchr_ev5.S
new file mode 100644
index 0000000000..2bed0a475f
--- /dev/null
+++ b/sysdeps/alpha/multiarch/strchr_ev5.S
@@ -0,0 +1,36 @@
+/* strchr for Alpha, generic version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#if IS_IN (libc)
+# define strchr __strchr_ev5
+
+# undef weak_alias
+# define weak_alias(a, b)
+
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+
+#endif
+
+#include <sysdeps/alpha/strchr.S>
+
+#if IS_IN (rtld)
+strong_alias (strchr, __strchr_ev5)
+#endif
diff --git a/sysdeps/alpha/multiarch/strchr_ev67.S b/sysdeps/alpha/multiarch/strchr_ev67.S
new file mode 100644
index 0000000000..4518d471c5
--- /dev/null
+++ b/sysdeps/alpha/multiarch/strchr_ev67.S
@@ -0,0 +1,37 @@
+/* strchr for Alpha, EV67 version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* Rename unconditionally, in both the libc and rtld builds: the plain
+ "strchr" name is reserved for whichever wrapper is the safe rtld
+ bootstrap default (strchr_ev5.S), so this file must never define it,
+ in either build. */
+#if IS_IN (libc) || IS_IN (rtld)
+# define strchr __strchr_ev67
+#endif
+
+#if IS_IN (libc)
+# undef weak_alias
+# define weak_alias(a, b)
+
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+#endif
+
+#include <sysdeps/alpha/alphaev67/strchr.S>
diff --git a/sysdeps/alpha/multiarch/strlen.c b/sysdeps/alpha/multiarch/strlen.c
new file mode 100644
index 0000000000..7c9bda3e67
--- /dev/null
+++ b/sysdeps/alpha/multiarch/strlen.c
@@ -0,0 +1,49 @@
+/* Multiple versions of strlen. Alpha version.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#if IS_IN (libc)
+# undef strlen
+# define strlen __redirect_strlen
+# include <string.h>
+# include <init-arch.h>
+
+extern __typeof (__redirect_strlen) __libc_strlen;
+
+extern __typeof (__redirect_strlen) __strlen_ev5 attribute_hidden;
+extern __typeof (__redirect_strlen) __strlen_ev67 attribute_hidden;
+
+static inline __typeof (__redirect_strlen) *
+select_strlen_ifunc (void)
+{
+ if (HAS_CIX)
+ return __strlen_ev67;
+
+ return __strlen_ev5;
+}
+
+libc_ifunc (__libc_strlen, select_strlen_ifunc ());
+
+# undef strlen
+strong_alias (__libc_strlen, strlen);
+/* Internal callers reach this through __GI_strlen. Alias it to the IFUNC
+ so that they get the implementation chosen for this CPU too. */
+# ifdef SHARED
+__hidden_ver1 (__libc_strlen, __GI_strlen, __redirect_strlen)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strlen);
+# endif
+#endif
diff --git a/sysdeps/alpha/multiarch/strlen_ev5.S b/sysdeps/alpha/multiarch/strlen_ev5.S
new file mode 100644
index 0000000000..8894b77486
--- /dev/null
+++ b/sysdeps/alpha/multiarch/strlen_ev5.S
@@ -0,0 +1,33 @@
+/* strlen for Alpha, generic version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#if IS_IN (libc)
+# define strlen __strlen_ev5
+
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+
+#endif
+
+#include <sysdeps/alpha/strlen.S>
+
+#if IS_IN (rtld)
+strong_alias (strlen, __strlen_ev5)
+#endif
diff --git a/sysdeps/alpha/multiarch/strlen_ev67.S b/sysdeps/alpha/multiarch/strlen_ev67.S
new file mode 100644
index 0000000000..d1ac881cd6
--- /dev/null
+++ b/sysdeps/alpha/multiarch/strlen_ev67.S
@@ -0,0 +1,34 @@
+/* strlen for Alpha, EV67 version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* Rename unconditionally, in both the libc and rtld builds: the plain
+ "strlen" name is reserved for whichever wrapper is the safe rtld
+ bootstrap default (strlen_ev5.S), so this file must never define it,
+ in either build. */
+#if IS_IN (libc) || IS_IN (rtld)
+# define strlen __strlen_ev67
+#endif
+
+#if IS_IN (libc)
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+#endif
+
+#include <sysdeps/alpha/alphaev67/strlen.S>
diff --git a/sysdeps/alpha/multiarch/strncat.c b/sysdeps/alpha/multiarch/strncat.c
new file mode 100644
index 0000000000..b844518d1a
--- /dev/null
+++ b/sysdeps/alpha/multiarch/strncat.c
@@ -0,0 +1,49 @@
+/* Multiple versions of strncat. Alpha version.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#if IS_IN (libc)
+# undef strncat
+# define strncat __redirect_strncat
+# include <string.h>
+# include <init-arch.h>
+
+extern __typeof (__redirect_strncat) __libc_strncat;
+
+extern __typeof (__redirect_strncat) __strncat_ev5 attribute_hidden;
+extern __typeof (__redirect_strncat) __strncat_ev67 attribute_hidden;
+
+static inline __typeof (__redirect_strncat) *
+select_strncat_ifunc (void)
+{
+ if (HAS_CIX)
+ return __strncat_ev67;
+
+ return __strncat_ev5;
+}
+
+libc_ifunc (__libc_strncat, select_strncat_ifunc ());
+
+# undef strncat
+strong_alias (__libc_strncat, strncat);
+/* Internal callers reach this through __GI_strncat. Alias it to the IFUNC
+ so that they get the implementation chosen for this CPU too. */
+# ifdef SHARED
+__hidden_ver1 (__libc_strncat, __GI_strncat, __redirect_strncat)
+ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strncat);
+# endif
+#endif
diff --git a/sysdeps/alpha/multiarch/strncat_ev5.S b/sysdeps/alpha/multiarch/strncat_ev5.S
new file mode 100644
index 0000000000..591ac9173d
--- /dev/null
+++ b/sysdeps/alpha/multiarch/strncat_ev5.S
@@ -0,0 +1,30 @@
+/* strncat for Alpha, generic version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#if IS_IN (libc)
+# define strncat __strncat_ev5
+
+#endif
+
+#include <sysdeps/alpha/strncat.S>
+
+#if IS_IN (rtld)
+strong_alias (strncat, __strncat_ev5)
+#endif
diff --git a/sysdeps/alpha/multiarch/strncat_ev67.S b/sysdeps/alpha/multiarch/strncat_ev67.S
new file mode 100644
index 0000000000..79850a941a
--- /dev/null
+++ b/sysdeps/alpha/multiarch/strncat_ev67.S
@@ -0,0 +1,29 @@
+/* strncat for Alpha, EV67 version for multiarch dispatch.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* Rename unconditionally, in both the libc and rtld builds: the plain
+ "strncat" name is reserved for whichever wrapper is the safe rtld
+ bootstrap default (strncat_ev5.S), so this file must never define it,
+ in either build. */
+#if IS_IN (libc) || IS_IN (rtld)
+# define strncat __strncat_ev67
+#endif
+
+#include <sysdeps/alpha/alphaev67/strncat.S>
--
2.54.0
More information about the Libc-alpha
mailing list