From patchwork Tue Sep 23 11:23:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Zihong X-Patchwork-Id: 120692 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7BA09385841D for ; Tue, 23 Sep 2025 11:33:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7BA09385841D X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from cstnet.cn (smtp84.cstnet.cn [159.226.251.84]) by sourceware.org (Postfix) with ESMTPS id D35DC3858D29 for ; Tue, 23 Sep 2025 11:32:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D35DC3858D29 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 D35DC3858D29 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=159.226.251.84 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758627151; cv=none; b=yCx+QniPOX8Ku0noKi8+mD0sLlQBs7qw4ir4YqrC2BI2u3HWFfbqY8wdIrwsHa55YuruxIUUn2Er9AEBqFVb2gXzoP6gIP332qjNUFmo3lS1TAdU7A52NFXIAhdJCICsCPW5CsBk7Rfe8brF8eYiuNSh6StOAzYJCLc60I/+YvA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758627151; c=relaxed/simple; bh=x4iSxk/jZnCeN+IO+H5Pm14cbSR0mixDUzNwMwAU9E8=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=tWcL8xKbx/wLZ9ZWciwavEePoLqTkTW6NOYksIQNPjYuT9WChQCQLMgdfSaYbcdstD6nrjCYl4OAckY3D4Xb8wCkOoHGMyv7FAU5MvFMnbXnz3SPZbSj4TiVOOCY11hBAmvAOpOR5EQSK4q7p6ZIliAEx2Ez5s01U34GdP00Jg8= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D35DC3858D29 Received: from Mobilestation.localdomain (unknown [183.6.59.140]) by APP-05 (Coremail) with SMTP id zQCowAAXuhMZhdJoVxd9BA--.14410S3; Tue, 23 Sep 2025 19:31:53 +0800 (CST) From: Yao Zihong To: libc-alpha@sourceware.org Cc: Wilco.Dijkstra@arm.com, andrew@sifive.com, bergner@tenstorrent.com, carlos@redhat.com, dj@redhat.com, evan@rivosinc.com, jlaw@ventanamicro.com, palmer@dabbelt.com, vineetg@rivosinc.com, zhangyin2018@iscas.ac.cn, yun.hsiang@sifive.com, hau.hsu@sifive.com, jerry.shih@sifive.com, nick.knight@sifive.com, zihong.plct@isrc.iscas.ac.cn, zihongyao@outlook.com Subject: [PATCH v1 1/4] riscv: Add multiarch scaffolding for str*/mem* routines Date: Tue, 23 Sep 2025 19:23:09 +0800 Message-ID: <20250923112338.77162-2-zihong.plct@isrc.iscas.ac.cn> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250923112338.77162-1-zihong.plct@isrc.iscas.ac.cn> References: <20250923112338.77162-1-zihong.plct@isrc.iscas.ac.cn> MIME-Version: 1.0 X-CM-TRANSID: zQCowAAXuhMZhdJoVxd9BA--.14410S3 X-Coremail-Antispam: 1UD129KBjv3XoW7tF4kZrW7Ww1UtoXrpF1xuFyxpFZ5u3W5CF 4kJr4xGrWS93Wj93W5JFs5Jr15KryY9w4UJw4DXrWxXFZ2qws7GFyxJrWru3y5ZFs8WFyD CF48ZaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy29KBjDU0x BIdaVrnRJUUUQ0b7Iv0xC_Kw4lb4IE77IF4wAFF20E14v26rWj6s0DM7CY07I20VC2zVCF 04k26cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxV WUGwA2048vs2IY020Ec7CjxVAFwI0_Gr0_Xr1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0 rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVWUJVWUCwA2z4x0Y4vE2Ix0cI8IcVCY1x0267 AKxVW8JVWxJwA2z4x0Y4vEx4A2jsIE14v26r1j6r4UM28EF7xvwVC2z280aVCY1x0267AK xVW8JVW8Jr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2 WlYx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkE bVWUJVW8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxcIEc7 CjxVA2Y2ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wryl42xK82IYc2Ij64vIr41l4I8I3I0E 4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGV WUWwC2zVAF1VAY17CE14v26r4a6rW5MIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_ Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0xvE42xK8VAvwI8IcIk0rV WUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4U JbIYCTnIWIevJa73UjIFyTuYvjxU2BMNUUUUU X-Originating-IP: [183.6.59.140] X-CM-SenderInfo: p2lk00vjoszunw6l223fol2u1dvotugofq/ X-Spam-Status: No, score=-6.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, INDUSTRIAL_BODY, INDUSTRIAL_SUBJECT, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.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 This patch introduces the RISC-V multiarch/IFUNC scaffolding for the str* and mem* routines: memchr, memcmp, __memcmpeq, memmove, memset strcat, strchr, strcmp, strcpy, strlen, strncat, strncmp, strncpy, strnlen It adds per-function IFUNC resolvers and generic re-exports, but all resolvers deliberately select the generic implementations at this stage. There is no functional change. Signed-off-by: Yao Zihong --- sysdeps/riscv/multiarch/memchr-generic.c | 24 +++++++++ sysdeps/riscv/multiarch/memcmp-generic.c | 31 +++++++++++ sysdeps/riscv/multiarch/memcmpeq-generic.c | 31 +++++++++++ sysdeps/riscv/multiarch/memmove-generic.c | 26 +++++++++ sysdeps/riscv/multiarch/memset-generic.c | 26 +++++++++ sysdeps/riscv/multiarch/strcat-generic.c | 26 +++++++++ sysdeps/riscv/multiarch/strchr-generic.c | 24 +++++++++ sysdeps/riscv/multiarch/strcmp-generic.c | 24 +++++++++ sysdeps/riscv/multiarch/strcpy-generic.c | 26 +++++++++ sysdeps/riscv/multiarch/strlen-generic.c | 24 +++++++++ sysdeps/riscv/multiarch/strncat-generic.c | 26 +++++++++ sysdeps/riscv/multiarch/strncmp-generic.c | 26 +++++++++ sysdeps/riscv/multiarch/strncpy-generic.c | 26 +++++++++ sysdeps/riscv/multiarch/strnlen-generic.c | 24 +++++++++ .../unix/sysv/linux/riscv/multiarch/Makefile | 28 ++++++++++ .../linux/riscv/multiarch/ifunc-impl-list.c | 38 ++++++++++++- .../unix/sysv/linux/riscv/multiarch/memchr.c | 52 ++++++++++++++++++ .../unix/sysv/linux/riscv/multiarch/memcmp.c | 54 +++++++++++++++++++ .../sysv/linux/riscv/multiarch/memcmpeq.c | 50 +++++++++++++++++ .../unix/sysv/linux/riscv/multiarch/memmove.c | 52 ++++++++++++++++++ .../unix/sysv/linux/riscv/multiarch/memset.c | 52 ++++++++++++++++++ .../unix/sysv/linux/riscv/multiarch/strcat.c | 52 ++++++++++++++++++ .../unix/sysv/linux/riscv/multiarch/strchr.c | 54 +++++++++++++++++++ .../unix/sysv/linux/riscv/multiarch/strcmp.c | 52 ++++++++++++++++++ .../unix/sysv/linux/riscv/multiarch/strcpy.c | 52 ++++++++++++++++++ .../unix/sysv/linux/riscv/multiarch/strlen.c | 52 ++++++++++++++++++ .../unix/sysv/linux/riscv/multiarch/strncat.c | 52 ++++++++++++++++++ .../unix/sysv/linux/riscv/multiarch/strncmp.c | 52 ++++++++++++++++++ .../unix/sysv/linux/riscv/multiarch/strncpy.c | 52 ++++++++++++++++++ .../unix/sysv/linux/riscv/multiarch/strnlen.c | 54 +++++++++++++++++++ 30 files changed, 1161 insertions(+), 1 deletion(-) create mode 100644 sysdeps/riscv/multiarch/memchr-generic.c create mode 100644 sysdeps/riscv/multiarch/memcmp-generic.c create mode 100644 sysdeps/riscv/multiarch/memcmpeq-generic.c create mode 100644 sysdeps/riscv/multiarch/memmove-generic.c create mode 100644 sysdeps/riscv/multiarch/memset-generic.c create mode 100644 sysdeps/riscv/multiarch/strcat-generic.c create mode 100644 sysdeps/riscv/multiarch/strchr-generic.c create mode 100644 sysdeps/riscv/multiarch/strcmp-generic.c create mode 100644 sysdeps/riscv/multiarch/strcpy-generic.c create mode 100644 sysdeps/riscv/multiarch/strlen-generic.c create mode 100644 sysdeps/riscv/multiarch/strncat-generic.c create mode 100644 sysdeps/riscv/multiarch/strncmp-generic.c create mode 100644 sysdeps/riscv/multiarch/strncpy-generic.c create mode 100644 sysdeps/riscv/multiarch/strnlen-generic.c create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memchr.c create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memcmp.c create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memcmpeq.c create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memmove.c create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/memset.c create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strcat.c create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strchr.c create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strcmp.c create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strcpy.c create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strncat.c create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strncmp.c create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strncpy.c create mode 100644 sysdeps/unix/sysv/linux/riscv/multiarch/strnlen.c diff --git a/sysdeps/riscv/multiarch/memchr-generic.c b/sysdeps/riscv/multiarch/memchr-generic.c new file mode 100644 index 0000000000..b708170584 --- /dev/null +++ b/sysdeps/riscv/multiarch/memchr-generic.c @@ -0,0 +1,24 @@ +/* Re-include the default memchr implementation. + Copyright (C) 2025 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 MEMCHR __memchr_generic +#endif +#include diff --git a/sysdeps/riscv/multiarch/memcmp-generic.c b/sysdeps/riscv/multiarch/memcmp-generic.c new file mode 100644 index 0000000000..73e7743b9b --- /dev/null +++ b/sysdeps/riscv/multiarch/memcmp-generic.c @@ -0,0 +1,31 @@ +/* Re-include the default memcmp implementation. + Copyright (C) 2025 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 MEMCMP __memcmp_generic +# undef libc_hidden_def +# define libc_hidden_def(x) +# undef weak_alias +# define weak_alias(x, x2) +# undef strong_alias +# define strong_alias(x, x2) +#endif + +#include diff --git a/sysdeps/riscv/multiarch/memcmpeq-generic.c b/sysdeps/riscv/multiarch/memcmpeq-generic.c new file mode 100644 index 0000000000..fad163c5aa --- /dev/null +++ b/sysdeps/riscv/multiarch/memcmpeq-generic.c @@ -0,0 +1,31 @@ +/* Re-include the default memcmp implementation. + Copyright (C) 2025 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 MEMCMP ____memcmpeq_generic +# undef libc_hidden_def +# define libc_hidden_def(x) +# undef weak_alias +# define weak_alias(x, x2) +# undef strong_alias +# define strong_alias(x, x2) +#endif + +#include diff --git a/sysdeps/riscv/multiarch/memmove-generic.c b/sysdeps/riscv/multiarch/memmove-generic.c new file mode 100644 index 0000000000..0f41a23fac --- /dev/null +++ b/sysdeps/riscv/multiarch/memmove-generic.c @@ -0,0 +1,26 @@ +/* Re-include the default memmove implementation. + Copyright (C) 2025 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 MEMMOVE __memmove_generic +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(x) +#endif +#include diff --git a/sysdeps/riscv/multiarch/memset-generic.c b/sysdeps/riscv/multiarch/memset-generic.c new file mode 100644 index 0000000000..c93bb43c8f --- /dev/null +++ b/sysdeps/riscv/multiarch/memset-generic.c @@ -0,0 +1,26 @@ +/* Re-include the default memset implementation. + Copyright (C) 2025 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 MEMSET __memset_generic +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(x) +#endif +#include diff --git a/sysdeps/riscv/multiarch/strcat-generic.c b/sysdeps/riscv/multiarch/strcat-generic.c new file mode 100644 index 0000000000..60b4df8f8c --- /dev/null +++ b/sysdeps/riscv/multiarch/strcat-generic.c @@ -0,0 +1,26 @@ +/* Re-include the default strcat implementation. + Copyright (C) 2025 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 STRCAT __strcat_generic +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(x) +#endif +#include diff --git a/sysdeps/riscv/multiarch/strchr-generic.c b/sysdeps/riscv/multiarch/strchr-generic.c new file mode 100644 index 0000000000..ee7b084f3a --- /dev/null +++ b/sysdeps/riscv/multiarch/strchr-generic.c @@ -0,0 +1,24 @@ +/* Re-include the default strchr implementation. + Copyright (C) 2025 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 STRCHR __strchr_generic +#endif +#include diff --git a/sysdeps/riscv/multiarch/strcmp-generic.c b/sysdeps/riscv/multiarch/strcmp-generic.c new file mode 100644 index 0000000000..17c81dac20 --- /dev/null +++ b/sysdeps/riscv/multiarch/strcmp-generic.c @@ -0,0 +1,24 @@ +/* Re-include the default strcmp implementation. + Copyright (C) 2025 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 STRCMP __strcmp_generic +#endif +#include diff --git a/sysdeps/riscv/multiarch/strcpy-generic.c b/sysdeps/riscv/multiarch/strcpy-generic.c new file mode 100644 index 0000000000..72901d49d6 --- /dev/null +++ b/sysdeps/riscv/multiarch/strcpy-generic.c @@ -0,0 +1,26 @@ +/* Re-include the default strcpy implementation. + Copyright (C) 2025 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 STRCPY __strcpy_generic +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(x) +#endif +#include diff --git a/sysdeps/riscv/multiarch/strlen-generic.c b/sysdeps/riscv/multiarch/strlen-generic.c new file mode 100644 index 0000000000..5b45836e9e --- /dev/null +++ b/sysdeps/riscv/multiarch/strlen-generic.c @@ -0,0 +1,24 @@ +/* Re-include the default strlen implementation. + Copyright (C) 2025 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 STRLEN __strlen_generic +#endif +#include diff --git a/sysdeps/riscv/multiarch/strncat-generic.c b/sysdeps/riscv/multiarch/strncat-generic.c new file mode 100644 index 0000000000..18d1e00756 --- /dev/null +++ b/sysdeps/riscv/multiarch/strncat-generic.c @@ -0,0 +1,26 @@ +/* Re-include the default strncat implementation. + Copyright (C) 2025 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 STRNCAT __strncat_generic +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(x) +#endif +#include diff --git a/sysdeps/riscv/multiarch/strncmp-generic.c b/sysdeps/riscv/multiarch/strncmp-generic.c new file mode 100644 index 0000000000..6477713a1c --- /dev/null +++ b/sysdeps/riscv/multiarch/strncmp-generic.c @@ -0,0 +1,26 @@ +/* Re-include the default strncmp implementation. + Copyright (C) 2025 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 STRNCMP __strncmp_generic +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(x) +#endif +#include diff --git a/sysdeps/riscv/multiarch/strncpy-generic.c b/sysdeps/riscv/multiarch/strncpy-generic.c new file mode 100644 index 0000000000..8833eddd5b --- /dev/null +++ b/sysdeps/riscv/multiarch/strncpy-generic.c @@ -0,0 +1,26 @@ +/* Re-include the default strncpy implementation. + Copyright (C) 2025 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 STRNCPY __strncpy_generic +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(x) +#endif +#include diff --git a/sysdeps/riscv/multiarch/strnlen-generic.c b/sysdeps/riscv/multiarch/strnlen-generic.c new file mode 100644 index 0000000000..20268bd444 --- /dev/null +++ b/sysdeps/riscv/multiarch/strnlen-generic.c @@ -0,0 +1,24 @@ +/* Re-include the default strnlen implementation. + Copyright (C) 2025 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 STRNLEN __strnlen_generic +#endif +#include diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile index fcef5659d4..9338db7f94 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile @@ -3,6 +3,34 @@ sysdep_routines += \ memcpy \ memcpy-generic \ memcpy_noalignment \ + memchr \ + memchr-generic \ + memcmp \ + memcmp-generic \ + memcmpeq \ + memcmpeq-generic \ + memmove \ + memmove-generic \ + memset \ + memset-generic \ + strcat \ + strcat-generic \ + strcmp \ + strcmp-generic \ + strcpy \ + strcpy-generic \ + strlen \ + strlen-generic \ + strnlen \ + strnlen-generic \ + strncat \ + strncat-generic \ + strncmp \ + strncmp-generic \ + strncpy \ + strncpy-generic \ + strchr \ + strchr-generic \ # sysdep_routines CFLAGS-memcpy_noalignment.c += -mno-strict-align 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 1c1deca8f6..567a16c723 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c @@ -35,9 +35,45 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, fast_unaligned = true; IFUNC_IMPL (i, name, memcpy, - IFUNC_IMPL_ADD (array, i, memcpy, fast_unaligned, + IFUNC_IMPL_ADD (array, i, memcpy, fast_unaligned, __memcpy_noalignment) IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_generic)) + + IFUNC_IMPL (i, name, memchr, + IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_generic)) + + IFUNC_IMPL (i, name, memmove, + IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_generic)) + + IFUNC_IMPL (i, name, memset, + IFUNC_IMPL_ADD (array, i, memset, 1, __memset_generic)) + + IFUNC_IMPL (i, name, strcat, + IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_generic)) + + IFUNC_IMPL (i, name, strcmp, + IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_generic)) + + IFUNC_IMPL (i, name, strcpy, + IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_generic)) + + IFUNC_IMPL (i, name, strlen, + IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_generic)) + + IFUNC_IMPL (i, name, strnlen, + IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_generic)) + + IFUNC_IMPL (i, name, strncat, + IFUNC_IMPL_ADD (array, i, strncat, 1, __strncat_generic)) + + IFUNC_IMPL (i, name, strncmp, + IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_generic)) + + IFUNC_IMPL (i, name, strncpy, + IFUNC_IMPL_ADD (array, i, strncpy, 1, __strncpy_generic)) + + IFUNC_IMPL (i, name, strchr, + IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_generic)) return 0; } diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memchr.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memchr.c new file mode 100644 index 0000000000..08a5f36e52 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memchr.c @@ -0,0 +1,52 @@ +/* Multiple versions of memchr. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2025 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 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 +# include +# include +# include +# include +# include + +extern __typeof (__redirect_memchr) __libc_memchr; + +extern __typeof (__redirect_memchr) __memchr_generic attribute_hidden; + +static inline __typeof (__redirect_memchr) * +select_memchr_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) +{ + return __memchr_generic; +} + +riscv_libc_ifunc (__libc_memchr, select_memchr_ifunc); + +# undef memchr +strong_alias (__libc_memchr, memchr); +# ifdef SHARED +__hidden_ver1 (memchr, __GI_memchr, __redirect_memchr) + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memchr); +# endif +#else +# include +#endif diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memcmp.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memcmp.c new file mode 100644 index 0000000000..13c86a8042 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memcmp.c @@ -0,0 +1,54 @@ +/* Multiple versions of memcmp. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2025 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 memcmp so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef memcmp +# define memcmp __redirect_memcmp +# include +# include +# include +# include +# include +# include + +extern __typeof (__redirect_memcmp) __libc_memcmp; + +extern __typeof (__redirect_memcmp) __memcmp_generic attribute_hidden; + +static inline __typeof (__redirect_memcmp) * +select_memcmp_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) +{ + return __memcmp_generic; +} + +riscv_libc_ifunc (__libc_memcmp, select_memcmp_ifunc); + +# undef memcmp +# undef bcmp +strong_alias (__libc_memcmp, memcmp); +weak_alias (memcmp, bcmp); +# ifdef SHARED +__hidden_ver1 (memcmp, __GI_memcmp, __redirect_memcmp) + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memcmp); +# endif +#else +# include +#endif diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memcmpeq.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memcmpeq.c new file mode 100644 index 0000000000..c963a2ee75 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memcmpeq.c @@ -0,0 +1,50 @@ +/* Multiple versions of memcmp. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2025 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 memcmp so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef __memcmpeq +# define __memcmpeq __redirect___memcmpeq +# include +# include +# include +# include +# include +# include + +extern __typeof (__redirect___memcmpeq) __libc___memcmpeq; + +extern __typeof (__redirect___memcmpeq) ____memcmpeq_generic attribute_hidden; + +static inline __typeof (__redirect___memcmpeq) * +select___memcmpeq_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) +{ + return ____memcmpeq_generic; +} + +riscv_libc_ifunc (__libc___memcmpeq, select___memcmpeq_ifunc); + +# undef __memcmpeq +strong_alias (__libc___memcmpeq, __memcmpeq); +# ifdef SHARED +__hidden_ver1 (__memcmpeq, __GI___memcmpeq, __redirect___memcmpeq) + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (__memcmpeq); +# endif +#endif diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memmove.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memmove.c new file mode 100644 index 0000000000..6aca93fd12 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memmove.c @@ -0,0 +1,52 @@ +/* Multiple versions of memmove. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2025 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 memmove so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef memmove +# define memmove __redirect_memmove +# include +# include +# include +# include +# include +# include + +extern __typeof (__redirect_memmove) __libc_memmove; + +extern __typeof (__redirect_memmove) __memmove_generic attribute_hidden; + +static inline __typeof (__redirect_memmove) * +select_memmove_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) +{ + return __memmove_generic; +} + +riscv_libc_ifunc (__libc_memmove, select_memmove_ifunc); + +# undef memmove +strong_alias (__libc_memmove, memmove); +# ifdef SHARED +__hidden_ver1 (memmove, __GI_memmove, __redirect_memmove) + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memmove); +# endif +#else +# include +#endif diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memset.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memset.c new file mode 100644 index 0000000000..07ebc59575 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memset.c @@ -0,0 +1,52 @@ +/* Multiple versions of memset. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2025 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 memset so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef memset +# define memset __redirect_memset +# include +# include +# include +# include +# include +# include + +extern __typeof (__redirect_memset) __libc_memset; + +extern __typeof (__redirect_memset) __memset_generic attribute_hidden; + +static inline __typeof (__redirect_memset) * +select_memset_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) +{ + return __memset_generic; +} + +riscv_libc_ifunc (__libc_memset, select_memset_ifunc); + +# undef memset +strong_alias (__libc_memset, memset); +# ifdef SHARED +__hidden_ver1 (memset, __GI_memset, __redirect_memset) + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (memset); +# endif +#else +# include +#endif diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strcat.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strcat.c new file mode 100644 index 0000000000..ca3254a018 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strcat.c @@ -0,0 +1,52 @@ +/* Multiple versions of strcat. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2025 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 strcat so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strcat +# define strcat __redirect_strcat +# include +# include +# include +# include +# include +# include + +extern __typeof (__redirect_strcat) __libc_strcat; + +extern __typeof (__redirect_strcat) __strcat_generic attribute_hidden; + +static inline __typeof (__redirect_strcat) * +select_strcat_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) +{ + return __strcat_generic; +} + +riscv_libc_ifunc (__libc_strcat, select_strcat_ifunc); + +# undef strcat +strong_alias (__libc_strcat, strcat); +# ifdef SHARED +__hidden_ver1 (strcat, __GI_strcat, __redirect_strcat) + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strcat); +# endif +#else +# include +#endif diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strchr.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strchr.c new file mode 100644 index 0000000000..a898f96bb8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strchr.c @@ -0,0 +1,54 @@ +/* Multiple versions of strchr. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2025 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 strchr so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strchr +# define strchr __redirect_strchr +# include +# include +# include +# include +# include +# include + +extern __typeof (__redirect_strchr) __libc_strchr; + +extern __typeof (__redirect_strchr) __strchr_generic attribute_hidden; + +static inline __typeof (__redirect_strchr) * +select_strchr_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) +{ + return __strchr_generic; +} + +riscv_libc_ifunc (__libc_strchr, select_strchr_ifunc); + +# undef strchr +# undef index +strong_alias (__libc_strchr, strchr); +weak_alias (strchr, index); +# ifdef SHARED +__hidden_ver1 (strchr, __GI_strchr, __redirect_strchr) + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strchr); +# endif +#else +# include +#endif diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strcmp.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strcmp.c new file mode 100644 index 0000000000..9fd5c530bd --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strcmp.c @@ -0,0 +1,52 @@ +/* Multiple versions of strcmp. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2025 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 strcmp so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strcmp +# define strcmp __redirect_strcmp +# include +# include +# include +# include +# include +# include + +extern __typeof (__redirect_strcmp) __libc_strcmp; + +extern __typeof (__redirect_strcmp) __strcmp_generic attribute_hidden; + +static inline __typeof (__redirect_strcmp) * +select_strcmp_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) +{ + return __strcmp_generic; +} + +riscv_libc_ifunc (__libc_strcmp, select_strcmp_ifunc); + +# undef strcmp +strong_alias (__libc_strcmp, strcmp); +# ifdef SHARED +__hidden_ver1 (strcmp, __GI_strcmp, __redirect_strcmp) + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strcmp); +# endif +#else +# include +#endif diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strcpy.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strcpy.c new file mode 100644 index 0000000000..473fa7768d --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strcpy.c @@ -0,0 +1,52 @@ +/* Multiple versions of strcpy. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2025 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 strcpy so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strcpy +# define strcpy __redirect_strcpy +# include +# include +# include +# include +# include +# include + +extern __typeof (__redirect_strcpy) __libc_strcpy; + +extern __typeof (__redirect_strcpy) __strcpy_generic attribute_hidden; + +static inline __typeof (__redirect_strcpy) * +select_strcpy_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) +{ + return __strcpy_generic; +} + +riscv_libc_ifunc (__libc_strcpy, select_strcpy_ifunc); + +# undef strcpy +strong_alias (__libc_strcpy, strcpy); +# ifdef SHARED +__hidden_ver1 (strcpy, __GI_strcpy, __redirect_strcpy) + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strcpy); +# endif +#else +# include +#endif diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c new file mode 100644 index 0000000000..4c15269028 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c @@ -0,0 +1,52 @@ +/* Multiple versions of strlen. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2025 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 strlen so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strlen +# define strlen __redirect_strlen +# include +# include +# include +# include +# include +# include + +extern __typeof (__redirect_strlen) __libc_strlen; + +extern __typeof (__redirect_strlen) __strlen_generic attribute_hidden; + +static inline __typeof (__redirect_strlen) * +select_strlen_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) +{ + return __strlen_generic; +} + +riscv_libc_ifunc (__libc_strlen, select_strlen_ifunc); + +# undef strlen +strong_alias (__libc_strlen, strlen); +# ifdef SHARED +__hidden_ver1 (strlen, __GI_strlen, __redirect_strlen) + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strlen); +# endif +#else +# include +#endif diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strncat.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strncat.c new file mode 100644 index 0000000000..2dd5b98e56 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strncat.c @@ -0,0 +1,52 @@ +/* Multiple versions of strncat. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2025 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 strncat so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strncat +# define strncat __redirect_strncat +# include +# include +# include +# include +# include +# include + +extern __typeof (__redirect_strncat) __libc_strncat; + +extern __typeof (__redirect_strncat) __strncat_generic attribute_hidden; + +static inline __typeof (__redirect_strncat) * +select_strncat_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) +{ + return __strncat_generic; +} + +riscv_libc_ifunc (__libc_strncat, select_strncat_ifunc); + +# undef strncat +strong_alias (__libc_strncat, strncat); +# ifdef SHARED +__hidden_ver1 (strncat, __GI_strncat, __redirect_strncat) + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strncat); +# endif +#else +# include +#endif diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strncmp.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strncmp.c new file mode 100644 index 0000000000..dc2f3dfbda --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strncmp.c @@ -0,0 +1,52 @@ +/* Multiple versions of strncmp. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2025 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 strncmp so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strncmp +# define strncmp __redirect_strncmp +# include +# include +# include +# include +# include +# include + +extern __typeof (__redirect_strncmp) __libc_strncmp; + +extern __typeof (__redirect_strncmp) __strncmp_generic attribute_hidden; + +static inline __typeof (__redirect_strncmp) * +select_strncmp_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) +{ + return __strncmp_generic; +} + +riscv_libc_ifunc (__libc_strncmp, select_strncmp_ifunc); + +# undef strncmp +strong_alias (__libc_strncmp, strncmp); +# ifdef SHARED +__hidden_ver1 (strncmp, __GI_strncmp, __redirect_strncmp) + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strncmp); +# endif +#else +# include +#endif diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strncpy.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strncpy.c new file mode 100644 index 0000000000..87451820d9 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strncpy.c @@ -0,0 +1,52 @@ +/* Multiple versions of strncpy. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2025 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 strncpy so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strncpy +# define strncpy __redirect_strncpy +# include +# include +# include +# include +# include +# include + +extern __typeof (__redirect_strncpy) __libc_strncpy; + +extern __typeof (__redirect_strncpy) __strncpy_generic attribute_hidden; + +static inline __typeof (__redirect_strncpy) * +select_strncpy_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) +{ + return __strncpy_generic; +} + +riscv_libc_ifunc (__libc_strncpy, select_strncpy_ifunc); + +# undef strncpy +strong_alias (__libc_strncpy, strncpy); +# ifdef SHARED +__hidden_ver1 (strncpy, __GI_strncpy, __redirect_strncpy) + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strncpy); +# endif +#else +# include +#endif diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strnlen.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strnlen.c new file mode 100644 index 0000000000..1ce4512651 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strnlen.c @@ -0,0 +1,54 @@ +/* Multiple versions of strnlen. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2025 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 strnlen so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strnlen +# define strnlen __redirect_strnlen +# include +# include +# include +# include +# include +# include + +extern __typeof (__redirect_strnlen) __libc_strnlen; + +extern __typeof (__redirect_strnlen) __strnlen_generic attribute_hidden; + +static inline __typeof (__redirect_strnlen) * +select_strnlen_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) +{ + return __strnlen_generic; +} + +riscv_libc_ifunc (__libc_strnlen, select_strnlen_ifunc); + +# undef strnlen +# undef __strnlen +strong_alias (__libc_strnlen, __strnlen); +weak_alias (__libc_strnlen, strnlen); +# ifdef SHARED +__hidden_ver1 (strnlen, __GI_strnlen, __redirect_strnlen) + __attribute__ ((visibility ("hidden"))) __attribute_copy__ (strnlen); +# endif +#else +# include +#endif From patchwork Tue Sep 23 11:23:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Yao Zihong X-Patchwork-Id: 120694 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C74783858C78 for ; Tue, 23 Sep 2025 11:35:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C74783858C78 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from cstnet.cn (smtp84.cstnet.cn [159.226.251.84]) by sourceware.org (Postfix) with ESMTPS id DB6CD3858CB6 for ; Tue, 23 Sep 2025 11:32:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DB6CD3858CB6 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 DB6CD3858CB6 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=159.226.251.84 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758627155; cv=none; b=lDom5NAoAIN17lnspE7iPOfHd2+MhCE6O58gDWzmrrvMHmhBzjLnMAd0WIqB9XinGIxKbORefeCI0ZP5inJWS7JfXm5OXTu03yfge07dNdZ3DLom9FS3ZGmRNgUJKoAU2FUNaPKCuL1pHsIHwUfpgFL073kC4qIa97sV6CpUdJU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758627155; c=relaxed/simple; bh=zjQt2rSmPIoUlxozdZx/zy/krMN8/o1WP9ydAEOfLiU=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=l1Hq/TlJ2uFhgV4d/IN+0T+daWqHN6V+bXphV7GF57AOjruSJjr808j4Z3QRC5Jiu813niMLZZSXP7QdkkpI4fwgujON9itjBoUFYoKIM6SHXYnxGiViZUSy+D1YKoju4W/Ys47JL60QeFNGd4KpdDZEbgu4g2Ze2emrDn8a68E= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DB6CD3858CB6 Received: from Mobilestation.localdomain (unknown [183.6.59.140]) by APP-05 (Coremail) with SMTP id zQCowAAXuhMZhdJoVxd9BA--.14410S4; Tue, 23 Sep 2025 19:31:58 +0800 (CST) From: Yao Zihong To: libc-alpha@sourceware.org Cc: Wilco.Dijkstra@arm.com, andrew@sifive.com, bergner@tenstorrent.com, carlos@redhat.com, dj@redhat.com, evan@rivosinc.com, jlaw@ventanamicro.com, palmer@dabbelt.com, vineetg@rivosinc.com, zhangyin2018@iscas.ac.cn, yun.hsiang@sifive.com, hau.hsu@sifive.com, jerry.shih@sifive.com, nick.knight@sifive.com, zihong.plct@isrc.iscas.ac.cn, zihongyao@outlook.com Subject: [PATCH v1 2/4] riscv: Add RVV implementations for mem* routines Date: Tue, 23 Sep 2025 19:23:10 +0800 Message-ID: <20250923112338.77162-3-zihong.plct@isrc.iscas.ac.cn> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250923112338.77162-1-zihong.plct@isrc.iscas.ac.cn> References: <20250923112338.77162-1-zihong.plct@isrc.iscas.ac.cn> MIME-Version: 1.0 X-CM-TRANSID: zQCowAAXuhMZhdJoVxd9BA--.14410S4 X-Coremail-Antispam: 1UD129KBjvAXoW3ur4Uuw1DWFWrAw1UZr18Zrb_yoW8JrWxKo WfKF47Zw4UKr1xAr4ruwsrZa47ZF1Ygr17Xw45ZaykJrn8Jr1kGryIyas5XrWakr4rWa1r XFW7tFZxJFWv9Fn7n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUOc7AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r15M28IrcIa0x kI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l84AC jcxK6xIIjxv20xvE14v26r1j6r1xM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJw A2z4x0Y4vEx4A2jsIE14v26r1j6r4UM28EF7xvwVC2z280aVCY1x0267AKxVW8JVW8Jr1l e2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI 8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwAC jcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxcIEc7CjxVA2Y2ka0x kIwI1lc7CjxVAaw2AFwI0_GFv_Wryl42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_ Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1V AY17CE14v26r4a6rW5MIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAI cVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIx AIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2 KfnxnUUI43ZEXa7sRipB-tUUUUU== X-Originating-IP: [183.6.59.140] X-CM-SenderInfo: p2lk00vjoszunw6l223fol2u1dvotugofq/ X-Spam-Status: No, score=-10.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.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 This patch imports RVV-based implementations of the mem* family: memchr, memcmp, memcpy, memmove, __memcmpeq, memset. They assume RVV 1.0 with VLEN >= 32, support arbitrary VLEN, and work on both RV32 and RV64 platforms. No page-size assumptions are made. Note that this version rebases Hau Hsu’s v3 patch, with no logic changes. Only symbol naming, formatting/spacing, and copyright years were updated to match current tree conventions. Based-on-patch-by: Hau Hsu Based-on-patch-by: Jerry Shih Based-on-patch-by: Yun Hsiang Co-authored-by: Hau Hsu Co-authored-by: Jerry Shih Co-authored-by: Yun Hsiang Signed-off-by: Yao Zihong --- sysdeps/riscv/multiarch/memchr_vector.S | 58 ++++++++++++++++++++ sysdeps/riscv/multiarch/memcmp_vector.S | 66 +++++++++++++++++++++++ sysdeps/riscv/multiarch/memcmpeq_vector.S | 60 +++++++++++++++++++++ sysdeps/riscv/multiarch/memcpy_vector.S | 46 ++++++++++++++++ sysdeps/riscv/multiarch/memmove_vector.S | 66 +++++++++++++++++++++++ sysdeps/riscv/multiarch/memset_vector.S | 45 ++++++++++++++++ 6 files changed, 341 insertions(+) create mode 100644 sysdeps/riscv/multiarch/memchr_vector.S create mode 100644 sysdeps/riscv/multiarch/memcmp_vector.S create mode 100644 sysdeps/riscv/multiarch/memcmpeq_vector.S create mode 100644 sysdeps/riscv/multiarch/memcpy_vector.S create mode 100644 sysdeps/riscv/multiarch/memmove_vector.S create mode 100644 sysdeps/riscv/multiarch/memset_vector.S diff --git a/sysdeps/riscv/multiarch/memchr_vector.S b/sysdeps/riscv/multiarch/memchr_vector.S new file mode 100644 index 0000000000..4435ac6572 --- /dev/null +++ b/sysdeps/riscv/multiarch/memchr_vector.S @@ -0,0 +1,58 @@ +/* RVV versions memchr. RISC-V version. + Copyright (C) 2025 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 + +#define result a0 + +#define src a0 +#define value a1 +#define num a2 + +#define ivl a3 +#define temp a4 + +#define ELEM_LMUL_SETTING m8 +#define vdata v0 +#define vmask v8 + +ENTRY (__memchr_vector) +L(loop): + vsetvli zero, num, e8, ELEM_LMUL_SETTING, ta, ma + + vle8ff.v vdata, (src) + /* Find the value inside the loaded data. */ + vmseq.vx vmask, vdata, value + vfirst.m temp, vmask + + /* Skip the loop if we find the matched value. */ + bgez temp, L(found) + + csrr ivl, vl + sub num, num, ivl + add src, src, ivl + + bnez num, L(loop) + + li result, 0 + ret +L(found): + add result, src, temp + ret +END (__memchr_vector) diff --git a/sysdeps/riscv/multiarch/memcmp_vector.S b/sysdeps/riscv/multiarch/memcmp_vector.S new file mode 100644 index 0000000000..3071518565 --- /dev/null +++ b/sysdeps/riscv/multiarch/memcmp_vector.S @@ -0,0 +1,66 @@ +/* RVV versions memcmp. RISC-V version. + Copyright (C) 2025 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 + +#define result a0 + +#define src1 a0 +#define src2 a1 +#define num a2 + +#define ivl a3 +#define temp a4 +#define temp1 a5 +#define temp2 a6 + +#define ELEM_LMUL_SETTING m8 +#define vdata1 v0 +#define vdata2 v8 +#define vmask v16 + +ENTRY (__memcmp_vector) +L(loop): + vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma + + vle8.v vdata1, (src1) + vle8.v vdata2, (src2) + + vmsne.vv vmask, vdata1, vdata2 + sub num, num, ivl + vfirst.m temp, vmask + + /* Skip the loop if we find the different value between src1 and src2. */ + bgez temp, L(found) + + add src1, src1, ivl + add src2, src2, ivl + + bnez num, L(loop) + + li result, 0 + ret +L(found): + add src1, src1, temp + add src2, src2, temp + lbu temp1, 0(src1) + lbu temp2, 0(src2) + sub result, temp1, temp2 + ret +END (__memcmp_vector) diff --git a/sysdeps/riscv/multiarch/memcmpeq_vector.S b/sysdeps/riscv/multiarch/memcmpeq_vector.S new file mode 100644 index 0000000000..54b9543531 --- /dev/null +++ b/sysdeps/riscv/multiarch/memcmpeq_vector.S @@ -0,0 +1,60 @@ +/* RVV versions memcmp. RISC-V version. + Copyright (C) 2025 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 + +#define result a0 + +#define src1 a0 +#define src2 a1 +#define num a2 + +#define ivl a3 +#define temp a4 + +#define ELEM_LMUL_SETTING m1 +#define vdata1 v0 +#define vdata2 v8 +#define vmask v16 + +ENTRY (____memcmpeq_vector) +L(loop): + vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma + + vle8.v vdata1, (src1) + vle8.v vdata2, (src2) + + vmsne.vv vmask, vdata1, vdata2 + sub num, num, ivl + vfirst.m temp, vmask + + /* Skip the loop if we find the different value between src1 and src2. */ + bgez temp, L(found) + + add src1, src1, ivl + add src2, src2, ivl + + bnez num, L(loop) + + li result, 0 + ret +L(found): + mv result, ivl + ret +END (____memcmpeq_vector) diff --git a/sysdeps/riscv/multiarch/memcpy_vector.S b/sysdeps/riscv/multiarch/memcpy_vector.S new file mode 100644 index 0000000000..e86e41d42b --- /dev/null +++ b/sysdeps/riscv/multiarch/memcpy_vector.S @@ -0,0 +1,46 @@ +/* RVV versions memcpy. RISC-V version. + Copyright (C) 2025 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 + +#define dst a0 +#define src a1 +#define num a2 + +#define ivl a3 +#define dst_ptr a4 + +#define ELEM_LMUL_SETTING m8 +#define vdata v0 + +ENTRY (__memcpy_vector) + mv dst_ptr, dst +L(loop): + vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma + + vle8.v vdata, (src) + sub num, num, ivl + add src, src, ivl + vse8.v vdata, (dst_ptr) + add dst_ptr, dst_ptr, ivl + + bnez num, L(loop) + + ret +END (__memcpy_vector) diff --git a/sysdeps/riscv/multiarch/memmove_vector.S b/sysdeps/riscv/multiarch/memmove_vector.S new file mode 100644 index 0000000000..b4f44fb27d --- /dev/null +++ b/sysdeps/riscv/multiarch/memmove_vector.S @@ -0,0 +1,66 @@ +/* RVV versions memmove. RISC-V version. + Copyright (C) 2025 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 + +#define dst a0 +#define src a1 +#define num a2 + +#define ivl a3 +#define dst_ptr a4 +#define src_backward_ptr a5 +#define dst_backward_ptr a6 + +#define ELEM_LMUL_SETTING m8 +#define vdata v0 + +ENTRY (__memmove_vector) + mv dst_ptr, dst + + /* If src is equal or after dst, all data in src will be loaded before + overwrited for the overlapping case. We could use faster `forward-copy`. */ + bgeu src, dst, L(forward_copy_loop) + add src_backward_ptr, src, num + add dst_backward_ptr, dst, num + /* If dst inside source data range, we need to use `backward_copy_loop` to + handle the overlapping issue. */ + bltu dst, src_backward_ptr, L(backward_copy_loop) +L(forward_copy_loop): + vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma + + vle8.v vdata, (src) + sub num, num, ivl + add src, src, ivl + vse8.v vdata, (dst_ptr) + add dst_ptr, dst_ptr, ivl + + bnez num, L(forward_copy_loop) + ret +L(backward_copy_loop): + vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma + + sub src_backward_ptr, src_backward_ptr, ivl + vle8.v vdata, (src_backward_ptr) + sub num, num, ivl + sub dst_backward_ptr, dst_backward_ptr, ivl + vse8.v vdata, (dst_backward_ptr) + bnez num, L(backward_copy_loop) + ret +END (__memmove_vector) diff --git a/sysdeps/riscv/multiarch/memset_vector.S b/sysdeps/riscv/multiarch/memset_vector.S new file mode 100644 index 0000000000..d66ea6dc0a --- /dev/null +++ b/sysdeps/riscv/multiarch/memset_vector.S @@ -0,0 +1,45 @@ +/* RVV versions memset. RISC-V version. + Copyright (C) 2025 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 + +#define dst a0 +#define value a1 +#define num a2 + +#define ivl a3 +#define dst_ptr a5 + +#define ELEM_LMUL_SETTING m8 +#define vdata v0 + +ENTRY (__memset_vector) + mv dst_ptr, dst + + vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma + vmv.v.x vdata, value +L(loop): + vse8.v vdata, (dst_ptr) + sub num, num, ivl + add dst_ptr, dst_ptr, ivl + vsetvli ivl, num, e8, ELEM_LMUL_SETTING, ta, ma + bnez num, L(loop) + + ret +END (__memset_vector) From patchwork Tue Sep 23 11:23:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Yao Zihong X-Patchwork-Id: 120695 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EFCC93858D33 for ; Tue, 23 Sep 2025 11:36:47 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EFCC93858D33 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from cstnet.cn (smtp84.cstnet.cn [159.226.251.84]) by sourceware.org (Postfix) with ESMTPS id 93DE03858D39 for ; Tue, 23 Sep 2025 11:32:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 93DE03858D39 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 93DE03858D39 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=159.226.251.84 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758627159; cv=none; b=ZMkjRdSvaRqkwWGJm5+out4nlh+p+T3cu1E9I44Dkqv5onU/yUbR53jq4hVkxeAu6YCPKHJdE2NAjKg+F+R4SF41o9W4LN66HBSqeYiPh23bC59R8UTbffEMw3yP47tBa2y0pUZyvrSDJVtb5OUaDLNtTdtsM1HXxCPmIrL8Kjk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758627159; c=relaxed/simple; bh=lIipZwuaRPv987f7GvQ52wcvEPauupWqf5LJ4eMq8hs=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=A51Bw9BUO7SZ9X1ys4WJ8A11XVlvTKZyZpO/5rmWhfGhGiCbNgm9iaILhXIhGFkaDZAP0jQQ4WJ/WxGZLzAKYVtvd77nfdw0+AsIuLm67gjhZVCVFpoVh161AuA+4KdAKKlTmPdV4DwwNTgdLMrx1qlCPc9Q+tcwb7xgrc/v11g= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 93DE03858D39 Received: from Mobilestation.localdomain (unknown [183.6.59.140]) by APP-05 (Coremail) with SMTP id zQCowAAXuhMZhdJoVxd9BA--.14410S5; Tue, 23 Sep 2025 19:32:01 +0800 (CST) From: Yao Zihong To: libc-alpha@sourceware.org Cc: Wilco.Dijkstra@arm.com, andrew@sifive.com, bergner@tenstorrent.com, carlos@redhat.com, dj@redhat.com, evan@rivosinc.com, jlaw@ventanamicro.com, palmer@dabbelt.com, vineetg@rivosinc.com, zhangyin2018@iscas.ac.cn, yun.hsiang@sifive.com, hau.hsu@sifive.com, jerry.shih@sifive.com, nick.knight@sifive.com, zihong.plct@isrc.iscas.ac.cn, zihongyao@outlook.com Subject: [PATCH v1 3/4] riscv: Add RVV implementations for str* routines Date: Tue, 23 Sep 2025 19:23:11 +0800 Message-ID: <20250923112338.77162-4-zihong.plct@isrc.iscas.ac.cn> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250923112338.77162-1-zihong.plct@isrc.iscas.ac.cn> References: <20250923112338.77162-1-zihong.plct@isrc.iscas.ac.cn> MIME-Version: 1.0 X-CM-TRANSID: zQCowAAXuhMZhdJoVxd9BA--.14410S5 X-Coremail-Antispam: 1UD129KBjvAXoWfZry8Jw45Ww1DKF1rXF4xJFb_yoW8uF48Co WfKFsrZw48GryxCrs5Cw47ua4xXr1Y9r17Xw45XaykXFy5JrykGryIya9Yg3y2kr4ruFWr XFyaya98JFWqkF18n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUOc7AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r1rM28IrcIa0x kI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l84AC jcxK6xIIjxv20xvE14v26r1j6r1xM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJw A2z4x0Y4vEx4A2jsIE14v26r1j6r4UM28EF7xvwVC2z280aVCY1x0267AKxVW8JVW8Jr1l e2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI 8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwAC jcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxcIEc7CjxVA2Y2ka0x kIwI1lc7CjxVAaw2AFwI0_GFv_Wryl42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_ Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1V AY17CE14v26r4a6rW5MIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAI cVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIx AIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2 KfnxnUUI43ZEXa7sRiuWl3UUUUU== X-Originating-IP: [183.6.59.140] X-CM-SenderInfo: p2lk00vjoszunw6l223fol2u1dvotugofq/ X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.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 This patch imports RVV-based implementations of the str* family: strcat, strcmp, strcpy, strlen, strnlen, strchr, strncat, strncmp, strncpy. They assume RVV 1.0 with VLEN >= 32, support arbitrary VLEN, and work on both RV32 and RV64. No page-size assumptions are made. Note that this version rebases Hau Hsu’s v3 patch, with no logic changes. Only symbol naming, formatting/spacing, and copyright years were updated to match current tree conventions. Based-on-patch-by: Hau Hsu Based-on-patch-by: Jerry Shih Based-on-patch-by: Nick Knight Co-authored-by: Hau Hsu Co-authored-by: Jerry Shih Co-authored-by: Nick Knight Signed-off-by: Yao Zihong --- sysdeps/riscv/multiarch/strcat_vector.S | 67 +++++++++++++++++++ sysdeps/riscv/multiarch/strchr_vector.S | 56 ++++++++++++++++ sysdeps/riscv/multiarch/strcmp_vector.S | 85 ++++++++++++++++++++++++ sysdeps/riscv/multiarch/strcpy_vector.S | 51 ++++++++++++++ sysdeps/riscv/multiarch/strlen_vector.S | 49 ++++++++++++++ sysdeps/riscv/multiarch/strncat_vector.S | 78 ++++++++++++++++++++++ sysdeps/riscv/multiarch/strncmp_vector.S | 80 ++++++++++++++++++++++ sysdeps/riscv/multiarch/strncpy_vector.S | 81 ++++++++++++++++++++++ sysdeps/riscv/multiarch/strnlen_vector.S | 51 ++++++++++++++ 9 files changed, 598 insertions(+) create mode 100644 sysdeps/riscv/multiarch/strcat_vector.S create mode 100644 sysdeps/riscv/multiarch/strchr_vector.S create mode 100644 sysdeps/riscv/multiarch/strcmp_vector.S create mode 100644 sysdeps/riscv/multiarch/strcpy_vector.S create mode 100644 sysdeps/riscv/multiarch/strlen_vector.S create mode 100644 sysdeps/riscv/multiarch/strncat_vector.S create mode 100644 sysdeps/riscv/multiarch/strncmp_vector.S create mode 100644 sysdeps/riscv/multiarch/strncpy_vector.S create mode 100644 sysdeps/riscv/multiarch/strnlen_vector.S diff --git a/sysdeps/riscv/multiarch/strcat_vector.S b/sysdeps/riscv/multiarch/strcat_vector.S new file mode 100644 index 0000000000..dbb48cd323 --- /dev/null +++ b/sysdeps/riscv/multiarch/strcat_vector.S @@ -0,0 +1,67 @@ +/* RVV versions strcat. RISC-V version. + Copyright (C) 2025 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 + +#define dst a0 +#define src a1 +#define dst_ptr a2 + +#define ivl a3 +#define cur_vl a4 +#define active_elem_pos a5 + +#define ELEM_LMUL_SETTING m1 +#define vmask1 v0 +#define vmask2 v1 +#define vstr1 v8 +#define vstr2 v16 + +ENTRY (__strcat_vector) + mv dst_ptr, dst + /* Perform `strlen(dst)`. */ +L(strlen_loop): + vsetvli ivl, zero, e8, ELEM_LMUL_SETTING, ta, ma + + vle8ff.v vstr1, (dst_ptr) + vmseq.vx vmask1, vstr1, zero + csrr cur_vl, vl + vfirst.m active_elem_pos, vmask1 + add dst_ptr, dst_ptr, cur_vl + bltz active_elem_pos, L(strlen_loop) + + sub dst_ptr, dst_ptr, cur_vl + add dst_ptr, dst_ptr, active_elem_pos + + /* Perform `strcpy(dst, src)`. */ +L(strcpy_loop): + vsetvli ivl, zero, e8, ELEM_LMUL_SETTING, ta, ma + + vle8ff.v vstr1, (src) + vmseq.vx vmask2, vstr1, zero + csrr cur_vl, vl + vfirst.m active_elem_pos, vmask2 + vmsif.m vmask1, vmask2 + add src, src, cur_vl + vse8.v vstr1, (dst_ptr), vmask1.t + add dst_ptr, dst_ptr, cur_vl + bltz active_elem_pos, L(strcpy_loop) + + ret +END (__strcat_vector) \ No newline at end of file diff --git a/sysdeps/riscv/multiarch/strchr_vector.S b/sysdeps/riscv/multiarch/strchr_vector.S new file mode 100644 index 0000000000..fca3b9bf4d --- /dev/null +++ b/sysdeps/riscv/multiarch/strchr_vector.S @@ -0,0 +1,56 @@ +/* RVV versions strchr. RISC-V version. + Copyright (C) 2025 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 + +#define str a0 +#define ch a1 +#define end_offset a2 +#define ch_offset a3 +#define temp1 a4 +#define temp2 a5 +#define cur_vl a6 +#define ivl t0 + +#define ELEM_LMUL_SETTING m1 +#define vstr v0 +#define vmask_end v8 +#define vmask_ch v9 + +ENTRY (__strchr_vector) +L(strchr_loop): + vsetvli ivl, zero, e8, ELEM_LMUL_SETTING, ta, ma + vle8ff.v vstr, (str) + vmseq.vi vmask_end, vstr, 0 + vmseq.vx vmask_ch, vstr, ch + vfirst.m end_offset, vmask_end /* first occurrence of \0 */ + vfirst.m ch_offset, vmask_ch /* first occurrence of ch */ + sltz temp1, ch_offset + sltu temp2, end_offset, ch_offset + or temp1, temp1, temp2 + beqz temp1, L(found_ch) /* Found ch, not preceded by \0? */ + csrr cur_vl, vl + add str, str, cur_vl + bltz end_offset, L(strchr_loop) /* Didn't find \0? */ + li str, 0 + ret +L(found_ch): + add str, str, ch_offset + ret +END (__strchr_vector) diff --git a/sysdeps/riscv/multiarch/strcmp_vector.S b/sysdeps/riscv/multiarch/strcmp_vector.S new file mode 100644 index 0000000000..037edc312b --- /dev/null +++ b/sysdeps/riscv/multiarch/strcmp_vector.S @@ -0,0 +1,85 @@ +/* RVV versions strcmp. RISC-V version. + Copyright (C) 2025 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 + +#define result a0 + +#define str1 a0 +#define str2 a1 + +#define ivl a2 +#define temp1 a3 +#define temp2 a4 + +#define vstr1 v0 +#define vstr2 v8 +#define vmask1 v16 +#define vmask2 v17 + +ENTRY(__strcmp_vector) + /* lmul=1 */ +L(Loop): + vsetvli ivl, zero, e8, m1, ta, ma + vle8ff.v vstr1, (str1) + /* check if vstr1[i] == 0 */ + vmseq.vx vmask1, vstr1, zero + + vle8ff.v vstr2, (str2) + /* check if vstr1[i] != vstr2[i] */ + vmsne.vv vmask2, vstr1, vstr2 + + /* find the index x for vstr1[x]==0 */ + vfirst.m temp1, vmask1 + /* find the index x for vstr1[x]!=vstr2[x] */ + vfirst.m temp2, vmask2 + + bgez temp1, L(check1) + bgez temp2, L(check2) + + /* get the current vl updated by vle8ff. */ + csrr ivl, vl + add str1, str1, ivl + add str2, str2, ivl + j L(Loop) + + /* temp1>=0 */ +L(check1): + bltz temp2, 1f + blt temp2, temp1, L(check2) +1: + /* temp2<0 */ + /* temp2>=0 && temp1=0 */ +L(check2): + add str1, str1, temp2 + add str2, str2, temp2 + lbu temp1, 0(str1) + lbu temp2, 0(str2) + sub result, temp1, temp2 + ret +END (__strcmp_vector) diff --git a/sysdeps/riscv/multiarch/strcpy_vector.S b/sysdeps/riscv/multiarch/strcpy_vector.S new file mode 100644 index 0000000000..fdd64f8cb5 --- /dev/null +++ b/sysdeps/riscv/multiarch/strcpy_vector.S @@ -0,0 +1,51 @@ +/* RVV versions strcpy. RISC-V version. + Copyright (C) 2025 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 + +#define dst a0 +#define src a1 +#define dst_ptr a2 + +#define ivl a3 +#define cur_vl a4 +#define active_elem_pos a5 + +#define ELEM_LMUL_SETTING m1 +#define vmask1 v0 +#define vmask2 v1 +#define vstr1 v8 +#define vstr2 v16 + +ENTRY (__strcpy_vector) + mv dst_ptr, dst +L(strcpy_loop): + vsetvli ivl, zero, e8, ELEM_LMUL_SETTING, ta, ma + vle8ff.v vstr1, (src) + vmseq.vx vmask2, vstr1, zero + csrr cur_vl, vl + vfirst.m active_elem_pos, vmask2 + vmsif.m vmask1, vmask2 + add src, src, cur_vl + vse8.v vstr1, (dst_ptr), vmask1.t + add dst_ptr, dst_ptr, cur_vl + bltz active_elem_pos, L(strcpy_loop) + + ret +END (__strcpy_vector) diff --git a/sysdeps/riscv/multiarch/strlen_vector.S b/sysdeps/riscv/multiarch/strlen_vector.S new file mode 100644 index 0000000000..ca471b9478 --- /dev/null +++ b/sysdeps/riscv/multiarch/strlen_vector.S @@ -0,0 +1,49 @@ +/* RVV versions strlen. RISC-V version. + Copyright (C) 2025 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 + +#define result a0 +#define str a0 +#define copy_str a1 +#define ivl a2 +#define cur_vl a2 +#define end_offset a3 + +#define ELEM_LMUL_SETTING m2 +#define vstr v0 +#define vmask_end v2 + +ENTRY (__strlen_vector) + mv copy_str, str +L(loop): + vsetvli ivl, zero, e8, ELEM_LMUL_SETTING, ta, ma + vle8ff.v vstr, (copy_str) + csrr cur_vl, vl + vmseq.vi vmask_end, vstr, 0 + vfirst.m end_offset, vmask_end + add copy_str, copy_str, cur_vl + bltz end_offset, L(loop) + + add str, str, cur_vl + add copy_str, copy_str, end_offset + sub result, copy_str, result + + ret +END (__strlen_vector) diff --git a/sysdeps/riscv/multiarch/strncat_vector.S b/sysdeps/riscv/multiarch/strncat_vector.S new file mode 100644 index 0000000000..8c46f833f8 --- /dev/null +++ b/sysdeps/riscv/multiarch/strncat_vector.S @@ -0,0 +1,78 @@ +/* RVV versions strncat. RISC-V version. + Copyright (C) 2025 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 + +#define dst a0 +#define src a1 +#define length a2 +#define dst_ptr a3 + +#define ivl a4 +#define cur_vl a5 +#define activate_elem_pos a6 + +#define ELEM_LMUL_SETTING m1 +#define vmask1 v0 +#define vmask2 v1 +#define vstr1 v8 +#define vstr2 v16 + +ENTRY (__strncat_vector) + mv dst_ptr, dst + /* the strlen of dst. */ +L(strlen_loop): + vsetvli ivl, zero, e8, ELEM_LMUL_SETTING, ta, ma + + vle8ff.v vstr1, (dst_ptr) + /* find the '\0'. */ + vmseq.vx vmask1, vstr1, zero + csrr cur_vl, vl + vfirst.m activate_elem_pos, vmask1 + add dst_ptr, dst_ptr, cur_vl + bltz activate_elem_pos, L(strlen_loop) + + sub dst_ptr, dst_ptr, cur_vl + add dst_ptr, dst_ptr, activate_elem_pos + + /* copy src to dst_ptr. */ +L(strcpy_loop): + vsetvli zero, length, e8, ELEM_LMUL_SETTING, ta, ma + + vle8ff.v vstr1, (src) + vmseq.vx vmask2, vstr1, zero + csrr cur_vl, vl + vfirst.m activate_elem_pos, vmask2 + vmsif.m vmask1, vmask2 + add src, src, cur_vl + sub length, length, cur_vl + vse8.v vstr1, (dst_ptr), vmask1.t + add dst_ptr, dst_ptr, cur_vl + beqz length, L(fill_zero) + bltz activate_elem_pos, L(strcpy_loop) + + ret + +L(fill_zero): + bgez activate_elem_pos, L(fill_zero_end) + sb zero, (dst_ptr) + +L(fill_zero_end): + ret +END (__strncat_vector) diff --git a/sysdeps/riscv/multiarch/strncmp_vector.S b/sysdeps/riscv/multiarch/strncmp_vector.S new file mode 100644 index 0000000000..448e42da24 --- /dev/null +++ b/sysdeps/riscv/multiarch/strncmp_vector.S @@ -0,0 +1,80 @@ +/* RVV versions strncmp. RISC-V version. + Copyright (C) 2025 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 + +#define result a0 + +#define str1 a0 +#define str2 a1 +#define length a2 + +#define ivl a3 +#define temp1 a4 +#define temp2 a5 + +#define ELEM_LMUL_SETTING m1 +#define vstr1 v0 +#define vstr2 v4 +#define vmask1 v8 +#define vmask2 v9 + +ENTRY (__strncmp_vector) + beqz length, L(zero_length) +L(loop): + vsetvli zero, length, e8, ELEM_LMUL_SETTING, ta, ma + + vle8ff.v vstr1, (str1) + /* vstr1[i] == 0. */ + vmseq.vx vmask1, vstr1, zero + + vle8ff.v vstr2, (str2) + /* vstr1[i] != vstr2[i]. */ + vmsne.vv vmask2, vstr1, vstr2 + + csrr ivl, vl + + /* r = mask1 | mask2 + We could use vfirst.m to get the first zero char or the + first different char between str1 and str2. */ + vmor.mm vmask1, vmask1, vmask2 + + sub length, length, ivl + + vfirst.m temp1, vmask1 + + bgez temp1, L(end_loop) + + add str1, str1, ivl + add str2, str2, ivl + bnez length, L(loop) +L(end_loop): + + add str1, str1, temp1 + add str2, str2, temp1 + lbu temp1, 0(str1) + lbu temp2, 0(str2) + + sub result, temp1, temp2 + ret + +L(zero_length): + li result, 0 + ret +END (__strncmp_vector) diff --git a/sysdeps/riscv/multiarch/strncpy_vector.S b/sysdeps/riscv/multiarch/strncpy_vector.S new file mode 100644 index 0000000000..8003ff396b --- /dev/null +++ b/sysdeps/riscv/multiarch/strncpy_vector.S @@ -0,0 +1,81 @@ +/* RVV versions strncpy. RISC-V version. + Copyright (C) 2025 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 + +#define dst a0 +#define src a1 +#define length a2 +#define dst_ptr a3 + +#define ivl a4 +#define cur_vl a5 +#define active_elem_pos a6 +#define temp a7 + +#define ELEM_LMUL_SETTING m1 +#define vmask1 v0 +#define vmask2 v1 +#define ZERO_FILL_ELEM_LMUL_SETTING m8 +#define vstr1 v8 +#define vstr2 v16 + +ENTRY (__strncpy_vector) + mv dst_ptr, dst + /* Copy src to dst_ptr. */ +L(strcpy_loop): + vsetvli zero, length, e8, ELEM_LMUL_SETTING, ta, ma + vle8ff.v vstr1, (src) + vmseq.vx vmask2, vstr1, zero + csrr cur_vl, vl + vfirst.m active_elem_pos, vmask2 + vmsif.m vmask1, vmask2 + add src, src, cur_vl + sub length, length, cur_vl + vse8.v vstr1, (dst_ptr), vmask1.t + add dst_ptr, dst_ptr, cur_vl + bgez active_elem_pos, L(fill_zero) + bnez length, L(strcpy_loop) + ret + + /* Fill the tail zero. */ +L(fill_zero): + /* We already copy the `\0` to dst. But we use `vfirst.m` to + get the `index` of `\0` position. We need to adjust `-1` + to get the correct remaining length for zero filling. */ + sub temp, cur_vl, active_elem_pos + addi temp, temp, -1 + add length, length, temp + /* Have an earily return for `strlen(src) + 1 == count` case. */ + bnez length, 1f + ret +1: + sub dst_ptr, dst_ptr, temp + vsetvli zero, length, e8, ZERO_FILL_ELEM_LMUL_SETTING, ta, ma + vmv.v.x vstr2, zero + +L(fill_zero_loop): + vsetvli ivl, length, e8, ZERO_FILL_ELEM_LMUL_SETTING, ta, ma + vse8.v vstr2, (dst_ptr) + sub length, length, ivl + add dst_ptr, dst_ptr, ivl + bnez length, L(fill_zero_loop) + + ret +END (__strncpy_vector) diff --git a/sysdeps/riscv/multiarch/strnlen_vector.S b/sysdeps/riscv/multiarch/strnlen_vector.S new file mode 100644 index 0000000000..5fb0f2d82d --- /dev/null +++ b/sysdeps/riscv/multiarch/strnlen_vector.S @@ -0,0 +1,51 @@ +/* RVV versions strnlen. RISC-V version. + Copyright (C) 2025 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 + +#define str a0 +#define copy_str a2 +#define ret_value a0 +#define max_len a1 +#define cur_vl a3 +#define end_offset a4 + +#define ELEM_LMUL_SETTING m1 +#define vstr v0 +#define vmask_end v8 + +ENTRY (__strnlen_vector) + mv copy_str, str + mv ret_value, max_len +L(strnlen_vector_loop): + beqz max_len, L(end_strnlen_vector_loop) + vsetvli zero, max_len, e8, ELEM_LMUL_SETTING, ta, ma + vle8ff.v vstr, (copy_str) + vmseq.vi vmask_end, vstr, 0 + vfirst.m end_offset, vmask_end /* first occurence of \0 */ + csrr cur_vl, vl + add copy_str, copy_str, cur_vl + sub max_len, max_len, cur_vl + bltz end_offset, L(strnlen_vector_loop) + add max_len, max_len, cur_vl + sub ret_value, ret_value, max_len + add ret_value, ret_value, end_offset +L(end_strnlen_vector_loop): + ret +END (__strnlen_vector) From patchwork Tue Sep 23 11:23:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Zihong X-Patchwork-Id: 120693 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2D7D23857C6C for ; Tue, 23 Sep 2025 11:34:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2D7D23857C6C X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from cstnet.cn (smtp84.cstnet.cn [159.226.251.84]) by sourceware.org (Postfix) with ESMTPS id 5BF813858C62 for ; Tue, 23 Sep 2025 11:32:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5BF813858C62 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 5BF813858C62 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=159.226.251.84 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758627161; cv=none; b=EyBQ4stRJsBpTtkE2JjPzQ98/2wQt/bMDhbn4KRUF3yEeVR45ccivqIU5wH4LPze8tcymW62Jghy/8IiS73fLMtgr7aH3C/Z+99HrTT0wLNbuwYRt/FUr5yCmkgnTjr+enmqHbd0i6iCeVOTebrsgsbnNjIKtI5YFRCVGIoT5qA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1758627161; c=relaxed/simple; bh=oO1s3Wqb3MUFeXxwml5n7B5/zVwHCOaEF7QBMF9QwYw=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=GZ93xyJZNPro3G8mjwKjXQXAtG5nVRfFV+yYpHnPnM6ZAWh+ak1f8bR+UWABlbHOVAXA7nex50ca4l8NV8K4Ml1rz69L7gZK3s8vy2T7sk7p7Xe/oALz3dawiGugXuavYz9aEQYFa7yBtZWhsDvm/wE0u+NS78BTlfYEdkMYsy4= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5BF813858C62 Received: from Mobilestation.localdomain (unknown [183.6.59.140]) by APP-05 (Coremail) with SMTP id zQCowAAXuhMZhdJoVxd9BA--.14410S6; Tue, 23 Sep 2025 19:32:03 +0800 (CST) From: Yao Zihong To: libc-alpha@sourceware.org Cc: Wilco.Dijkstra@arm.com, andrew@sifive.com, bergner@tenstorrent.com, carlos@redhat.com, dj@redhat.com, evan@rivosinc.com, jlaw@ventanamicro.com, palmer@dabbelt.com, vineetg@rivosinc.com, zhangyin2018@iscas.ac.cn, yun.hsiang@sifive.com, hau.hsu@sifive.com, jerry.shih@sifive.com, nick.knight@sifive.com, zihong.plct@isrc.iscas.ac.cn, zihongyao@outlook.com Subject: [PATCH v1 4/4] riscv: Enable RVV selection in ifunc resolvers Date: Tue, 23 Sep 2025 19:23:12 +0800 Message-ID: <20250923112338.77162-5-zihong.plct@isrc.iscas.ac.cn> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250923112338.77162-1-zihong.plct@isrc.iscas.ac.cn> References: <20250923112338.77162-1-zihong.plct@isrc.iscas.ac.cn> MIME-Version: 1.0 X-CM-TRANSID: zQCowAAXuhMZhdJoVxd9BA--.14410S6 X-Coremail-Antispam: 1UD129KBjvAXoWfJrW8KF45Cw13XFy3XFyrJFb_yoW8Aw43Xo WagFZxZFn7Wr1UuF4ruayDGa9FvryrAF1jq3W5Xa1DJ3Z3JrW8ursIka1vy34avw13WF4r Wry8Kryrtan5JF9xn29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUOI7AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r126s0DM28Irc Ia0xkI8VCY1x0267AKxVW5JVCq3wA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l 84ACjcxK6xIIjxv20xvE14v26r1j6r1xM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26F4j6r 4UJwA2z4x0Y4vEx4A2jsIE14v26r1j6r4UM28EF7xvwVC2z280aVCY1x0267AKxVW8JVW8 Jr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2I x0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8 JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lFIxGxcIEc7CjxVA2Y2 ka0xkIwI1lc7CjxVAaw2AFwI0_GFv_Wryl42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Y z7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zV AF1VAY17CE14v26r4a6rW5MIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4l IxAIcVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF 4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsG vfC2KfnxnUUI43ZEXa7sRiHUDtUUUUU== X-Originating-IP: [183.6.59.140] X-CM-SenderInfo: p2lk00vjoszunw6l223fol2u1dvotugofq/ X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.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 This patch enables runtime selection of the imported RVV variants via IFUNC for the RISC-V mem*/str* families. It augments ifunc-impl-list.c and updates per-function resolvers to pick RVV when the RISC-V V extension is present, otherwise falling back to generic. On non-RVV systems, behavior is identical to before. Signed-off-by: Yao Zihong --- .../unix/sysv/linux/riscv/multiarch/Makefile | 15 +++++++ .../linux/riscv/multiarch/ifunc-impl-list.c | 44 ++++++++++++++++++- .../unix/sysv/linux/riscv/multiarch/memchr.c | 3 ++ .../unix/sysv/linux/riscv/multiarch/memcmp.c | 3 ++ .../sysv/linux/riscv/multiarch/memcmpeq.c | 3 ++ .../unix/sysv/linux/riscv/multiarch/memcpy.c | 5 +++ .../unix/sysv/linux/riscv/multiarch/memmove.c | 3 ++ .../unix/sysv/linux/riscv/multiarch/memset.c | 3 ++ .../unix/sysv/linux/riscv/multiarch/strcat.c | 3 ++ .../unix/sysv/linux/riscv/multiarch/strchr.c | 3 ++ .../unix/sysv/linux/riscv/multiarch/strcmp.c | 3 ++ .../unix/sysv/linux/riscv/multiarch/strcpy.c | 3 ++ .../unix/sysv/linux/riscv/multiarch/strlen.c | 3 ++ .../unix/sysv/linux/riscv/multiarch/strncat.c | 3 ++ .../unix/sysv/linux/riscv/multiarch/strncmp.c | 3 ++ .../unix/sysv/linux/riscv/multiarch/strncpy.c | 3 ++ .../unix/sysv/linux/riscv/multiarch/strnlen.c | 3 ++ 17 files changed, 105 insertions(+), 1 deletion(-) diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile index 9338db7f94..09a674af0d 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/Makefile @@ -3,34 +3,49 @@ sysdep_routines += \ memcpy \ memcpy-generic \ memcpy_noalignment \ + memcpy_vector \ memchr \ memchr-generic \ + memchr_vector \ memcmp \ memcmp-generic \ + memcmp_vector \ memcmpeq \ memcmpeq-generic \ + memcmpeq_vector \ memmove \ memmove-generic \ + memmove_vector \ memset \ memset-generic \ + memset_vector \ strcat \ strcat-generic \ + strcat_vector \ strcmp \ strcmp-generic \ + strcmp_vector \ strcpy \ strcpy-generic \ + strcpy_vector \ strlen \ strlen-generic \ + strlen_vector \ strnlen \ strnlen-generic \ + strnlen_vector \ strncat \ strncat-generic \ + strncat_vector \ strncmp \ strncmp-generic \ + strncmp_vector \ strncpy \ strncpy-generic \ + strncpy_vector \ strchr \ strchr-generic \ + strchr_vector \ # sysdep_routines CFLAGS-memcpy_noalignment.c += -mno-strict-align 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 567a16c723..092211f0c6 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c @@ -27,52 +27,94 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, size_t i = max; bool fast_unaligned = false; + bool rvv_ext = false; struct riscv_hwprobe pair = { .key = RISCV_HWPROBE_KEY_CPUPERF_0 }; if (__riscv_hwprobe (&pair, 1, 0, NULL, 0) == 0 && (pair.value & RISCV_HWPROBE_MISALIGNED_MASK) == RISCV_HWPROBE_MISALIGNED_FAST) fast_unaligned = true; + + struct riscv_hwprobe ext_pair = { .key = RISCV_HWPROBE_KEY_IMA_EXT_0 }; + if (__riscv_hwprobe (&ext_pair, 1, 0, NULL, 0) == 0 + && (ext_pair.value & RISCV_HWPROBE_IMA_V)) + rvv_ext = true; IFUNC_IMPL (i, name, memcpy, - IFUNC_IMPL_ADD (array, i, memcpy, fast_unaligned, + IFUNC_IMPL_ADD (array, i, memcpy, rvv_ext, + __memcpy_vector) + IFUNC_IMPL_ADD (array, i, memcpy, fast_unaligned, __memcpy_noalignment) IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_generic)) IFUNC_IMPL (i, name, memchr, + IFUNC_IMPL_ADD (array, i, memchr, rvv_ext, + __memchr_vector) IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_generic)) IFUNC_IMPL (i, name, memmove, + IFUNC_IMPL_ADD (array, i, memmove, rvv_ext, + __memmove_vector) IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_generic)) IFUNC_IMPL (i, name, memset, + IFUNC_IMPL_ADD (array, i, memset, rvv_ext, + __memset_vector) IFUNC_IMPL_ADD (array, i, memset, 1, __memset_generic)) + IFUNC_IMPL (i, name, memcmp, + IFUNC_IMPL_ADD (array, i, memcmp, rvv_ext, + __memcmp_vector) + IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_generic)) + + IFUNC_IMPL (i, name, __memcmpeq, + IFUNC_IMPL_ADD (array, i, __memcmpeq, rvv_ext, + ____memcmpeq_vector) + IFUNC_IMPL_ADD (array, i, __memcmpeq, 1, ____memcmpeq_generic)) + IFUNC_IMPL (i, name, strcat, + IFUNC_IMPL_ADD (array, i, strcat, rvv_ext, + __strcat_vector) IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_generic)) IFUNC_IMPL (i, name, strcmp, + IFUNC_IMPL_ADD (array, i, strcmp, rvv_ext, + __strcmp_vector) IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_generic)) IFUNC_IMPL (i, name, strcpy, + IFUNC_IMPL_ADD (array, i, strcpy, rvv_ext, + __strcpy_vector) IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_generic)) IFUNC_IMPL (i, name, strlen, + IFUNC_IMPL_ADD (array, i, strlen, rvv_ext, + __strlen_vector) IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_generic)) IFUNC_IMPL (i, name, strnlen, + IFUNC_IMPL_ADD (array, i, strnlen, rvv_ext, + __strnlen_vector) IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_generic)) IFUNC_IMPL (i, name, strncat, + IFUNC_IMPL_ADD (array, i, strncat, rvv_ext, + __strncat_vector) IFUNC_IMPL_ADD (array, i, strncat, 1, __strncat_generic)) IFUNC_IMPL (i, name, strncmp, + IFUNC_IMPL_ADD (array, i, strncmp, rvv_ext, + __strncmp_vector) IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_generic)) IFUNC_IMPL (i, name, strncpy, + IFUNC_IMPL_ADD (array, i, strncpy, rvv_ext, + __strncpy_vector) IFUNC_IMPL_ADD (array, i, strncpy, 1, __strncpy_generic)) IFUNC_IMPL (i, name, strchr, + IFUNC_IMPL_ADD (array, i, strchr, rvv_ext, + __strchr_vector) IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_generic)) return 0; diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memchr.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memchr.c index 08a5f36e52..c056a41ca4 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/memchr.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memchr.c @@ -32,10 +32,13 @@ extern __typeof (__redirect_memchr) __libc_memchr; extern __typeof (__redirect_memchr) __memchr_generic attribute_hidden; +extern __typeof (__redirect_memchr) __memchr_vector attribute_hidden; static inline __typeof (__redirect_memchr) * select_memchr_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { + if (dl_hwcap & COMPAT_HWCAP_ISA_V) + return __memchr_vector; return __memchr_generic; } diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memcmp.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memcmp.c index 13c86a8042..9b2f36bd07 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/memcmp.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memcmp.c @@ -32,10 +32,13 @@ extern __typeof (__redirect_memcmp) __libc_memcmp; extern __typeof (__redirect_memcmp) __memcmp_generic attribute_hidden; +extern __typeof (__redirect_memcmp) __memcmp_vector attribute_hidden; static inline __typeof (__redirect_memcmp) * select_memcmp_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { + if (dl_hwcap & COMPAT_HWCAP_ISA_V) + return __memcmp_vector; return __memcmp_generic; } diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memcmpeq.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memcmpeq.c index c963a2ee75..7a9eaa268e 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/memcmpeq.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memcmpeq.c @@ -32,10 +32,13 @@ extern __typeof (__redirect___memcmpeq) __libc___memcmpeq; extern __typeof (__redirect___memcmpeq) ____memcmpeq_generic attribute_hidden; +extern __typeof (__redirect___memcmpeq) ____memcmpeq_vector attribute_hidden; static inline __typeof (__redirect___memcmpeq) * select___memcmpeq_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { + if (dl_hwcap & COMPAT_HWCAP_ISA_V) + return ____memcmpeq_vector; return ____memcmpeq_generic; } diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memcpy.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memcpy.c index 8544f5402a..0e478b3e77 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/memcpy.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memcpy.c @@ -27,16 +27,21 @@ # include # include # include +# include extern __typeof (__redirect_memcpy) __libc_memcpy; extern __typeof (__redirect_memcpy) __memcpy_generic attribute_hidden; extern __typeof (__redirect_memcpy) __memcpy_noalignment attribute_hidden; +extern __typeof (__redirect_memcpy) __memcpy_vector attribute_hidden; static inline __typeof (__redirect_memcpy) * select_memcpy_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { unsigned long long int v; + if (dl_hwcap & COMPAT_HWCAP_ISA_V) + return __memcpy_vector; + if (__riscv_hwprobe_one (hwprobe_func, RISCV_HWPROBE_KEY_CPUPERF_0, &v) == 0 && (v & RISCV_HWPROBE_MISALIGNED_MASK) == RISCV_HWPROBE_MISALIGNED_FAST) return __memcpy_noalignment; diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memmove.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memmove.c index 6aca93fd12..6294069c71 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/memmove.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memmove.c @@ -32,10 +32,13 @@ extern __typeof (__redirect_memmove) __libc_memmove; extern __typeof (__redirect_memmove) __memmove_generic attribute_hidden; +extern __typeof (__redirect_memmove) __memmove_vector attribute_hidden; static inline __typeof (__redirect_memmove) * select_memmove_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { + if (dl_hwcap & COMPAT_HWCAP_ISA_V) + return __memmove_vector; return __memmove_generic; } diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memset.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memset.c index 07ebc59575..28de7ef9d3 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/memset.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memset.c @@ -32,10 +32,13 @@ extern __typeof (__redirect_memset) __libc_memset; extern __typeof (__redirect_memset) __memset_generic attribute_hidden; +extern __typeof (__redirect_memset) __memset_vector attribute_hidden; static inline __typeof (__redirect_memset) * select_memset_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { + if (dl_hwcap & COMPAT_HWCAP_ISA_V) + return __memset_vector; return __memset_generic; } diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strcat.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strcat.c index ca3254a018..d39f01b880 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/strcat.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strcat.c @@ -32,10 +32,13 @@ extern __typeof (__redirect_strcat) __libc_strcat; extern __typeof (__redirect_strcat) __strcat_generic attribute_hidden; +extern __typeof (__redirect_strcat) __strcat_vector attribute_hidden; static inline __typeof (__redirect_strcat) * select_strcat_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { + if (dl_hwcap & COMPAT_HWCAP_ISA_V) + return __strcat_vector; return __strcat_generic; } diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strchr.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strchr.c index a898f96bb8..cd043db06a 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/strchr.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strchr.c @@ -32,10 +32,13 @@ extern __typeof (__redirect_strchr) __libc_strchr; extern __typeof (__redirect_strchr) __strchr_generic attribute_hidden; +extern __typeof (__redirect_strchr) __strchr_vector attribute_hidden; static inline __typeof (__redirect_strchr) * select_strchr_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { + if (dl_hwcap & COMPAT_HWCAP_ISA_V) + return __strchr_vector; return __strchr_generic; } diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strcmp.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strcmp.c index 9fd5c530bd..86a312d7f6 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/strcmp.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strcmp.c @@ -32,10 +32,13 @@ extern __typeof (__redirect_strcmp) __libc_strcmp; extern __typeof (__redirect_strcmp) __strcmp_generic attribute_hidden; +extern __typeof (__redirect_strcmp) __strcmp_vector attribute_hidden; static inline __typeof (__redirect_strcmp) * select_strcmp_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { + if (dl_hwcap & COMPAT_HWCAP_ISA_V) + return __strcmp_vector; return __strcmp_generic; } diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strcpy.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strcpy.c index 473fa7768d..04164885c3 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/strcpy.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strcpy.c @@ -32,10 +32,13 @@ extern __typeof (__redirect_strcpy) __libc_strcpy; extern __typeof (__redirect_strcpy) __strcpy_generic attribute_hidden; +extern __typeof (__redirect_strcpy) __strcpy_vector attribute_hidden; static inline __typeof (__redirect_strcpy) * select_strcpy_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { + if (dl_hwcap & COMPAT_HWCAP_ISA_V) + return __strcpy_vector; return __strcpy_generic; } diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c index 4c15269028..e2fd06d2f4 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strlen.c @@ -32,10 +32,13 @@ extern __typeof (__redirect_strlen) __libc_strlen; extern __typeof (__redirect_strlen) __strlen_generic attribute_hidden; +extern __typeof (__redirect_strlen) __strlen_vector attribute_hidden; static inline __typeof (__redirect_strlen) * select_strlen_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { + if (dl_hwcap & COMPAT_HWCAP_ISA_V) + return __strlen_vector; return __strlen_generic; } diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strncat.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strncat.c index 2dd5b98e56..802011835d 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/strncat.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strncat.c @@ -32,10 +32,13 @@ extern __typeof (__redirect_strncat) __libc_strncat; extern __typeof (__redirect_strncat) __strncat_generic attribute_hidden; +extern __typeof (__redirect_strncat) __strncat_vector attribute_hidden; static inline __typeof (__redirect_strncat) * select_strncat_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { + if (dl_hwcap & COMPAT_HWCAP_ISA_V) + return __strncat_vector; return __strncat_generic; } diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strncmp.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strncmp.c index dc2f3dfbda..d5416c1d81 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/strncmp.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strncmp.c @@ -32,10 +32,13 @@ extern __typeof (__redirect_strncmp) __libc_strncmp; extern __typeof (__redirect_strncmp) __strncmp_generic attribute_hidden; +extern __typeof (__redirect_strncmp) __strncmp_vector attribute_hidden; static inline __typeof (__redirect_strncmp) * select_strncmp_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { + if (dl_hwcap & COMPAT_HWCAP_ISA_V) + return __strncmp_vector; return __strncmp_generic; } diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strncpy.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strncpy.c index 87451820d9..827c331695 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/strncpy.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strncpy.c @@ -32,10 +32,13 @@ extern __typeof (__redirect_strncpy) __libc_strncpy; extern __typeof (__redirect_strncpy) __strncpy_generic attribute_hidden; +extern __typeof (__redirect_strncpy) __strncpy_vector attribute_hidden; static inline __typeof (__redirect_strncpy) * select_strncpy_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { + if (dl_hwcap & COMPAT_HWCAP_ISA_V) + return __strncpy_vector; return __strncpy_generic; } diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/strnlen.c b/sysdeps/unix/sysv/linux/riscv/multiarch/strnlen.c index 1ce4512651..d2e736ad54 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/strnlen.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/strnlen.c @@ -32,10 +32,13 @@ extern __typeof (__redirect_strnlen) __libc_strnlen; extern __typeof (__redirect_strnlen) __strnlen_generic attribute_hidden; +extern __typeof (__redirect_strnlen) __strnlen_vector attribute_hidden; static inline __typeof (__redirect_strnlen) * select_strnlen_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { + if (dl_hwcap & COMPAT_HWCAP_ISA_V) + return __strnlen_vector; return __strnlen_generic; }