From patchwork Tue Sep 30 00:56:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Zihong X-Patchwork-Id: 121018 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 5C95C3857C5F for ; Tue, 30 Sep 2025 00:58:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5C95C3857C5F 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 703513858D3C for ; Tue, 30 Sep 2025 00:57:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 703513858D3C 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 703513858D3C 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=1759193860; cv=none; b=tO8Rzo10n4LX89/RPwm7ra4invJqj9qdyZ9ruEfRdZvW1UryzQaxY78EIx7ItcWsusuvHNsjeF7oyZU82n9+KFPW/MtBUj7/6Yc5tDp6tl+PtYOtiuqTwr6WJGDf5QluDNOxV5n8bhJW/gqSTj5A8Qabzt7tm23XtQJHwDSfgJA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1759193860; c=relaxed/simple; bh=oX+vTbEH1IczyjJYQsRvHk4vd0i/uoydg3Fy5u75XcI=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=r2LLCevK9HLzSvEjBXUs4vwXHDRmv3MrYtXM2AHQ5BKaiZ2jgppvV7inhTYLVVBRpfLod+EQcXslaP38gBTN+PE5BUwkk4Sss5s33eLXNGC2xG7HumlpkkBV5K8/f9A8DGh6PDIGBw0ysviDvhSivW8li1abk74AC2UwKjaP0lI= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 703513858D3C Received: from Mobilestation.localdomain (unknown [183.6.60.69]) by APP-05 (Coremail) with SMTP id zQCowAAHqhPxKttorL0WCQ--.11769S4; Tue, 30 Sep 2025 08:57:31 +0800 (CST) From: Yao Zihong To: libc-alpha@sourceware.org Cc: bergner@linux.ibm.com, evan@rivosinc.com, jlaw@ventanamicro.com, palmer@dabbelt.com, vineetg@rivosinc.com, zhangyin2018@iscas.ac.cn, zihong.plct@isrc.iscas.ac.cn, zihongyao@outlook.com Subject: [RFC PATCH v2 2/4] riscv: Add hwcaps-subdir support for RVA20U64 Date: Tue, 30 Sep 2025 08:56:54 +0800 Message-ID: <20250930005715.95436-3-zihong.plct@isrc.iscas.ac.cn> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250930005715.95436-1-zihong.plct@isrc.iscas.ac.cn> References: <20250930005715.95436-1-zihong.plct@isrc.iscas.ac.cn> MIME-Version: 1.0 X-CM-TRANSID: zQCowAAHqhPxKttorL0WCQ--.11769S4 X-Coremail-Antispam: 1UD129KBjvAXoW3KFyfuF47tr4xtFWkCw45KFg_yoW8Gw1xWo WfWF47Xr4jgrn5Cr4rC347W3y7ur98Wr4xXa98XFZ5Jr18Jr18CryFy3Z7Wr43Kr1rKa1r Aa4xXFWfJF4FqF97n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUYE7AC8VAFwI0_Wr0E3s1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r15M28IrcIa0x kI8VCY1x0267AKxVW8JVW5JwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l84AC jcxK6xIIjxv20xvE14v26r1j6r1xM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4j6F4UM2 8EF7xvwVC2z280aVAFwI0_Jr0_Gr1l84ACjcxK6I8E87Iv6xkF7I0E14v26r4UJVWxJr1l e2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI 8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwAC jcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lc7CjxVAaw2AFwI0_Jw0_GF yl42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWU JVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r1q6r43MIIYrxkI7V AKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j 6F4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42 IY6I8E87Iv6xkF7I0E14v26r4UJVWxJrUvcSsGvfC2KfnxnUUI43ZEXa7VUj5Ef7UUUUU= = X-Originating-IP: [183.6.60.69] X-CM-SenderInfo: p2lk00vjoszunw6l223fol2u1dvotugofq/ X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_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 Introduce glibc-hwcaps subdir "rva20u64" and minimal profile-level infrastructure. This allows ifunc selection (starting with memcpy) to gate RVA20U64 implementations while keeping generic as fallback. Signed-off-by: Yao Zihong --- sysdeps/riscv/Makefile | 11 ++++ sysdeps/riscv/get-profile-level.h | 54 +++++++++++++++ sysdeps/riscv/multiarch/memcpy-generic.c | 5 ++ sysdeps/riscv/multiarch/memcpy_noalignment.S | 5 ++ sysdeps/riscv/profile-ifunc-macros.h | 53 +++++++++++++++ sysdeps/riscv/profile-level.h | 66 +++++++++++++++++++ sysdeps/riscv/rv64/dl-hwcaps-subdirs.c | 40 +++++++++++ .../linux/riscv/multiarch/ifunc-impl-list.c | 11 ++-- .../unix/sysv/linux/riscv/multiarch/memcpy.c | 10 ++- 9 files changed, 248 insertions(+), 7 deletions(-) create mode 100644 sysdeps/riscv/get-profile-level.h create mode 100644 sysdeps/riscv/profile-ifunc-macros.h create mode 100644 sysdeps/riscv/profile-level.h create mode 100644 sysdeps/riscv/rv64/dl-hwcaps-subdirs.c diff --git a/sysdeps/riscv/Makefile b/sysdeps/riscv/Makefile index c08753ae8a..4c52f0d1ea 100644 --- a/sysdeps/riscv/Makefile +++ b/sysdeps/riscv/Makefile @@ -4,6 +4,17 @@ endif ifeq ($(subdir),elf) gen-as-const-headers += dl-link.sym + +$(objpfx)tst-glibc-hwcaps: $(objpfx)libmarkermod2-1.so + +$(objpfx)tst-glibc-hwcaps.out: \ + $(objpfx)libmarkermod2.so \ + $(objpfx)glibc-hwcaps/rva20u64/libmarkermod2.so \ + +$(objpfx)glibc-hwcaps/rva20u64/libmarkermod2.so: $(objpfx)libmarkermod2-2.so + $(make-target-directory) + cp $< $@ + endif # RISC-V's assembler also needs to know about PIC as it changes the definition diff --git a/sysdeps/riscv/get-profile-level.h b/sysdeps/riscv/get-profile-level.h new file mode 100644 index 0000000000..ce98d8f807 --- /dev/null +++ b/sysdeps/riscv/get-profile-level.h @@ -0,0 +1,54 @@ +/* Get RISC-V profile level. + This file is part of the GNU C Library. + Copyright (C) 2025 Free Software Foundation, Inc. + + 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 + +# define PROFILE_MASK_RISCV_RVA20U64 (RISCV_HWPROBE_IMA_FD | RISCV_HWPROBE_IMA_C | \ + RISCV_HWPROBE_EXT_ZICNTR) + +static unsigned int +get_profile_level() +{ + unsigned int profile_level = 0; + struct riscv_hwprobe pair; + + pair.key = RISCV_HWPROBE_KEY_CPUPERF_0; + if (__riscv_hwprobe(&pair, 1, 0, NULL, 0) != 0) { + return profile_level; + } + + if ((pair.value & RISCV_HWPROBE_MISALIGNED_MASK) == \ + RISCV_HWPROBE_MISALIGNED_UNSUPPORTED) { + return profile_level; + } + + pair.key = RISCV_HWPROBE_KEY_IMA_EXT_0; + if (__riscv_hwprobe(&pair, 1, 0, NULL, 0) != 0) { + return profile_level; + } + + // Extensions without explicit detection (yet): + // Ziccif, Ziccrse, Ziccamoa, Za128rs, Zicclsm + if ((pair.value & PROFILE_MASK_RISCV_RVA20U64) != \ + PROFILE_MASK_RISCV_RVA20U64) { + return profile_level; + } + profile_level = 20; + + return profile_level; +} diff --git a/sysdeps/riscv/multiarch/memcpy-generic.c b/sysdeps/riscv/multiarch/memcpy-generic.c index 151dd0e6f9..83fd6ae03f 100644 --- a/sysdeps/riscv/multiarch/memcpy-generic.c +++ b/sysdeps/riscv/multiarch/memcpy-generic.c @@ -17,6 +17,9 @@ . */ #include +#include + +#if PROFILE_SHOULD_BUILD (0) #if IS_IN(libc) # define MEMCPY __memcpy_generic @@ -24,3 +27,5 @@ # define libc_hidden_builtin_def(x) #endif #include + +#endif diff --git a/sysdeps/riscv/multiarch/memcpy_noalignment.S b/sysdeps/riscv/multiarch/memcpy_noalignment.S index dd135f4a4d..8f892ba550 100644 --- a/sysdeps/riscv/multiarch/memcpy_noalignment.S +++ b/sysdeps/riscv/multiarch/memcpy_noalignment.S @@ -18,6 +18,9 @@ #include #include +#include + +#if PROFILE_SHOULD_BUILD (20) /* memcpy optimization for CPUs with fast unaligned support (RISCV_HWPROBE_MISALIGNED_FAST). @@ -160,3 +163,5 @@ L(word_copy_adjust): mv a3, a5 j L(word_copy) END (__memcpy_noalignment) + +#endif diff --git a/sysdeps/riscv/profile-ifunc-macros.h b/sysdeps/riscv/profile-ifunc-macros.h new file mode 100644 index 0000000000..33a16af241 --- /dev/null +++ b/sysdeps/riscv/profile-ifunc-macros.h @@ -0,0 +1,53 @@ +/* Common ifunc selection utils + 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 + . */ + +#ifndef _PROFILE_IFUNC_MACROS_H +#define _PROFILE_IFUNC_MACROS_H + +#include +#include +#include + +/* Only include at the level of the minimum build profile or higher. I.e + if built with profile lower than RVA20, then include all implementations. + On the other hand if built with profile=RVA22/RVA23 only include RVA22/RVA23 + implementations. If there is no implementation at or above the + minimum build profile level, then include the highest profile level + implementation. */ +#if MINIMUM_RISCV_PROFILE_LEVEL <= 20 +# define RISCV_IFUNC_RESOLVE_RVA20(cond, impl) {if(cond) { return impl; }} +# define RISCV_IFUNC_IMPL_ADD_RVA20(...) IFUNC_IMPL_ADD (__VA_ARGS__) +#else +# define RISCV_IFUNC_RESOLVE_RVA20(cond, impl) +# define RISCV_IFUNC_IMPL_ADD_RVA20(...) +#endif + +#if MINIMUM_RISCV_PROFILE_LEVEL <= 0 +# define RISCV_IFUNC_RESOLVE_INIT(cond, impl) {if(cond) { return impl; }} +# define RISCV_IFUNC_IMPL_ADD_INIT(...) IFUNC_IMPL_ADD (__VA_ARGS__) +#else +# define RISCV_IFUNC_RESOLVE_INIT(cond, impl) +# define RISCV_IFUNC_IMPL_ADD_INIT(...) +#endif + +#define RISCV_PROFILE_COND(cond, name) \ + (((name##_RISCV_PROFILE_LEVEL) <= MINIMUM_RISCV_PROFILE_LEVEL) \ + || cond) + +#endif diff --git a/sysdeps/riscv/profile-level.h b/sysdeps/riscv/profile-level.h new file mode 100644 index 0000000000..c846e1beb1 --- /dev/null +++ b/sysdeps/riscv/profile-level.h @@ -0,0 +1,66 @@ +/* Header defining the RISC-V Profile level + 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. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + 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 + . */ + +#ifndef _PROFILE_LEVEL_H +#define _PROFILE_LEVEL_H + +# define MINIMUM_RISCV_PROFILE_LEVEL 0 + +#if defined __riscv_i && defined __riscv_m && defined __riscv_a && \ + defined __riscv_f && defined __riscv_d && defined __riscv_c +# define __RISCV_GC 1 +#else +# define __RISCV_GC 0 +#endif + +#if __RISCV_GC && defined __riscv_zicsr && defined __riscv_zicntr && \ + defined __riscv_ziccif && defined __riscv_ziccrse && \ + defined __riscv_ziccamoa && defined __riscv_za128rs && \ + defined __riscv_zicclsm +# define __RISCV_PROFILE_RVA20 1 +# undef MINIMUM_RISCV_PROFILE_LEVEL +# define MINIMUM_RISCV_PROFILE_LEVEL 20 +#else +# define __RISCV_PROFILE_RVA20 0 +#endif + +/* Profile level >= 20 guaranteed includes. */ +#define FD_RISCV_PROFILE_LEVEL 20 +#define A_RISCV_PROFILE_LEVEL 20 +#define C_RISCV_PROFILE_LEVEL 20 +#define ZICSR_RISCV_PROFILE_LEVEL 20 +#define ZICNTR_RISCV_PROFILE_LEVEL 20 +#define ZICCIF_RISCV_PROFILE_LEVEL 20 +#define ZICCRSE_RISCV_PROFILE_LEVEL 20 +#define ZICCAMOA_RISCV_PROFILE_LEVEL 20 +#define ZA128RS_RISCV_PROFILE_LEVEL 20 +#define ZICCLSM_RISCV_PROFILE_LEVEL 20 + +#define PROFILE_SHOULD_BUILD(profile_build_level) \ + (MINIMUM_RISCV_PROFILE_LEVEL <= (profile_build_level)) + +#endif diff --git a/sysdeps/riscv/rv64/dl-hwcaps-subdirs.c b/sysdeps/riscv/rv64/dl-hwcaps-subdirs.c new file mode 100644 index 0000000000..3a88271ebd --- /dev/null +++ b/sysdeps/riscv/rv64/dl-hwcaps-subdirs.c @@ -0,0 +1,40 @@ +/* Architecture-specific glibc-hwcaps subdirectories. 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 +#include +#include + +const char _dl_hwcaps_subdirs[] = "rva20u64"; +enum { subdirs_count = 1 }; /* Number of components in _dl_hwcaps_subdirs. */ + +uint32_t +_dl_hwcaps_subdirs_active (void) +{ + int active = 0; + + /* Test in reverse preference order. */ + /* v1: RVA20U64 */ + int profile_level = get_profile_level(); + if(profile_level < 20) { + return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active); + } + ++active; + return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active); +} \ No newline at end of file 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..f0271679fd 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/ifunc-impl-list.c @@ -19,6 +19,7 @@ #include #include #include +#include size_t __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, @@ -26,18 +27,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, { size_t i = max; - bool fast_unaligned = false; + bool unaligned = 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; + != RISCV_HWPROBE_MISALIGNED_UNSUPPORTED) + unaligned = true; IFUNC_IMPL (i, name, memcpy, - IFUNC_IMPL_ADD (array, i, memcpy, fast_unaligned, + RISCV_IFUNC_IMPL_ADD_RVA20 (array, i, memcpy, unaligned, __memcpy_noalignment) - IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_generic)) + RISCV_IFUNC_IMPL_ADD_INIT (array, i, memcpy, 1, __memcpy_generic)) return 0; } diff --git a/sysdeps/unix/sysv/linux/riscv/multiarch/memcpy.c b/sysdeps/unix/sysv/linux/riscv/multiarch/memcpy.c index 8544f5402a..353eace6bb 100644 --- a/sysdeps/unix/sysv/linux/riscv/multiarch/memcpy.c +++ b/sysdeps/unix/sysv/linux/riscv/multiarch/memcpy.c @@ -27,6 +27,7 @@ # include # include # include +# include extern __typeof (__redirect_memcpy) __libc_memcpy; @@ -37,10 +38,15 @@ static inline __typeof (__redirect_memcpy) * select_memcpy_ifunc (uint64_t dl_hwcap, __riscv_hwprobe_t hwprobe_func) { unsigned long long int v; + bool unaligned = false; if (__riscv_hwprobe_one (hwprobe_func, RISCV_HWPROBE_KEY_CPUPERF_0, &v) == 0 - && (v & RISCV_HWPROBE_MISALIGNED_MASK) == RISCV_HWPROBE_MISALIGNED_FAST) + && (v & RISCV_HWPROBE_MISALIGNED_MASK) != RISCV_HWPROBE_MISALIGNED_UNSUPPORTED) + unaligned = true; + + if(RISCV_PROFILE_COND(unaligned, ZICCLSM)) { return __memcpy_noalignment; - + } + return __memcpy_generic; }