From patchwork Tue Feb 3 15:05:31 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zihong Yao X-Patchwork-Id: 129493 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 588CA4BA23C5 for ; Tue, 3 Feb 2026 15:17:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 588CA4BA23C5 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from cstnet.cn (smtp21.cstnet.cn [159.226.251.21]) by sourceware.org (Postfix) with ESMTPS id 2C00D4BA23C9 for ; Tue, 3 Feb 2026 15:14:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2C00D4BA23C9 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=isrc.iscas.ac.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=isrc.iscas.ac.cn ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 2C00D4BA23C9 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=159.226.251.21 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1770131701; cv=none; b=s/hpAq/yIRsOAxeRZ0A8UHMaC7BzLVME3NXgC/50BKO3mQkYjsvTVzN44qe0JQhQ7wsJ9cHdzzJiPYe+paGa5g+An0ZH4hkLAzJ2r1/B6L+tKBNfkUDkQAEbWR8hmQPcfPy5OQ4q3zRjl/afh672ss+bo7bHwu8dOc1gHDjNhwo= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1770131701; c=relaxed/simple; bh=utd76OyHo+rC0NJ4IZ1o8zS37Nm1dKqcQIXU1fq1oas=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=ZYFhQ53fYwb5RxKhby7r+iu1VttMxeBosfMKFDR55q5QnwWiSMROipd4sIrElMvTar9PsDFijuhkH+Ip7H/4BA50XeFPdel1Jhyf6BuTz3Rb8vxS1Rlb14V90qKzxsq/QggiWcXHkCU9SrWCjHVrTZPy34P+y3DMq3jpEz/aAGc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2C00D4BA23C9 Received: from Mobilestation.localdomain (unknown [183.6.59.140]) by APP-01 (Coremail) with SMTP id qwCowADHbmriEIJpZ2EVBw--.24930S9; Tue, 03 Feb 2026 23:14:51 +0800 (CST) From: Yao Zihong To: libc-alpha@sourceware.org Cc: adhemerval.zanella@linaro.org, andrew@sifive.com, schwab@linux-m68k.org, bergner@tenstorrent.com, jlaw@ventanamicro.com, zhangyin2018@iscas.ac.cn, enh@google.com, zihongyao@outlook.com, Yao Zihong , daichengrong Subject: [PATCH v5 07/18] riscv: Add RVV memrchr for multiarch and non-multiarch Date: Tue, 3 Feb 2026 23:05:31 +0800 Message-ID: <20260203151406.27450-8-zihong.plct@isrc.iscas.ac.cn> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260203151406.27450-1-zihong.plct@isrc.iscas.ac.cn> References: <20260203151406.27450-1-zihong.plct@isrc.iscas.ac.cn> MIME-Version: 1.0 X-CM-TRANSID: qwCowADHbmriEIJpZ2EVBw--.24930S9 X-Coremail-Antispam: 1UD129KBjvJXoWxKw1fuF4DurW5Gw4xWF4Durg_yoWfWr4fpF Z5uF15GFn3Cr1xWrWSgF1jv3W5tr95Gr1Yg34Y93yUJrWUJ397WFsFvw1rWFZ7ArWrC3y5 u3WDWFyqkFW8AaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUmI14x267AKxVWrJVCq3wAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2048vs2IY020E87I2jVAFwI0_JF0E3s1l82xGYI kIc2x26xkF7I0E14v26ryj6s0DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2 z4x0Y4vE2Ix0cI8IcVAFwI0_JFI_Gr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr 1UM28EF7xvwVC2z280aVAFwI0_Jr0_Gr1l84ACjcxK6I8E87Iv6xkF7I0E14v26r4j6r4U JwAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwACI402YVCY1x02628vn2 kIc2xKxwCY1x0262kKe7AKxVWUtVW8ZwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkE bVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67 AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUCVW8JwCI 42IY6xIIjxv20xvEc7CjxVAFwI0_Cr0_Gr1UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCw CI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnI WIevJa73UjIFyTuYvjfUOyIUUUUUU X-Originating-IP: [183.6.59.140] X-CM-SenderInfo: p2lk00vjoszunw6l223fol2u1dvotugofq/ X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_DNSWL_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_PASS, SPF_PASS, TXREP, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Co-authored-by: daichengrong Signed-off-by: Yao Zihong --- sysdeps/riscv/multiarch/memrchr-generic.c | 28 ++++++++ sysdeps/riscv/multiarch/memrchr-vector.S | 28 ++++++++ sysdeps/riscv/rvv/memrchr.S | 71 +++++++++++++++++++ .../unix/sysv/linux/riscv/multiarch/Makefile | 3 + .../linux/riscv/multiarch/ifunc-impl-list.c | 5 ++ .../unix/sysv/linux/riscv/multiarch/memrchr.c | 50 +++++++++++++ 6 files changed, 185 insertions(+) create mode 100644 sysdeps/riscv/multiarch/memrchr-generic.c create mode 100644 sysdeps/riscv/multiarch/memrchr-vector.S create mode 100644 sysdeps/riscv/rvv/memrchr.S create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memrchr.c diff --git a/sysdeps/riscv/multiarch/memrchr-generic.c b/sysdeps/riscv/multiarch/memrchr-generic.c new file mode 100644 index 0000000000..09766ac565 --- /dev/null +++ b/sysdeps/riscv/multiarch/memrchr-generic.c @@ -0,0 +1,28 @@ +/* Re-include the default memrchr implementation. + 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 + . */ + +#include + +#if IS_IN(libc) +# define MEMRCHR __memrchr_generic +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(name) +# undef weak_alias +# define weak_alias(a, b) +# include +#endif diff --git a/sysdeps/riscv/multiarch/memrchr-vector.S b/sysdeps/riscv/multiarch/memrchr-vector.S new file mode 100644 index 0000000000..1554c066aa --- /dev/null +++ b/sysdeps/riscv/multiarch/memrchr-vector.S @@ -0,0 +1,28 @@ +/* Re-include the RISC-V RVV based memrchr implementation. + 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 + . */ + +#if IS_IN(libc) +# define MEMRCHR __memrchr_vector +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(name) +# undef libc_hidden_def +# define libc_hidden_def(name) +# undef weak_alias +# define weak_alias(name, alias) +# include +#endif diff --git a/sysdeps/riscv/rvv/memrchr.S b/sysdeps/riscv/rvv/memrchr.S new file mode 100644 index 0000000000..00df77e5d7 --- /dev/null +++ b/sysdeps/riscv/rvv/memrchr.S @@ -0,0 +1,71 @@ +/* RISC-V RVV based memrchr. + 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 + . */ + +#include +#include + +#ifndef MEMRCHR +# define MEMRCHR __memrchr +#endif + +#define src a0 +#define ch a1 +#define num a2 +#define vl a3 +#define first_idx a4 +#define idx a5 + +#define vmask v0 +#define vdata v8 +#define vidx v16 +#define vmax v24 + +ENTRY (MEMRCHR) +.option push +.option arch, +v + add src, src, num +L(loop): + beqz num, L(nohit) + + vsetvli vl, num, e8, m4, ta, ma + sub src, src, vl + vle8.v vdata, (src) + sub num, num, vl + + vmseq.vx vmask, vdata, ch + vfirst.m first_idx, vmask + bltz first_idx, L(loop) +L(hit): + vsetvli zero, vl, e16, m8, ta, ma + vid.v vidx + + /* reduce max index over hit lanes */ + vmv.s.x vmax, x0 + vredmaxu.vs vmax, vidx, vmax, vmask.t + vmv.x.s idx, vmax + + add a0, src, idx + ret +L(nohit): + li a0, 0 + ret +.option pop +END (MEMRCHR) +libc_hidden_def (MEMRCHR) +weak_alias (MEMRCHR, memrchr) +libc_hidden_builtin_def (memrchr) diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile index a0990c9ff1..190e853e6e 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile @@ -19,6 +19,9 @@ sysdep_routines += \ memmove \ memmove-generic \ memmove-vector \ + memrchr \ + memrchr-generic \ + memrchr-vector \ memset \ memset-generic \ memset-vector \ diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c b/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c index d955f56dba..53e76705df 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c @@ -80,5 +80,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, __memmove_vector) IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_generic)) + IFUNC_IMPL (i, name, memrchr, + IFUNC_IMPL_ADD (array, i, memrchr, rvv_enabled, + __memrchr_vector) + IFUNC_IMPL_ADD (array, i, memrchr, 1, __memrchr_generic)) + return 0; } diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memrchr.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memrchr.c new file mode 100644 index 0000000000..310b8e14f0 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memrchr.c @@ -0,0 +1,50 @@ +/* Multiple versions of memrchr. + All versions must be listed in ifunc-impl-list.c. + 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 + . */ + +#if IS_IN (libc) +/* Redefine memrchr so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# define memrchr __redirect_memrchr +# include +# include +# undef memrchr +# include +# include +# include + +extern __typeof (__redirect_memrchr) __memrchr_generic attribute_hidden; +extern __typeof (__redirect_memrchr) __memrchr_vector attribute_hidden; + +static inline __typeof (__redirect_memrchr) * +select_memrchr_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) +{ + unsigned long long v; + + if (__riscv_hwprobe_one (hwprobe_func, RISCV_HWPROBE_KEY_IMA_EXT_0, &v) == 0 + && (v & RISCV_HWPROBE_IMA_V) == RISCV_HWPROBE_IMA_V) + return __memrchr_vector; + return __memrchr_generic; +} + +riscv_libc_ifunc_redirected (__redirect_memrchr, __memrchr, select_memrchr_ifunc); +libc_hidden_def (__memrchr) +weak_alias (__memrchr, memrchr) +#else +# include +#endif