aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
diff options
context:
space:
mode:
authorMatheus Castanho <msc@linux.ibm.com>2021-05-11 17:53:07 -0300
committerMatheus Castanho <msc@linux.ibm.com>2021-05-17 10:30:35 -0300
commit1a594aa986ffe28657a03baa5c53c0a0e7dc2ecd (patch)
tree0778775cd1288d4ead4e707473656b338654bcd6 /sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
parent2d53566ec3c622944bd3921c1ccb9391b2dbcb13 (diff)
downloadglibc-1a594aa986ffe28657a03baa5c53c0a0e7dc2ecd.zip
glibc-1a594aa986ffe28657a03baa5c53c0a0e7dc2ecd.tar.gz
glibc-1a594aa986ffe28657a03baa5c53c0a0e7dc2ecd.tar.bz2
powerpc: Add optimized rawmemchr for POWER10
Reuse code for optimized strlen to implement a faster version of rawmemchr. This takes advantage of the same benefits provided by the strlen implementation, but needs some extra steps. __strlen_power10 code should be unchanged after this change. rawmemchr returns a pointer to the char found, while strlen returns only the length, so we have to take that into account when preparing the return value. To quickly check 64B, the loop on __strlen_power10 merges the whole block into 16B by using unsigned minimum vector operations (vminub) and checks if there are any \0 on the resulting vector. The same code is used by rawmemchr if the char c is 0. However, this approach does not work when c != 0. We first need to subtract each byte by c, so that the value we are looking for is converted to a 0, then taking the minimum and checking for nulls works again. The new code branches after it has compared ~256 bytes and chooses which of the two strategies above will be used in the main loop, based on the char c. This extra branch adds some overhead (~5%) for length ~256, but is quickly amortized by the faster loop for larger sizes. Compared to __rawmemchr_power9, this version is ~20% faster for length < 256. Because of the optimized main loop, the improvement becomes ~35% for c != 0 and ~50% for c = 0 for strings longer than 256. Reviewed-by: Lucas A. M. Magalhaes <lamm@linux.ibm.com> Reviewed-by: Raphael M Zinsly <rzinsly@linux.ibm.com>
Diffstat (limited to 'sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c')
-rw-r--r--sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
index b123c6a..a92b674 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
@@ -258,6 +258,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL (i, name, rawmemchr,
#ifdef __LITTLE_ENDIAN__
IFUNC_IMPL_ADD (array, i, rawmemchr,
+ (hwcap2 & PPC_FEATURE2_ARCH_3_1)
+ && (hwcap & PPC_FEATURE_HAS_VSX),
+ __rawmemchr_power10)
+ IFUNC_IMPL_ADD (array, i, rawmemchr,
hwcap2 & PPC_FEATURE2_ARCH_3_00,
__rawmemchr_power9)
#endif