[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