[PATCH] AArch64: Remove EMAG ifuncs

Wilco Dijkstra Wilco.Dijkstra@arm.com
Mon Mar 2 18:54:56 GMT 2026


Remove the old EMAG ifuncs for memset and memchr.  Also remove old
entries from cpu_list[].

Passes regress, OK for commit?

---

diff --git a/sysdeps/aarch64/cpu-features.h b/sysdeps/aarch64/cpu-features.h
index 1fe35d986b14a14fd55d6e4d3ac59fbb21e55f71..2957cd9c255bdb811a84b6b0fb3e8ab193d62233 100644
--- a/sysdeps/aarch64/cpu-features.h
+++ b/sysdeps/aarch64/cpu-features.h
@@ -40,9 +40,6 @@
 #define MIDR_IMPLEMENTOR(midr)	\
 	(((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT)
 
-#define IS_EMAG(midr) (MIDR_IMPLEMENTOR(midr) == 'P'			      \
-                       && MIDR_PARTNUM(midr) == 0x000)
-
 #define IS_KUNPENG920(midr) (MIDR_IMPLEMENTOR(midr) == 'H'			   \
                         && MIDR_PARTNUM(midr) == 0xd01)
 
diff --git a/sysdeps/aarch64/multiarch/Makefile b/sysdeps/aarch64/multiarch/Makefile
index deef7349fc4922aa158d72af285d042351c0bb71..988f7cec2562127cdae463b449245aab2a0e00dc 100644
--- a/sysdeps/aarch64/multiarch/Makefile
+++ b/sysdeps/aarch64/multiarch/Makefile
@@ -1,7 +1,5 @@
 ifeq ($(subdir),string)
 sysdep_routines += \
-  memchr_generic \
-  memchr_nosimd \
   memcpy_a64fx \
   memcpy_generic \
   memcpy_kunpeng950 \
@@ -10,7 +8,6 @@ sysdep_routines += \
   memcpy_sve \
   memmove_mops \
   memset_a64fx \
-  memset_emag \
   memset_generic \
   memset_kunpeng \
   memset_mops \
diff --git a/sysdeps/aarch64/multiarch/ifunc-impl-list.c b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
index 2fddf58010a912ae3ea1e2d123a886066f0b3880..ea5f5853c312e61fcf12458654a76740114c8a4d 100644
--- a/sysdeps/aarch64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/aarch64/multiarch/ifunc-impl-list.c
@@ -50,16 +50,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
   IFUNC_IMPL (i, name, memset,
 	      IFUNC_IMPL_ADD (array, i, memset, (zva_size == 64), __memset_zva64)
 	      IFUNC_IMPL_ADD (array, i, memset, (zva_size == 64), __memset_oryon1)
-	      IFUNC_IMPL_ADD (array, i, memset, 1, __memset_emag)
 	      IFUNC_IMPL_ADD (array, i, memset, 1, __memset_kunpeng)
 	      IFUNC_IMPL_ADD (array, i, memset, sve && zva_size == 256, __memset_a64fx)
 	      IFUNC_IMPL_ADD (array, i, memset, sve && zva_size == 64, __memset_sve_zva64)
 	      IFUNC_IMPL_ADD (array, i, memset, mops, __memset_mops)
 	      IFUNC_IMPL_ADD (array, i, memset, 1, __memset_generic))
-  IFUNC_IMPL (i, name, memchr,
-	      IFUNC_IMPL_ADD (array, i, memchr, !mte, __memchr_nosimd)
-	      IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_generic))
-
   IFUNC_IMPL (i, name, strlen,
 	      IFUNC_IMPL_ADD (array, i, strlen, !mte, __strlen_asimd)
 	      IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_generic))
diff --git a/sysdeps/aarch64/multiarch/memchr.c b/sysdeps/aarch64/multiarch/memchr.c
deleted file mode 100644
index 3b9f14e49054b3dd004577278ab08259e3d7c928..0000000000000000000000000000000000000000
--- a/sysdeps/aarch64/multiarch/memchr.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Multiple versions of memchr. AARCH64 version.
-   Copyright (C) 2018-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/>.  */
-
-/* Define multiple versions only for the definition in libc.  */
-
-#if IS_IN (libc)
-/* Redefine memchr so that the compiler won't complain about the type
-   mismatch with the IFUNC selector in strong_alias, below.  */
-# undef memchr
-# define memchr __redirect_memchr
-# include <string.h>
-# include <init-arch.h>
-
-extern __typeof (__redirect_memchr) __memchr;
-
-extern __typeof (__redirect_memchr) __memchr_generic attribute_hidden;
-extern __typeof (__redirect_memchr) __memchr_nosimd attribute_hidden;
-
-libc_ifunc (__memchr,
-	    ((IS_EMAG (midr)
-	       ? __memchr_nosimd
-	       : __memchr_generic)));
-
-# undef memchr
-strong_alias (__memchr, memchr);
-#endif
diff --git a/sysdeps/aarch64/multiarch/memchr_generic.S b/sysdeps/aarch64/multiarch/memchr_generic.S
deleted file mode 100644
index 2de3d535e571252cd7d0bd69803145661e826e9e..0000000000000000000000000000000000000000
--- a/sysdeps/aarch64/multiarch/memchr_generic.S
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Memchr for aarch64, default version for internal use.
-   Copyright (C) 2018-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 MEMCHR __memchr_generic
-
-/* Do not hide the generic version of memchr, we use it internally.  */
-# undef libc_hidden_builtin_def
-# define libc_hidden_builtin_def(name)
-
-# undef weak_alias
-# define weak_alias(a, b)
-
-/* Add a hidden definition for use within libc.so.  */
-# ifdef SHARED
-	.globl __GI_memchr; __GI_memchr = __memchr_generic
-# endif
-#endif
-
-# include "../memchr.S"
diff --git a/sysdeps/aarch64/multiarch/memchr_nosimd.S b/sysdeps/aarch64/multiarch/memchr_nosimd.S
deleted file mode 100644
index a7e331f3af0729e43922b84ac5da1d9866489c2c..0000000000000000000000000000000000000000
--- a/sysdeps/aarch64/multiarch/memchr_nosimd.S
+++ /dev/null
@@ -1,215 +0,0 @@
-/* memchr - find a character in a memory zone using base integer registers
-
-   Copyright (C) 2018-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>
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * Use base integer registers.
- */
-
-/* Arguments and results.  */
-#define srcin		x0
-#define chrin		x1
-#define cntin		x2
-
-#define result		x0
-
-#define repchr		x1
-
-#define tmp1		x2
-#define tmp2		x3
-#define tmp3		x4
-#define tmp4		x5
-
-#define src		x6
-#define srcend		x7
-#define srcend16	x8
-
-#define anymore		x9
-
-#define zeroones	x10
-
-#define data1		x11
-#define data2		x12
-
-#define has_chr1	x13
-#define has_chr2	x14
-
-#define REP8_01		0x0101010101010101
-#define REP8_7f		0x7f7f7f7f7f7f7f7f
-
-
-ENTRY (__memchr_nosimd)
-
-	/* Do not dereference srcin if no bytes to compare. */
-	cbz	cntin, L(none_chr)
-
-	/* Start address is 16-byte aligned or not? */
-	tst	srcin, 15
-	bic	src, srcin, 15
-
-	mov	zeroones, REP8_01
-	and	repchr, chrin, 255
-	/* Generate a qword integer as |c|c|c|c|c|c|c|c|. */
-	mul	repchr, repchr, zeroones
-
-	add	srcend, srcin, cntin
-	/*
-	 * srcend16 is address of the block following the last block.
-	 *
-	 * [A block is 16-byte aligned and sized.]
-	 */
-	add	srcend16, srcend, 15
-	bic	srcend16, srcend16, 15
-
-	b.eq	L(loop)
-
-	/* Load the first block containing start address. */
-	ldp	data1, data2, [src], 16
-
-	lsl	tmp1, srcin, 3
-	mov	tmp2, ~0
-#ifdef __AARCH64EB__
-	lsr	tmp3, tmp2, tmp1
-#else
-	lsl	tmp3, tmp2, tmp1
-#endif
-	/* Start address is in the first or the second qword? */
-	tst	srcin, 8
-
-	/*
-	 * Transform any byte in the block to zero using XOR operation,
-	 * if that byte equals the char to search. In this way, searching
-	 * the char becomes detecting zero in the resulting two qwords.
-	 */
-	eor	data1, data1, repchr
-	eor	data2, data2, repchr
-
-	/*
-	 * Set those unused bytes(before start address) to 0xff, so
-	 * that they will not hit any zero detection.
-	 */
-	orn	tmp1, data1, tmp3
-	orn	tmp2, data2, tmp3
-
-	csinv	data1, tmp1, xzr, eq
-	csel	data2, data2, tmp2, eq
-
-	/*
-	 * When the first and last block are the same, there are two cases:
-	 *  o. Memory range to search is just in one block.
-	 *      ( start address - end address) < 0
-	 *
-	 *  o. Memory range is so large that end address wrap-around.
-	 *      ( start address - end address) > 0
-	 */
-	cmp	srcin, srcend
-	ccmp	src, srcend16, 0, mi
-	csetm	anymore, ne
-	b	L(find_chr)
-
-	.p2align 4
-L(loop):
-	ldp	data1, data2, [src], 16
-
-	subs	anymore, src, srcend16
-
-	/*
-	 * Transform any byte in the block to zero using XOR operation,
-	 * if that byte equals the char to search.
-	 */
-	eor	data1, data1, repchr
-	eor	data2, data2, repchr
-
-L(find_chr):
-	/*
-	 * Use the following integer test to find out if any byte in a
-	 * qword is zero. If do not contain zero-valued byte, test result
-	 * is zero.
-	 *
-	 *  (qword - 0x0101010101010101) & ~(qword) & 0x8080808080808080
-	 * =
-	 *  (qword - 0x0101010101010101) & ~(qword  | 0x7f7f7f7f7f7f7f7f)
-	 *
-	 */
-	sub	tmp1, data1, zeroones
-	sub	tmp2, data2, zeroones
-
-	orr	tmp3, data1, REP8_7f
-	orr	tmp4, data2, REP8_7f
-
-	bic	has_chr1, tmp1, tmp3
-	bic	has_chr2, tmp2, tmp4
-
-	orr	tmp1, has_chr1, has_chr2
-	ccmp	tmp1, 0, 0, ne
-
-	b.eq	L(loop)
-
-	cbz	has_chr1, 1f
-	sub	result, src, 16
-#ifdef __AARCH64EB__
-	rev	data1, data1
-#else
-	rev	has_chr1, has_chr1
-#endif
-	b	L(done)
-
-1:	cbz	has_chr2, L(none_chr)
-	sub	result, src, 8
-#ifdef __AARCH64EB__
-	rev	data1, data2
-#else
-	rev	has_chr1, has_chr2
-#endif
-
-L(done):
-#ifdef __AARCH64EB__
-	/*
-	 * For big-endian, can not directly use has_chr1/has_chr2 because
-	 * two qwords has been reversed after loading from memory.
-	 * Thus, have to perform char detection on two qwords again, which
-	 * should be byte-swapped this time.
-	 */
-	sub	tmp1, data1, zeroones
-	orr	tmp3, data1, REP8_7f
-	bic	has_chr1, tmp1, tmp3
-	rev	has_chr1, has_chr1
-#endif
-
-	/*
-	 * If the specified char is found in a qword, the corresponding
-	 * byte of in has_chr has value of 1, while this is only true for
-	 * the first occurrence, not other occurrences.
-	 */
-	cmp	anymore, 0
-	clz	tmp1, has_chr1
-	add	result, result, tmp1, lsr 3
-	ccmp	result, srcend, 8, eq	/* NZCV = 8000 */
-	csel	result, result, xzr, mi
-	ret
-
-L(none_chr):
-	mov	result, 0
-	ret
-
-END (__memchr_nosimd)
diff --git a/sysdeps/aarch64/multiarch/memset.c b/sysdeps/aarch64/multiarch/memset.c
index 76c6532b811e3bfab31bb60b4270305c8b60a811..438845eec9e2d273272a270a0f87833e26ea8c84 100644
--- a/sysdeps/aarch64/multiarch/memset.c
+++ b/sysdeps/aarch64/multiarch/memset.c
@@ -30,7 +30,6 @@
 extern __typeof (__redirect_memset) __libc_memset;
 
 extern __typeof (__redirect_memset) __memset_zva64 attribute_hidden;
-extern __typeof (__redirect_memset) __memset_emag attribute_hidden;
 extern __typeof (__redirect_memset) __memset_kunpeng attribute_hidden;
 extern __typeof (__redirect_memset) __memset_a64fx attribute_hidden;
 extern __typeof (__redirect_memset) __memset_generic attribute_hidden;
@@ -61,9 +60,6 @@ select_memset_ifunc (void)
   if (IS_KUNPENG920 (midr))
     return __memset_kunpeng;
 
-  if (IS_EMAG (midr))
-    return __memset_emag;
-
   if (zva_size == 64)
     return __memset_zva64;
 
diff --git a/sysdeps/aarch64/multiarch/memset_emag.S b/sysdeps/aarch64/multiarch/memset_emag.S
deleted file mode 100644
index 8f68de6f72d0f75acc068351c8689b004bdbab0d..0000000000000000000000000000000000000000
--- a/sysdeps/aarch64/multiarch/memset_emag.S
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Optimized memset for AmpereComputing emag processor.
-   Copyright (C) 2018-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>
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64, unaligned accesses
- *
- */
-
-#define dstin	x0
-#define val	x1
-#define valw	w1
-#define count	x2
-#define dst	x3
-#define dstend	x4
-
-ENTRY (__memset_emag)
-
-	bfi	valw, valw, 8, 8
-	bfi	valw, valw, 16, 16
-	bfi	val, val, 32, 32
-
-	add	dstend, dstin, count
-
-	cmp	count, 96
-	b.hi	L(set_long)
-	cmp	count, 16
-	b.hs	L(set_medium)
-
-	/* Set 0..15 bytes.  */
-	tbz	count, 3, 1f
-	str	val, [dstin]
-	str	val, [dstend, -8]
-	ret
-
-	.p2align 3
-1:	tbz	count, 2, 2f
-	str	valw, [dstin]
-	str	valw, [dstend, -4]
-	ret
-2:	cbz	count, 3f
-	strb	valw, [dstin]
-	tbz	count, 1, 3f
-	strh	valw, [dstend, -2]
-3:	ret
-
-	.p2align 3
-	/* Set 16..96 bytes.  */
-L(set_medium):
-	stp	val, val, [dstin]
-	tbnz	count, 6, L(set96)
-	stp	val, val, [dstend, -16]
-	tbz	count, 5, 1f
-	stp	val, val, [dstin, 16]
-	stp	val, val, [dstend, -32]
-1:	ret
-
-	.p2align 4
-	/* Set 64..96 bytes.  Write 64 bytes from the start and
-	   32 bytes from the end.  */
-L(set96):
-	stp	val, val, [dstin, 16]
-	stp	val, val, [dstin, 32]
-	stp	val, val, [dstin, 48]
-	stp	val, val, [dstend, -32]
-	stp	val, val, [dstend, -16]
-	ret
-
-	.p2align 4
-L(set_long):
-	stp	val, val, [dstin]
-	bic	dst, dstin, 15
-	/* Small-size or non-zero memset does not use DC ZVA. */
-	sub	count, dstend, dst
-
-	/*
-	 * Adjust count and bias for loop. By subtracting extra 1 from count,
-	 * it is easy to use tbz instruction to check whether loop tailing
-	 * count is less than 33 bytes, so as to bypass 2 unnecessary stps.
-	 */
-	sub	count, count, 64+16+1
-
-1:	stp	val, val, [dst, 16]
-	stp	val, val, [dst, 32]
-	stp	val, val, [dst, 48]
-	stp	val, val, [dst, 64]!
-	subs	count, count, 64
-	b.hs	1b
-
-	tbz	count, 5, 1f	/* Remaining count is less than 33 bytes? */
-	stp	val, val, [dst, 16]
-	stp	val, val, [dst, 32]
-1:	stp	val, val, [dstend, -32]
-	stp	val, val, [dstend, -16]
-	ret
-
-END (__memset_emag)
diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
index 15aed15a667e89abd2790a22a319a8a6aaecba02..70d3272772f5f36a3435d0ae8919d781a1e2412e 100644
--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
@@ -44,11 +44,6 @@ struct cpu_list
 static const struct cpu_list cpu_list[] =
 {
 #define CPU_LIST_ENTRY(__str, __num) { __str, sizeof (__str) - 1, __num }
-  CPU_LIST_ENTRY ("thunderxt88",    0x430F0A10),
-  CPU_LIST_ENTRY ("thunderx2t99",   0x431F0AF0),
-  CPU_LIST_ENTRY ("thunderx2t99p1", 0x420F5160),
-  CPU_LIST_ENTRY ("ares",           0x411FD0C0),
-  CPU_LIST_ENTRY ("emag",           0x503F0001),
   CPU_LIST_ENTRY ("kunpeng920",     0x481FD010),
   CPU_LIST_ENTRY ("kunpeng950",     0x480FD060),
   CPU_LIST_ENTRY ("a64fx",          0x460F0010),



More information about the Libc-alpha mailing list