diff options
Diffstat (limited to 'Loongarch-Add-ifunc-support-for-strchr-aligned-lsx-l.patch')
-rw-r--r-- | Loongarch-Add-ifunc-support-for-strchr-aligned-lsx-l.patch | 706 |
1 files changed, 706 insertions, 0 deletions
diff --git a/Loongarch-Add-ifunc-support-for-strchr-aligned-lsx-l.patch b/Loongarch-Add-ifunc-support-for-strchr-aligned-lsx-l.patch new file mode 100644 index 0000000..03e1299 --- /dev/null +++ b/Loongarch-Add-ifunc-support-for-strchr-aligned-lsx-l.patch @@ -0,0 +1,706 @@ +From aca7d7f0dde5f56344e8e58e5f6648c96bb1f1cc Mon Sep 17 00:00:00 2001 +From: dengjianbo <dengjianbo@loongson.cn> +Date: Tue, 15 Aug 2023 09:08:11 +0800 +Subject: [PATCH 06/29] Loongarch: Add ifunc support for strchr{aligned, lsx, + lasx} and strchrnul{aligned, lsx, lasx} + +These implementations improve the time to run strchr{nul} +microbenchmark in glibc as below: +strchr-lasx reduces the runtime about 50%-83% +strchr-lsx reduces the runtime about 30%-67% +strchr-aligned reduces the runtime about 10%-20% +strchrnul-lasx reduces the runtime about 50%-83% +strchrnul-lsx reduces the runtime about 36%-65% +strchrnul-aligned reduces the runtime about 6%-10% + +Signed-off-by: Peng Fan <fanpeng@loongson.cn> +Signed-off-by: ticat_fp <fanpeng@loongson.cn> +--- + sysdeps/loongarch/lp64/multiarch/Makefile | 6 ++ + .../lp64/multiarch/ifunc-impl-list.c | 16 +++ + .../loongarch/lp64/multiarch/ifunc-strchr.h | 41 ++++++++ + .../lp64/multiarch/ifunc-strchrnul.h | 41 ++++++++ + .../loongarch/lp64/multiarch/strchr-aligned.S | 99 +++++++++++++++++++ + .../loongarch/lp64/multiarch/strchr-lasx.S | 91 +++++++++++++++++ + sysdeps/loongarch/lp64/multiarch/strchr-lsx.S | 73 ++++++++++++++ + sysdeps/loongarch/lp64/multiarch/strchr.c | 36 +++++++ + .../lp64/multiarch/strchrnul-aligned.S | 95 ++++++++++++++++++ + .../loongarch/lp64/multiarch/strchrnul-lasx.S | 22 +++++ + .../loongarch/lp64/multiarch/strchrnul-lsx.S | 22 +++++ + sysdeps/loongarch/lp64/multiarch/strchrnul.c | 39 ++++++++ + 12 files changed, 581 insertions(+) + create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-strchr.h + create mode 100644 sysdeps/loongarch/lp64/multiarch/ifunc-strchrnul.h + create mode 100644 sysdeps/loongarch/lp64/multiarch/strchr-aligned.S + create mode 100644 sysdeps/loongarch/lp64/multiarch/strchr-lasx.S + create mode 100644 sysdeps/loongarch/lp64/multiarch/strchr-lsx.S + create mode 100644 sysdeps/loongarch/lp64/multiarch/strchr.c + create mode 100644 sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S + create mode 100644 sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S + create mode 100644 sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S + create mode 100644 sysdeps/loongarch/lp64/multiarch/strchrnul.c + +diff --git a/sysdeps/loongarch/lp64/multiarch/Makefile b/sysdeps/loongarch/lp64/multiarch/Makefile +index 76c506c9..110a8c5c 100644 +--- a/sysdeps/loongarch/lp64/multiarch/Makefile ++++ b/sysdeps/loongarch/lp64/multiarch/Makefile +@@ -3,5 +3,11 @@ sysdep_routines += \ + strlen-aligned \ + strlen-lsx \ + strlen-lasx \ ++ strchr-aligned \ ++ strchr-lsx \ ++ strchr-lasx \ ++ strchrnul-aligned \ ++ strchrnul-lsx \ ++ strchrnul-lasx \ + # sysdep_routines + endif +diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c +index 1a2a576f..c7164b45 100644 +--- a/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-impl-list.c +@@ -37,5 +37,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + #endif + IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_aligned) + ) ++ ++ IFUNC_IMPL (i, name, strchr, ++#if !defined __loongarch_soft_float ++ IFUNC_IMPL_ADD (array, i, strchr, SUPPORT_LASX, __strchr_lasx) ++ IFUNC_IMPL_ADD (array, i, strchr, SUPPORT_LSX, __strchr_lsx) ++#endif ++ IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_aligned) ++ ) ++ ++ IFUNC_IMPL (i, name, strchrnul, ++#if !defined __loongarch_soft_float ++ IFUNC_IMPL_ADD (array, i, strchrnul, SUPPORT_LASX, __strchrnul_lasx) ++ IFUNC_IMPL_ADD (array, i, strchrnul, SUPPORT_LSX, __strchrnul_lsx) ++#endif ++ IFUNC_IMPL_ADD (array, i, strchrnul, 1, __strchrnul_aligned) ++ ) + return i; + } +diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-strchr.h b/sysdeps/loongarch/lp64/multiarch/ifunc-strchr.h +new file mode 100644 +index 00000000..4494db79 +--- /dev/null ++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-strchr.h +@@ -0,0 +1,41 @@ ++/* Common definition for strchr ifunc selections. ++ All versions must be listed in ifunc-impl-list.c. ++ Copyright (C) 2023 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 <ldsodefs.h> ++#include <ifunc-init.h> ++ ++#if !defined __loongarch_soft_float ++extern __typeof (REDIRECT_NAME) OPTIMIZE (lasx) attribute_hidden; ++extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden; ++#endif ++ ++extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden; ++ ++static inline void * ++IFUNC_SELECTOR (void) ++{ ++#if !defined __loongarch_soft_float ++ if (SUPPORT_LASX) ++ return OPTIMIZE (lasx); ++ else if (SUPPORT_LSX) ++ return OPTIMIZE (lsx); ++ else ++#endif ++ return OPTIMIZE (aligned); ++} +diff --git a/sysdeps/loongarch/lp64/multiarch/ifunc-strchrnul.h b/sysdeps/loongarch/lp64/multiarch/ifunc-strchrnul.h +new file mode 100644 +index 00000000..8a925120 +--- /dev/null ++++ b/sysdeps/loongarch/lp64/multiarch/ifunc-strchrnul.h +@@ -0,0 +1,41 @@ ++/* Common definition for strchrnul ifunc selections. ++ All versions must be listed in ifunc-impl-list.c. ++ Copyright (C) 2023 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 <ldsodefs.h> ++#include <ifunc-init.h> ++ ++#if !defined __loongarch_soft_float ++extern __typeof (REDIRECT_NAME) OPTIMIZE (lasx) attribute_hidden; ++extern __typeof (REDIRECT_NAME) OPTIMIZE (lsx) attribute_hidden; ++#endif ++ ++extern __typeof (REDIRECT_NAME) OPTIMIZE (aligned) attribute_hidden; ++ ++static inline void * ++IFUNC_SELECTOR (void) ++{ ++#if !defined __loongarch_soft_float ++ if (SUPPORT_LASX) ++ return OPTIMIZE (lasx); ++ else if (SUPPORT_LSX) ++ return OPTIMIZE (lsx); ++ else ++#endif ++ return OPTIMIZE (aligned); ++} +diff --git a/sysdeps/loongarch/lp64/multiarch/strchr-aligned.S b/sysdeps/loongarch/lp64/multiarch/strchr-aligned.S +new file mode 100644 +index 00000000..5fb01806 +--- /dev/null ++++ b/sysdeps/loongarch/lp64/multiarch/strchr-aligned.S +@@ -0,0 +1,99 @@ ++/* Optimized strchr implementation using basic Loongarch instructions. ++ Copyright (C) 2023 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> ++#include <sys/regdef.h> ++#include <sys/asm.h> ++ ++#if IS_IN (libc) ++# define STRCHR_NAME __strchr_aligned ++#else ++# define STRCHR_NAME strchr ++#endif ++ ++LEAF(STRCHR_NAME, 6) ++ slli.d t1, a0, 3 ++ bstrins.d a0, zero, 2, 0 ++ lu12i.w a2, 0x01010 ++ ld.d t2, a0, 0 ++ ++ ori a2, a2, 0x101 ++ andi a1, a1, 0xff ++ bstrins.d a2, a2, 63, 32 ++ li.w t0, -1 ++ ++ mul.d a1, a1, a2 ++ sll.d t0, t0, t1 ++ slli.d a3, a2, 7 ++ orn t2, t2, t0 ++ ++ sll.d t3, a1, t1 ++ xor t4, t2, t3 ++ sub.d a4, t2, a2 ++ sub.d a5, t4, a2 ++ ++ ++ andn a4, a4, t2 ++ andn a5, a5, t4 ++ or t0, a4, a5 ++ and t0, t0, a3 ++ ++ bnez t0, L(end) ++ addi.d a0, a0, 8 ++L(loop): ++ ld.d t4, a0, 0 ++ xor t2, t4, a1 ++ ++ sub.d a4, t4, a2 ++ sub.d a5, t2, a2 ++ andn a4, a4, t4 ++ andn a5, a5, t2 ++ ++ or t0, a4, a5 ++ and t0, t0, a3 ++ bnez t0, L(end) ++ ld.d t4, a0, 8 ++ ++ ++ addi.d a0, a0, 16 ++ xor t2, t4, a1 ++ sub.d a4, t4, a2 ++ sub.d a5, t2, a2 ++ ++ andn a4, a4, t4 ++ andn a5, a5, t2 ++ or t0, a4, a5 ++ and t0, t0, a3 ++ ++ beqz t0, L(loop) ++ addi.d a0, a0, -8 ++L(end): ++ and t0, a5, a3 ++ and t1, a4, a3 ++ ++ ctz.d t0, t0 ++ ctz.d t1, t1 ++ srli.w t2, t0, 3 ++ sltu t3, t1, t0 ++ ++ ++ add.d a0, a0, t2 ++ masknez a0, a0, t3 ++ jr ra ++END(STRCHR_NAME) +diff --git a/sysdeps/loongarch/lp64/multiarch/strchr-lasx.S b/sysdeps/loongarch/lp64/multiarch/strchr-lasx.S +new file mode 100644 +index 00000000..254402da +--- /dev/null ++++ b/sysdeps/loongarch/lp64/multiarch/strchr-lasx.S +@@ -0,0 +1,91 @@ ++/* Optimized strchr implementation using loongarch LASX SIMD instructions. ++ Copyright (C) 2023 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> ++#include <sys/regdef.h> ++#include <sys/asm.h> ++ ++#if IS_IN (libc) && !defined __loongarch_soft_float ++ ++#ifndef AS_STRCHRNUL ++# define STRCHR __strchr_lasx ++#endif ++ ++LEAF(STRCHR, 6) ++ andi t1, a0, 0x1f ++ bstrins.d a0, zero, 4, 0 ++ xvld xr0, a0, 0 ++ li.d t2, -1 ++ ++ xvreplgr2vr.b xr1, a1 ++ sll.d t1, t2, t1 ++ xvxor.v xr2, xr0, xr1 ++ xvmin.bu xr0, xr0, xr2 ++ ++ xvmsknz.b xr0, xr0 ++ xvpickve.w xr3, xr0, 4 ++ vilvl.h vr0, vr3, vr0 ++ movfr2gr.s t0, fa0 ++ ++ orn t0, t0, t1 ++ bne t0, t2, L(end) ++ addi.d a0, a0, 32 ++ nop ++ ++ ++L(loop): ++ xvld xr0, a0, 0 ++ xvxor.v xr2, xr0, xr1 ++ xvmin.bu xr0, xr0, xr2 ++ xvsetanyeqz.b fcc0, xr0 ++ ++ bcnez fcc0, L(loop_end) ++ xvld xr0, a0, 32 ++ addi.d a0, a0, 64 ++ xvxor.v xr2, xr0, xr1 ++ ++ xvmin.bu xr0, xr0, xr2 ++ xvsetanyeqz.b fcc0, xr0 ++ bceqz fcc0, L(loop) ++ addi.d a0, a0, -32 ++ ++L(loop_end): ++ xvmsknz.b xr0, xr0 ++ xvpickve.w xr1, xr0, 4 ++ vilvl.h vr0, vr1, vr0 ++ movfr2gr.s t0, fa0 ++ ++ ++L(end): ++ cto.w t0, t0 ++ add.d a0, a0, t0 ++#ifndef AS_STRCHRNUL ++ vreplgr2vr.b vr0, t0 ++ xvpermi.q xr3, xr2, 1 ++ ++ vshuf.b vr0, vr3, vr2, vr0 ++ vpickve2gr.bu t0, vr0, 0 ++ masknez a0, a0, t0 ++#endif ++ jr ra ++ ++END(STRCHR) ++ ++libc_hidden_builtin_def(STRCHR) ++#endif +diff --git a/sysdeps/loongarch/lp64/multiarch/strchr-lsx.S b/sysdeps/loongarch/lp64/multiarch/strchr-lsx.S +new file mode 100644 +index 00000000..dae98b0a +--- /dev/null ++++ b/sysdeps/loongarch/lp64/multiarch/strchr-lsx.S +@@ -0,0 +1,73 @@ ++/* Optimized strlen implementation using loongarch LSX SIMD instructions. ++ Copyright (C) 2023 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> ++#include <sys/regdef.h> ++#include <sys/asm.h> ++ ++#if IS_IN (libc) && !defined __loongarch_soft_float ++ ++#ifndef AS_STRCHRNUL ++# define STRCHR __strchr_lsx ++#endif ++ ++LEAF(STRCHR, 6) ++ andi t1, a0, 0xf ++ bstrins.d a0, zero, 3, 0 ++ vld vr0, a0, 0 ++ li.d t2, -1 ++ ++ vreplgr2vr.b vr1, a1 ++ sll.d t3, t2, t1 ++ vxor.v vr2, vr0, vr1 ++ vmin.bu vr0, vr0, vr2 ++ ++ vmsknz.b vr0, vr0 ++ movfr2gr.s t0, fa0 ++ ext.w.h t0, t0 ++ orn t0, t0, t3 ++ ++ beq t0, t2, L(loop) ++L(found): ++ cto.w t0, t0 ++ add.d a0, a0, t0 ++#ifndef AS_STRCHRNUL ++ vreplve.b vr2, vr2, t0 ++ vpickve2gr.bu t1, vr2, 0 ++ masknez a0, a0, t1 ++#endif ++ jr ra ++ ++ ++L(loop): ++ vld vr0, a0, 16 ++ addi.d a0, a0, 16 ++ vxor.v vr2, vr0, vr1 ++ vmin.bu vr0, vr0, vr2 ++ ++ vsetanyeqz.b fcc0, vr0 ++ bceqz fcc0, L(loop) ++ vmsknz.b vr0, vr0 ++ movfr2gr.s t0, fa0 ++ ++ b L(found) ++END(STRCHR) ++ ++libc_hidden_builtin_def (STRCHR) ++#endif +diff --git a/sysdeps/loongarch/lp64/multiarch/strchr.c b/sysdeps/loongarch/lp64/multiarch/strchr.c +new file mode 100644 +index 00000000..404e97bd +--- /dev/null ++++ b/sysdeps/loongarch/lp64/multiarch/strchr.c +@@ -0,0 +1,36 @@ ++/* Multiple versions of strchr. ++ All versions must be listed in ifunc-impl-list.c. ++ Copyright (C) 2023 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) ++# define strchr __redirect_strchr ++# include <string.h> ++# undef strchr ++ ++# define SYMBOL_NAME strchr ++# include "ifunc-strchr.h" ++ ++libc_ifunc_redirected (__redirect_strchr, strchr, IFUNC_SELECTOR ()); ++weak_alias(strchr, index) ++# ifdef SHARED ++__hidden_ver1 (strchr, __GI_strchr, __redirect_strchr) ++ __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strchr); ++# endif ++ ++#endif +diff --git a/sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S b/sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S +new file mode 100644 +index 00000000..1c01a023 +--- /dev/null ++++ b/sysdeps/loongarch/lp64/multiarch/strchrnul-aligned.S +@@ -0,0 +1,95 @@ ++/* Optimized strchrnul implementation using basic Loongarch instructions. ++ Copyright (C) 2023 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> ++#include <sys/regdef.h> ++#include <sys/asm.h> ++ ++#if IS_IN (libc) ++# define STRCHRNUL_NAME __strchrnul_aligned ++#else ++# define STRCHRNUL_NAME __strchrnul ++#endif ++ ++LEAF(STRCHRNUL_NAME, 6) ++ slli.d t1, a0, 3 ++ bstrins.d a0, zero, 2, 0 ++ lu12i.w a2, 0x01010 ++ ld.d t2, a0, 0 ++ ++ ori a2, a2, 0x101 ++ andi a1, a1, 0xff ++ bstrins.d a2, a2, 63, 32 ++ li.w t0, -1 ++ ++ mul.d a1, a1, a2 ++ sll.d t0, t0, t1 ++ slli.d a3, a2, 7 ++ orn t2, t2, t0 ++ ++ sll.d t3, a1, t1 ++ xor t4, t2, t3 ++ sub.d a4, t2, a2 ++ sub.d a5, t4, a2 ++ ++ ++ andn a4, a4, t2 ++ andn a5, a5, t4 ++ or t0, a4, a5 ++ and t0, t0, a3 ++ ++ bnez t0, L(end) ++ addi.d a0, a0, 8 ++L(loop): ++ ld.d t4, a0, 0 ++ xor t2, t4, a1 ++ ++ sub.d a4, t4, a2 ++ sub.d a5, t2, a2 ++ andn a4, a4, t4 ++ andn a5, a5, t2 ++ ++ or t0, a4, a5 ++ and t0, t0, a3 ++ bnez t0, L(end) ++ ld.d t4, a0, 8 ++ ++ ++ addi.d a0, a0, 16 ++ xor t2, t4, a1 ++ sub.d a4, t4, a2 ++ sub.d a5, t2, a2 ++ ++ andn a4, a4, t4 ++ andn a5, a5, t2 ++ or t0, a4, a5 ++ and t0, t0, a3 ++ ++ beqz t0, L(loop) ++ addi.d a0, a0, -8 ++L(end): ++ ctz.d t0, t0 ++ srli.w t0, t0, 3 ++ ++ ++ add.d a0, a0, t0 ++ jr ra ++END(STRCHRNUL_NAME) ++ ++libc_hidden_builtin_def (STRCHRNUL_NAME) +diff --git a/sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S b/sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S +new file mode 100644 +index 00000000..d45495e4 +--- /dev/null ++++ b/sysdeps/loongarch/lp64/multiarch/strchrnul-lasx.S +@@ -0,0 +1,22 @@ ++/* Optimized strchrnul implementation using loongarch LASX SIMD instructions. ++ Copyright (C) 2023 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 STRCHR __strchrnul_lasx ++#define AS_STRCHRNUL ++#include "strchr-lasx.S" +diff --git a/sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S b/sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S +new file mode 100644 +index 00000000..07d793ae +--- /dev/null ++++ b/sysdeps/loongarch/lp64/multiarch/strchrnul-lsx.S +@@ -0,0 +1,22 @@ ++/* Optimized strchrnul implementation using loongarch LSX SIMD instructions. ++ Copyright (C) 2023 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 STRCHR __strchrnul_lsx ++#define AS_STRCHRNUL ++#include "strchr-lsx.S" +diff --git a/sysdeps/loongarch/lp64/multiarch/strchrnul.c b/sysdeps/loongarch/lp64/multiarch/strchrnul.c +new file mode 100644 +index 00000000..f3b8296e +--- /dev/null ++++ b/sysdeps/loongarch/lp64/multiarch/strchrnul.c +@@ -0,0 +1,39 @@ ++/* Multiple versions of strchrnul. ++ All versions must be listed in ifunc-impl-list.c. ++ Copyright (C) 2023 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 ++ <http://www.gnu.org/licenses/>. */ ++ ++/* Define multiple versions only for the definition in libc. */ ++ ++#if IS_IN (libc) ++# define strchrnul __redirect_strchrnul ++# define __strchrnul __redirect___strchrnul ++# include <string.h> ++# undef __strchrnul ++# undef strchrnul ++ ++# define SYMBOL_NAME strchrnul ++# include "ifunc-strchrnul.h" ++ ++libc_ifunc_redirected (__redirect_strchrnul, __strchrnul, ++ IFUNC_SELECTOR ()); ++weak_alias (__strchrnul, strchrnul) ++# ifdef SHARED ++__hidden_ver1 (__strchrnul, __GI___strchrnul, __redirect_strchrnul) ++ __attribute__((visibility ("hidden"))) __attribute_copy__ (strchrnul); ++# endif ++#endif +-- +2.33.0 + |