[compiler-rt] [compiler-rt][RISCV] Implement __riscv_ifunc_select (PR #85790)
Piyou Chen via llvm-commits
llvm-commits at lists.llvm.org
Sun Apr 7 21:35:22 PDT 2024
https://github.com/BeMg updated https://github.com/llvm/llvm-project/pull/85790
>From 446b4a9936967b146c612f7489a8b53c38662e70 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Thu, 14 Mar 2024 05:50:51 -0700
Subject: [PATCH 01/11] [compiler-rt][RISCV] Implement __riscv_ifunc_select
This patch implement the `__riscv_ifunc_select` base on `Hwprobe/cpuinfo`.
```
unsigned __riscv_ifunc_select(char *FeatStrs);
```
The __riscv_ifunc_select function checks if the features specified in FeatStrs are supported.
If all features are available in the current runtime environment, it returns 1. Otherwise, it returns 0.
---
compiler-rt/lib/builtins/CMakeLists.txt | 1 +
compiler-rt/lib/builtins/riscv/ifunc_select.c | 260 ++++++++++++++++++
2 files changed, 261 insertions(+)
create mode 100644 compiler-rt/lib/builtins/riscv/ifunc_select.c
diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt
index f9611574a562b4..c9f82f3c38dbf5 100644
--- a/compiler-rt/lib/builtins/CMakeLists.txt
+++ b/compiler-rt/lib/builtins/CMakeLists.txt
@@ -716,6 +716,7 @@ endif()
set(powerpc64le_SOURCES ${powerpc64_SOURCES})
set(riscv_SOURCES
+ riscv/ifunc_select.c
riscv/fp_mode.c
riscv/save.S
riscv/restore.S
diff --git a/compiler-rt/lib/builtins/riscv/ifunc_select.c b/compiler-rt/lib/builtins/riscv/ifunc_select.c
new file mode 100644
index 00000000000000..75639c19011c13
--- /dev/null
+++ b/compiler-rt/lib/builtins/riscv/ifunc_select.c
@@ -0,0 +1,260 @@
+//=== ifunc_select.c - Check environment hardware feature -*- C -*-===========//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#define BUFSIZE 1024
+
+static void fillzero(char *s, unsigned size) {
+ for (int i = 0; i < size; i++)
+ s[i] = '\0';
+}
+
+static unsigned strcmp(const char *a, const char *b) {
+ while (*a != '\0' && *b != '\0') {
+ if (*a != *b)
+ return 0;
+ a++;
+ b++;
+ }
+ if (*a == *b)
+ return 1;
+ return 0;
+}
+
+static void memcpy(char *dest, const char *src, unsigned len) {
+ for (unsigned i = 0; i < len; i++)
+ dest[i] = src[i];
+}
+
+static unsigned strlen(char *s) {
+ int len = 0;
+ while (*s != '\0') {
+ len++;
+ s++;
+ }
+ return len;
+}
+
+// TODO: Replace with more efficient algorithm
+static unsigned isPatternInSrc(char *src, char *pattern) {
+ char buf[BUFSIZE];
+ int lenOfSrc = strlen(src);
+ int lenOfPattern = strlen(pattern);
+ for (int i = 0; i + lenOfPattern < lenOfSrc; i++) {
+ fillzero(buf, BUFSIZE);
+ memcpy(buf, src + i, lenOfPattern);
+ if (strcmp(buf, pattern))
+ return 1;
+ }
+ return 0;
+}
+
+static char *tokenize(char *src, char *rst, char delim) {
+ while (*src != '\0' && *src != delim) {
+ *rst = *src;
+ src++;
+ rst++;
+ }
+ if (*src == delim)
+ src++;
+ return src;
+}
+
+static void getBasicExtFromHwFeatStr(char *rst, char *src) {
+ while (*src != 'r') {
+ src++;
+ }
+
+ while (*src != '_' && *src != '\0') {
+ *rst = *src;
+ rst++;
+ src++;
+ }
+}
+
+static unsigned checkFeatStrInHwFeatStr(char *FeatStr, char *HwFeatStr) {
+ // For basic extension like a,m,f,d...
+ if (strlen(FeatStr) == 1) {
+ char BasicExt[BUFSIZE];
+ fillzero(BasicExt, BUFSIZE);
+ getBasicExtFromHwFeatStr(BasicExt, HwFeatStr);
+ return isPatternInSrc(BasicExt, FeatStr);
+ }
+ // For zbb,zihintntl...
+ return isPatternInSrc(HwFeatStr, FeatStr);
+}
+
+#if defined(__linux__)
+
+#define SYS_read 63
+#define SYS_openat 56
+#define SYS_riscv_hwprobe 258
+
+static long syscall_impl_3_args(long number, long arg1, long arg2, long arg3) {
+ register long a7 __asm__("a7") = number;
+ register long a0 __asm__("a0") = arg1;
+ register long a1 __asm__("a1") = arg2;
+ register long a2 __asm__("a2") = arg3;
+ __asm__ __volatile__("ecall\n\t"
+ : "=r"(a0)
+ : "r"(a7), "r"(a0), "r"(a1), "r"(a2)
+ : "memory");
+ return a0;
+}
+
+static long syscall_impl_5_args(long number, long arg1, long arg2, long arg3,
+ long arg4, long arg5) {
+ register long a7 __asm__("a7") = number;
+ register long a0 __asm__("a0") = arg1;
+ register long a1 __asm__("a1") = arg2;
+ register long a2 __asm__("a2") = arg3;
+ register long a3 __asm__("a3") = arg4;
+ register long a4 __asm__("a4") = arg5;
+ __asm__ __volatile__("ecall\n\t"
+ : "=r"(a0)
+ : "r"(a7), "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4)
+ : "memory");
+ return a0;
+}
+
+static unsigned read(int fd, const void *buf, unsigned count) {
+ return syscall_impl_3_args(SYS_read, fd, (long)buf, count);
+}
+
+static int openat(int dirfd, const char *pathname, int flags) {
+ return syscall_impl_3_args(SYS_openat, (long)dirfd, (long)pathname, flags);
+}
+
+static void readUntilNextLine(int fd, char *rst, int len) {
+ char buf = '\0';
+ while (buf != '\n' && read(fd, &buf, 1) != 0 && len > 0) {
+ *rst = buf;
+ rst++;
+ len--;
+ }
+}
+
+static void __riscv_cpuinfo(char *FeatStr) {
+ char buf[BUFSIZE];
+ int fd = openat(0, "/proc/cpuinfo", 2);
+ do {
+ fillzero(buf, BUFSIZE);
+ readUntilNextLine(fd, buf, BUFSIZE);
+ if (isPatternInSrc(buf, "isa")) {
+ memcpy(FeatStr, buf, BUFSIZE);
+ return;
+ }
+ } while (strlen(buf) != 0);
+}
+
+struct riscv_hwprobe {
+ long long key;
+ unsigned long long value;
+};
+
+#define RISCV_HWPROBE_MAX_KEY 5
+#define RISCV_HWPROBE_KEY_MVENDORID 0
+#define RISCV_HWPROBE_KEY_MARCHID 1
+#define RISCV_HWPROBE_KEY_MIMPID 2
+#define RISCV_HWPROBE_KEY_BASE_BEHAVIOR 3
+#define RISCV_HWPROBE_BASE_BEHAVIOR_IMA (1 << 0)
+#define RISCV_HWPROBE_KEY_IMA_EXT_0 4
+#define RISCV_HWPROBE_IMA_FD (1 << 0)
+#define RISCV_HWPROBE_IMA_C (1 << 1)
+#define RISCV_HWPROBE_IMA_V (1 << 2)
+#define RISCV_HWPROBE_EXT_ZBA (1 << 3)
+#define RISCV_HWPROBE_EXT_ZBB (1 << 4)
+#define RISCV_HWPROBE_EXT_ZBS (1 << 5)
+#define RISCV_HWPROBE_KEY_CPUPERF_0 5
+#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
+#define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0)
+#define RISCV_HWPROBE_MISALIGNED_SLOW (2 << 0)
+#define RISCV_HWPROBE_MISALIGNED_FAST (3 << 0)
+#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
+#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
+
+/* Size definition for CPU sets. */
+#define __CPU_SETSIZE 1024
+#define __NCPUBITS (8 * sizeof(unsigned long int))
+
+/* Data structure to describe CPU mask. */
+typedef struct {
+ unsigned long int __bits[__CPU_SETSIZE / __NCPUBITS];
+} cpu_set_t;
+
+static long sys_riscv_hwprobe(struct riscv_hwprobe *pairs, unsigned pair_count,
+ unsigned cpu_count, cpu_set_t *cpus,
+ unsigned int flags) {
+ return syscall_impl_5_args(SYS_riscv_hwprobe, (long)pairs, pair_count,
+ cpu_count, (long)cpus, flags);
+}
+
+static void initHwProbe(struct riscv_hwprobe *Hwprobes, int len) {
+ sys_riscv_hwprobe(Hwprobes, len, 0, 0, 0);
+}
+
+static unsigned checkFeatStrInHwProbe(char *FeatStr,
+ struct riscv_hwprobe Hwprobe) {
+ if (Hwprobe.key == -1)
+ return 0;
+
+ if (strcmp(FeatStr, "i"))
+ return Hwprobe.value & RISCV_HWPROBE_KEY_IMA_EXT_0;
+ if (strcmp(FeatStr, "m"))
+ return Hwprobe.value & RISCV_HWPROBE_KEY_IMA_EXT_0;
+ if (strcmp(FeatStr, "a"))
+ return Hwprobe.value & RISCV_HWPROBE_KEY_IMA_EXT_0;
+ if (strcmp(FeatStr, "f"))
+ return Hwprobe.value & RISCV_HWPROBE_IMA_FD;
+ if (strcmp(FeatStr, "d"))
+ return Hwprobe.value & RISCV_HWPROBE_IMA_FD;
+ if (strcmp(FeatStr, "c"))
+ return Hwprobe.value & RISCV_HWPROBE_IMA_C;
+ if (strcmp(FeatStr, "v"))
+ return Hwprobe.value & RISCV_HWPROBE_IMA_V;
+ if (strcmp(FeatStr, "zba"))
+ return Hwprobe.value & RISCV_HWPROBE_EXT_ZBA;
+ if (strcmp(FeatStr, "zbb"))
+ return Hwprobe.value & RISCV_HWPROBE_EXT_ZBB;
+ if (strcmp(FeatStr, "zbs"))
+ return Hwprobe.value & RISCV_HWPROBE_EXT_ZBS;
+
+ return 0;
+}
+#endif // defined(__linux__)
+
+// FeatStr format is like <Feature1>;<Feature2>...<FeatureN>.
+unsigned __riscv_ifunc_select(char *FeatStrs) {
+#if defined(__linux__)
+ // Init Hwprobe
+ struct riscv_hwprobe pairs[] = {
+ {RISCV_HWPROBE_KEY_IMA_EXT_0, 0},
+ };
+ initHwProbe(pairs, 1);
+ // Init from cpuinfo
+ char HwFeatStr[BUFSIZE];
+ fillzero(HwFeatStr, BUFSIZE);
+ __riscv_cpuinfo(HwFeatStr);
+
+ // Check each extension whether available
+ char FeatStr[BUFSIZE];
+ while (*FeatStrs != '\0') {
+ fillzero(FeatStr, BUFSIZE);
+ FeatStrs = tokenize(FeatStrs, FeatStr, ';');
+ if (checkFeatStrInHwProbe(FeatStr, pairs[0]))
+ continue;
+ if (!checkFeatStrInHwFeatStr(FeatStr, HwFeatStr))
+ return 0;
+ }
+
+ return 1;
+#else
+ // If other platform support IFUNC, need to implement its
+ // __riscv_ifunc_select.
+ return 0;
+#endif
+}
>From 60848d3e4fda19a2ac0c2571d68eb3ee18c7a773 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Sat, 30 Mar 2024 04:07:35 -0700
Subject: [PATCH 02/11] Use bitset instead of string
---
compiler-rt/lib/builtins/riscv/ifunc_select.c | 225 ++++--------------
1 file changed, 52 insertions(+), 173 deletions(-)
diff --git a/compiler-rt/lib/builtins/riscv/ifunc_select.c b/compiler-rt/lib/builtins/riscv/ifunc_select.c
index 75639c19011c13..93269054835c29 100644
--- a/compiler-rt/lib/builtins/riscv/ifunc_select.c
+++ b/compiler-rt/lib/builtins/riscv/ifunc_select.c
@@ -6,106 +6,9 @@
//
//===----------------------------------------------------------------------===//
-#define BUFSIZE 1024
-
-static void fillzero(char *s, unsigned size) {
- for (int i = 0; i < size; i++)
- s[i] = '\0';
-}
-
-static unsigned strcmp(const char *a, const char *b) {
- while (*a != '\0' && *b != '\0') {
- if (*a != *b)
- return 0;
- a++;
- b++;
- }
- if (*a == *b)
- return 1;
- return 0;
-}
-
-static void memcpy(char *dest, const char *src, unsigned len) {
- for (unsigned i = 0; i < len; i++)
- dest[i] = src[i];
-}
-
-static unsigned strlen(char *s) {
- int len = 0;
- while (*s != '\0') {
- len++;
- s++;
- }
- return len;
-}
-
-// TODO: Replace with more efficient algorithm
-static unsigned isPatternInSrc(char *src, char *pattern) {
- char buf[BUFSIZE];
- int lenOfSrc = strlen(src);
- int lenOfPattern = strlen(pattern);
- for (int i = 0; i + lenOfPattern < lenOfSrc; i++) {
- fillzero(buf, BUFSIZE);
- memcpy(buf, src + i, lenOfPattern);
- if (strcmp(buf, pattern))
- return 1;
- }
- return 0;
-}
-
-static char *tokenize(char *src, char *rst, char delim) {
- while (*src != '\0' && *src != delim) {
- *rst = *src;
- src++;
- rst++;
- }
- if (*src == delim)
- src++;
- return src;
-}
-
-static void getBasicExtFromHwFeatStr(char *rst, char *src) {
- while (*src != 'r') {
- src++;
- }
-
- while (*src != '_' && *src != '\0') {
- *rst = *src;
- rst++;
- src++;
- }
-}
-
-static unsigned checkFeatStrInHwFeatStr(char *FeatStr, char *HwFeatStr) {
- // For basic extension like a,m,f,d...
- if (strlen(FeatStr) == 1) {
- char BasicExt[BUFSIZE];
- fillzero(BasicExt, BUFSIZE);
- getBasicExtFromHwFeatStr(BasicExt, HwFeatStr);
- return isPatternInSrc(BasicExt, FeatStr);
- }
- // For zbb,zihintntl...
- return isPatternInSrc(HwFeatStr, FeatStr);
-}
-
#if defined(__linux__)
-#define SYS_read 63
-#define SYS_openat 56
#define SYS_riscv_hwprobe 258
-
-static long syscall_impl_3_args(long number, long arg1, long arg2, long arg3) {
- register long a7 __asm__("a7") = number;
- register long a0 __asm__("a0") = arg1;
- register long a1 __asm__("a1") = arg2;
- register long a2 __asm__("a2") = arg3;
- __asm__ __volatile__("ecall\n\t"
- : "=r"(a0)
- : "r"(a7), "r"(a0), "r"(a1), "r"(a2)
- : "memory");
- return a0;
-}
-
static long syscall_impl_5_args(long number, long arg1, long arg2, long arg3,
long arg4, long arg5) {
register long a7 __asm__("a7") = number;
@@ -121,42 +24,12 @@ static long syscall_impl_5_args(long number, long arg1, long arg2, long arg3,
return a0;
}
-static unsigned read(int fd, const void *buf, unsigned count) {
- return syscall_impl_3_args(SYS_read, fd, (long)buf, count);
-}
-
-static int openat(int dirfd, const char *pathname, int flags) {
- return syscall_impl_3_args(SYS_openat, (long)dirfd, (long)pathname, flags);
-}
-
-static void readUntilNextLine(int fd, char *rst, int len) {
- char buf = '\0';
- while (buf != '\n' && read(fd, &buf, 1) != 0 && len > 0) {
- *rst = buf;
- rst++;
- len--;
- }
-}
-
-static void __riscv_cpuinfo(char *FeatStr) {
- char buf[BUFSIZE];
- int fd = openat(0, "/proc/cpuinfo", 2);
- do {
- fillzero(buf, BUFSIZE);
- readUntilNextLine(fd, buf, BUFSIZE);
- if (isPatternInSrc(buf, "isa")) {
- memcpy(FeatStr, buf, BUFSIZE);
- return;
- }
- } while (strlen(buf) != 0);
-}
-
struct riscv_hwprobe {
long long key;
unsigned long long value;
};
-#define RISCV_HWPROBE_MAX_KEY 5
+// Note: sync with linux/arch/riscv/include/uapi/asm/hwprobe.h
#define RISCV_HWPROBE_KEY_MVENDORID 0
#define RISCV_HWPROBE_KEY_MARCHID 1
#define RISCV_HWPROBE_KEY_MIMPID 2
@@ -169,6 +42,36 @@ struct riscv_hwprobe {
#define RISCV_HWPROBE_EXT_ZBA (1 << 3)
#define RISCV_HWPROBE_EXT_ZBB (1 << 4)
#define RISCV_HWPROBE_EXT_ZBS (1 << 5)
+#define RISCV_HWPROBE_EXT_ZICBOZ (1 << 6)
+#define RISCV_HWPROBE_EXT_ZBC (1 << 7)
+#define RISCV_HWPROBE_EXT_ZBKB (1 << 8)
+#define RISCV_HWPROBE_EXT_ZBKC (1 << 9)
+#define RISCV_HWPROBE_EXT_ZBKX (1 << 10)
+#define RISCV_HWPROBE_EXT_ZKND (1 << 11)
+#define RISCV_HWPROBE_EXT_ZKNE (1 << 12)
+#define RISCV_HWPROBE_EXT_ZKNH (1 << 13)
+#define RISCV_HWPROBE_EXT_ZKSED (1 << 14)
+#define RISCV_HWPROBE_EXT_ZKSH (1 << 15)
+#define RISCV_HWPROBE_EXT_ZKT (1 << 16)
+#define RISCV_HWPROBE_EXT_ZVBB (1 << 17)
+#define RISCV_HWPROBE_EXT_ZVBC (1 << 18)
+#define RISCV_HWPROBE_EXT_ZVKB (1 << 19)
+#define RISCV_HWPROBE_EXT_ZVKG (1 << 20)
+#define RISCV_HWPROBE_EXT_ZVKNED (1 << 21)
+#define RISCV_HWPROBE_EXT_ZVKNHA (1 << 22)
+#define RISCV_HWPROBE_EXT_ZVKNHB (1 << 23)
+#define RISCV_HWPROBE_EXT_ZVKSED (1 << 24)
+#define RISCV_HWPROBE_EXT_ZVKSH (1 << 25)
+#define RISCV_HWPROBE_EXT_ZVKT (1 << 26)
+#define RISCV_HWPROBE_EXT_ZFH (1 << 27)
+#define RISCV_HWPROBE_EXT_ZFHMIN (1 << 28)
+#define RISCV_HWPROBE_EXT_ZIHINTNTL (1 << 29)
+#define RISCV_HWPROBE_EXT_ZVFH (1 << 30)
+#define RISCV_HWPROBE_EXT_ZVFHMIN (1 << 31)
+#define RISCV_HWPROBE_EXT_ZFA (1ULL << 32)
+#define RISCV_HWPROBE_EXT_ZTSO (1ULL << 33)
+#define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34)
+#define RISCV_HWPROBE_EXT_ZICOND (1ULL << 35)
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
#define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0)
@@ -176,6 +79,11 @@ struct riscv_hwprobe {
#define RISCV_HWPROBE_MISALIGNED_FAST (3 << 0)
#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
+#define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6
+/* Increase RISCV_HWPROBE_MAX_KEY when adding items. */
+
+/* Flags */
+#define RISCV_HWPROBE_WHICH_CPUS (1 << 0)
/* Size definition for CPU sets. */
#define __CPU_SETSIZE 1024
@@ -197,59 +105,30 @@ static void initHwProbe(struct riscv_hwprobe *Hwprobes, int len) {
sys_riscv_hwprobe(Hwprobes, len, 0, 0, 0);
}
-static unsigned checkFeatStrInHwProbe(char *FeatStr,
- struct riscv_hwprobe Hwprobe) {
- if (Hwprobe.key == -1)
- return 0;
-
- if (strcmp(FeatStr, "i"))
- return Hwprobe.value & RISCV_HWPROBE_KEY_IMA_EXT_0;
- if (strcmp(FeatStr, "m"))
- return Hwprobe.value & RISCV_HWPROBE_KEY_IMA_EXT_0;
- if (strcmp(FeatStr, "a"))
- return Hwprobe.value & RISCV_HWPROBE_KEY_IMA_EXT_0;
- if (strcmp(FeatStr, "f"))
- return Hwprobe.value & RISCV_HWPROBE_IMA_FD;
- if (strcmp(FeatStr, "d"))
- return Hwprobe.value & RISCV_HWPROBE_IMA_FD;
- if (strcmp(FeatStr, "c"))
- return Hwprobe.value & RISCV_HWPROBE_IMA_C;
- if (strcmp(FeatStr, "v"))
- return Hwprobe.value & RISCV_HWPROBE_IMA_V;
- if (strcmp(FeatStr, "zba"))
- return Hwprobe.value & RISCV_HWPROBE_EXT_ZBA;
- if (strcmp(FeatStr, "zbb"))
- return Hwprobe.value & RISCV_HWPROBE_EXT_ZBB;
- if (strcmp(FeatStr, "zbs"))
- return Hwprobe.value & RISCV_HWPROBE_EXT_ZBS;
-
- return 0;
-}
#endif // defined(__linux__)
-// FeatStr format is like <Feature1>;<Feature2>...<FeatureN>.
-unsigned __riscv_ifunc_select(char *FeatStrs) {
+unsigned __riscv_ifunc_select(unsigned long long BaseKey,
+ unsigned long long IMAKey) {
#if defined(__linux__)
// Init Hwprobe
struct riscv_hwprobe pairs[] = {
+ {RISCV_HWPROBE_KEY_BASE_BEHAVIOR, 0},
{RISCV_HWPROBE_KEY_IMA_EXT_0, 0},
};
- initHwProbe(pairs, 1);
- // Init from cpuinfo
- char HwFeatStr[BUFSIZE];
- fillzero(HwFeatStr, BUFSIZE);
- __riscv_cpuinfo(HwFeatStr);
+ initHwProbe(pairs, 2);
+
+ // sys_riscv_hwprobe key is unknown to the kernel
+ if (pairs[0].key == -1 || pairs[1].key == -1)
+ return 0;
+
+ // Check KEY_BASE_BEHAVIOR
+ if ((BaseKey & pairs[0].value) != BaseKey)
+ return 0;
+
+ if ((IMAKey & pairs[1].value) != IMAKey)
+ return 0;
- // Check each extension whether available
- char FeatStr[BUFSIZE];
- while (*FeatStrs != '\0') {
- fillzero(FeatStr, BUFSIZE);
- FeatStrs = tokenize(FeatStrs, FeatStr, ';');
- if (checkFeatStrInHwProbe(FeatStr, pairs[0]))
- continue;
- if (!checkFeatStrInHwFeatStr(FeatStr, HwFeatStr))
- return 0;
- }
+ // Check KEY_IMA_EXT_0
return 1;
#else
>From 6022ee358d7a1c493f7ca989ebd658c47c70daff Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Sun, 31 Mar 2024 19:20:56 -0700
Subject: [PATCH 03/11] Fixup comment
---
compiler-rt/lib/builtins/riscv/ifunc_select.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/compiler-rt/lib/builtins/riscv/ifunc_select.c b/compiler-rt/lib/builtins/riscv/ifunc_select.c
index 93269054835c29..cbfd2df74d7228 100644
--- a/compiler-rt/lib/builtins/riscv/ifunc_select.c
+++ b/compiler-rt/lib/builtins/riscv/ifunc_select.c
@@ -125,11 +125,10 @@ unsigned __riscv_ifunc_select(unsigned long long BaseKey,
if ((BaseKey & pairs[0].value) != BaseKey)
return 0;
+ // Check KEY_IMA_EXT_0
if ((IMAKey & pairs[1].value) != IMAKey)
return 0;
- // Check KEY_IMA_EXT_0
-
return 1;
#else
// If other platform support IFUNC, need to implement its
>From 368789deb0dfaef0e8bf8e8d27751c0f5b6ec623 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Sun, 31 Mar 2024 19:22:26 -0700
Subject: [PATCH 04/11] Make SYS_riscv_hwprobe closer to use
---
compiler-rt/lib/builtins/riscv/ifunc_select.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/compiler-rt/lib/builtins/riscv/ifunc_select.c b/compiler-rt/lib/builtins/riscv/ifunc_select.c
index cbfd2df74d7228..5e98caeada286b 100644
--- a/compiler-rt/lib/builtins/riscv/ifunc_select.c
+++ b/compiler-rt/lib/builtins/riscv/ifunc_select.c
@@ -8,7 +8,6 @@
#if defined(__linux__)
-#define SYS_riscv_hwprobe 258
static long syscall_impl_5_args(long number, long arg1, long arg2, long arg3,
long arg4, long arg5) {
register long a7 __asm__("a7") = number;
@@ -94,6 +93,7 @@ typedef struct {
unsigned long int __bits[__CPU_SETSIZE / __NCPUBITS];
} cpu_set_t;
+#define SYS_riscv_hwprobe 258
static long sys_riscv_hwprobe(struct riscv_hwprobe *pairs, unsigned pair_count,
unsigned cpu_count, cpu_set_t *cpus,
unsigned int flags) {
>From 8b2aa7d176143a8ab46d8855111a1ff720a1b2d7 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Sun, 31 Mar 2024 19:25:33 -0700
Subject: [PATCH 05/11] Update hwprobe relate comment
---
compiler-rt/lib/builtins/riscv/ifunc_select.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/compiler-rt/lib/builtins/riscv/ifunc_select.c b/compiler-rt/lib/builtins/riscv/ifunc_select.c
index 5e98caeada286b..fac8bea07c3e6a 100644
--- a/compiler-rt/lib/builtins/riscv/ifunc_select.c
+++ b/compiler-rt/lib/builtins/riscv/ifunc_select.c
@@ -28,7 +28,7 @@ struct riscv_hwprobe {
unsigned long long value;
};
-// Note: sync with linux/arch/riscv/include/uapi/asm/hwprobe.h
+// Note: sync with https://docs.kernel.org/arch/riscv/hwprobe.html
#define RISCV_HWPROBE_KEY_MVENDORID 0
#define RISCV_HWPROBE_KEY_MARCHID 1
#define RISCV_HWPROBE_KEY_MIMPID 2
>From 7e1dc72d7279f9ccf850ce145d379aad7d8942ad Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Sun, 31 Mar 2024 19:29:52 -0700
Subject: [PATCH 06/11] Pass NULL-like form for cpu_set_t *cpus
---
compiler-rt/lib/builtins/riscv/ifunc_select.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/compiler-rt/lib/builtins/riscv/ifunc_select.c b/compiler-rt/lib/builtins/riscv/ifunc_select.c
index fac8bea07c3e6a..13a4582fd1add1 100644
--- a/compiler-rt/lib/builtins/riscv/ifunc_select.c
+++ b/compiler-rt/lib/builtins/riscv/ifunc_select.c
@@ -102,7 +102,7 @@ static long sys_riscv_hwprobe(struct riscv_hwprobe *pairs, unsigned pair_count,
}
static void initHwProbe(struct riscv_hwprobe *Hwprobes, int len) {
- sys_riscv_hwprobe(Hwprobes, len, 0, 0, 0);
+ sys_riscv_hwprobe(Hwprobes, len, 0, (cpu_set_t *)((void*) 0), 0);
}
#endif // defined(__linux__)
>From 822358039cae1d1e9c24289c8063c763098e0c9c Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Sun, 31 Mar 2024 19:36:07 -0700
Subject: [PATCH 07/11] Fix format issue
---
compiler-rt/lib/builtins/riscv/ifunc_select.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/compiler-rt/lib/builtins/riscv/ifunc_select.c b/compiler-rt/lib/builtins/riscv/ifunc_select.c
index 13a4582fd1add1..f8678473ae0747 100644
--- a/compiler-rt/lib/builtins/riscv/ifunc_select.c
+++ b/compiler-rt/lib/builtins/riscv/ifunc_select.c
@@ -102,7 +102,7 @@ static long sys_riscv_hwprobe(struct riscv_hwprobe *pairs, unsigned pair_count,
}
static void initHwProbe(struct riscv_hwprobe *Hwprobes, int len) {
- sys_riscv_hwprobe(Hwprobes, len, 0, (cpu_set_t *)((void*) 0), 0);
+ sys_riscv_hwprobe(Hwprobes, len, 0, (cpu_set_t *)((void *)0), 0);
}
#endif // defined(__linux__)
>From 4a3f4b65ebceaf6a15b0e336435eb16925ab0ac3 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Wed, 3 Apr 2024 02:17:32 -0700
Subject: [PATCH 08/11] [compiler-rt] Update __riscv_ifunc_select prototype
---
compiler-rt/lib/builtins/riscv/ifunc_select.c | 37 ++++++++++---------
1 file changed, 19 insertions(+), 18 deletions(-)
diff --git a/compiler-rt/lib/builtins/riscv/ifunc_select.c b/compiler-rt/lib/builtins/riscv/ifunc_select.c
index f8678473ae0747..580c18ea88bff9 100644
--- a/compiler-rt/lib/builtins/riscv/ifunc_select.c
+++ b/compiler-rt/lib/builtins/riscv/ifunc_select.c
@@ -101,34 +101,35 @@ static long sys_riscv_hwprobe(struct riscv_hwprobe *pairs, unsigned pair_count,
cpu_count, (long)cpus, flags);
}
-static void initHwProbe(struct riscv_hwprobe *Hwprobes, int len) {
- sys_riscv_hwprobe(Hwprobes, len, 0, (cpu_set_t *)((void *)0), 0);
+static long initHwProbe(struct riscv_hwprobe *Hwprobes, int len) {
+ return sys_riscv_hwprobe(Hwprobes, len, 0, (cpu_set_t *)((void *)0), 0);
}
#endif // defined(__linux__)
-unsigned __riscv_ifunc_select(unsigned long long BaseKey,
- unsigned long long IMAKey) {
+unsigned __riscv_ifunc_select(struct riscv_hwprobe *ReqirePreKey,
+ unsigned Length) {
#if defined(__linux__)
// Init Hwprobe
- struct riscv_hwprobe pairs[] = {
- {RISCV_HWPROBE_KEY_BASE_BEHAVIOR, 0},
- {RISCV_HWPROBE_KEY_IMA_EXT_0, 0},
- };
- initHwProbe(pairs, 2);
-
- // sys_riscv_hwprobe key is unknown to the kernel
- if (pairs[0].key == -1 || pairs[1].key == -1)
- return 0;
+ struct riscv_hwprobe Pairs[64];
- // Check KEY_BASE_BEHAVIOR
- if ((BaseKey & pairs[0].value) != BaseKey)
- return 0;
+ for (unsigned Idx = 0; Idx < Length; Idx++) {
+ Pairs[Idx].key = ReqirePreKey[Idx].key;
+ Pairs[Idx].value = 0;
+ }
- // Check KEY_IMA_EXT_0
- if ((IMAKey & pairs[1].value) != IMAKey)
+ // hwprobe not success
+ if (initHwProbe(Pairs, 2))
return 0;
+ for (unsigned Idx = 0; Idx < Length; Idx++) {
+ if (Pairs[Idx].key == -1)
+ return 0;
+
+ if ((ReqirePreKey[Idx].value & Pairs[Idx].value) != ReqirePreKey[Idx].value)
+ return 0;
+ }
+
return 1;
#else
// If other platform support IFUNC, need to implement its
>From 305af7dffd2e92f2137d5027e0e888f4922df0f6 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Sun, 7 Apr 2024 21:26:08 -0700
Subject: [PATCH 09/11] [NFC] Rename ReqirePreKey to ReqireKeys
---
compiler-rt/lib/builtins/riscv/ifunc_select.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/compiler-rt/lib/builtins/riscv/ifunc_select.c b/compiler-rt/lib/builtins/riscv/ifunc_select.c
index 580c18ea88bff9..0e7eb757f2aa30 100644
--- a/compiler-rt/lib/builtins/riscv/ifunc_select.c
+++ b/compiler-rt/lib/builtins/riscv/ifunc_select.c
@@ -107,14 +107,14 @@ static long initHwProbe(struct riscv_hwprobe *Hwprobes, int len) {
#endif // defined(__linux__)
-unsigned __riscv_ifunc_select(struct riscv_hwprobe *ReqirePreKey,
+unsigned __riscv_ifunc_select(struct riscv_hwprobe *ReqireKeys,
unsigned Length) {
#if defined(__linux__)
// Init Hwprobe
struct riscv_hwprobe Pairs[64];
for (unsigned Idx = 0; Idx < Length; Idx++) {
- Pairs[Idx].key = ReqirePreKey[Idx].key;
+ Pairs[Idx].key = ReqireKeys[Idx].key;
Pairs[Idx].value = 0;
}
@@ -126,7 +126,7 @@ unsigned __riscv_ifunc_select(struct riscv_hwprobe *ReqirePreKey,
if (Pairs[Idx].key == -1)
return 0;
- if ((ReqirePreKey[Idx].value & Pairs[Idx].value) != ReqirePreKey[Idx].value)
+ if ((ReqireKeys[Idx].value & Pairs[Idx].value) != ReqireKeys[Idx].value)
return 0;
}
>From f39b2cc4ef5d64580bd0f1abbd014ee1a61d9160 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Sun, 7 Apr 2024 21:32:14 -0700
Subject: [PATCH 10/11] [NFC] Rename Pairs to HwprobePairs
---
compiler-rt/lib/builtins/riscv/ifunc_select.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/compiler-rt/lib/builtins/riscv/ifunc_select.c b/compiler-rt/lib/builtins/riscv/ifunc_select.c
index 0e7eb757f2aa30..4a93944be8129f 100644
--- a/compiler-rt/lib/builtins/riscv/ifunc_select.c
+++ b/compiler-rt/lib/builtins/riscv/ifunc_select.c
@@ -111,22 +111,22 @@ unsigned __riscv_ifunc_select(struct riscv_hwprobe *ReqireKeys,
unsigned Length) {
#if defined(__linux__)
// Init Hwprobe
- struct riscv_hwprobe Pairs[64];
+ struct riscv_hwprobe HwprobePairs[64];
for (unsigned Idx = 0; Idx < Length; Idx++) {
- Pairs[Idx].key = ReqireKeys[Idx].key;
- Pairs[Idx].value = 0;
+ HwprobePairs[Idx].key = ReqireKeys[Idx].key;
+ HwprobePairs[Idx].value = 0;
}
// hwprobe not success
- if (initHwProbe(Pairs, 2))
+ if (initHwProbe(HwprobePairs, 2))
return 0;
for (unsigned Idx = 0; Idx < Length; Idx++) {
- if (Pairs[Idx].key == -1)
+ if (HwprobePairs[Idx].key == -1)
return 0;
- if ((ReqireKeys[Idx].value & Pairs[Idx].value) != ReqireKeys[Idx].value)
+ if ((ReqireKeys[Idx].value & HwprobePairs[Idx].value) != ReqireKeys[Idx].value)
return 0;
}
>From a0ad273c03a9f43dcccee3de8a469a7feedcd601 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Sun, 7 Apr 2024 21:34:45 -0700
Subject: [PATCH 11/11] Move sys_hwprobe define key into caller site
---
compiler-rt/lib/builtins/riscv/ifunc_select.c | 56 -------------------
1 file changed, 56 deletions(-)
diff --git a/compiler-rt/lib/builtins/riscv/ifunc_select.c b/compiler-rt/lib/builtins/riscv/ifunc_select.c
index 4a93944be8129f..1e235fa8451cd8 100644
--- a/compiler-rt/lib/builtins/riscv/ifunc_select.c
+++ b/compiler-rt/lib/builtins/riscv/ifunc_select.c
@@ -28,62 +28,6 @@ struct riscv_hwprobe {
unsigned long long value;
};
-// Note: sync with https://docs.kernel.org/arch/riscv/hwprobe.html
-#define RISCV_HWPROBE_KEY_MVENDORID 0
-#define RISCV_HWPROBE_KEY_MARCHID 1
-#define RISCV_HWPROBE_KEY_MIMPID 2
-#define RISCV_HWPROBE_KEY_BASE_BEHAVIOR 3
-#define RISCV_HWPROBE_BASE_BEHAVIOR_IMA (1 << 0)
-#define RISCV_HWPROBE_KEY_IMA_EXT_0 4
-#define RISCV_HWPROBE_IMA_FD (1 << 0)
-#define RISCV_HWPROBE_IMA_C (1 << 1)
-#define RISCV_HWPROBE_IMA_V (1 << 2)
-#define RISCV_HWPROBE_EXT_ZBA (1 << 3)
-#define RISCV_HWPROBE_EXT_ZBB (1 << 4)
-#define RISCV_HWPROBE_EXT_ZBS (1 << 5)
-#define RISCV_HWPROBE_EXT_ZICBOZ (1 << 6)
-#define RISCV_HWPROBE_EXT_ZBC (1 << 7)
-#define RISCV_HWPROBE_EXT_ZBKB (1 << 8)
-#define RISCV_HWPROBE_EXT_ZBKC (1 << 9)
-#define RISCV_HWPROBE_EXT_ZBKX (1 << 10)
-#define RISCV_HWPROBE_EXT_ZKND (1 << 11)
-#define RISCV_HWPROBE_EXT_ZKNE (1 << 12)
-#define RISCV_HWPROBE_EXT_ZKNH (1 << 13)
-#define RISCV_HWPROBE_EXT_ZKSED (1 << 14)
-#define RISCV_HWPROBE_EXT_ZKSH (1 << 15)
-#define RISCV_HWPROBE_EXT_ZKT (1 << 16)
-#define RISCV_HWPROBE_EXT_ZVBB (1 << 17)
-#define RISCV_HWPROBE_EXT_ZVBC (1 << 18)
-#define RISCV_HWPROBE_EXT_ZVKB (1 << 19)
-#define RISCV_HWPROBE_EXT_ZVKG (1 << 20)
-#define RISCV_HWPROBE_EXT_ZVKNED (1 << 21)
-#define RISCV_HWPROBE_EXT_ZVKNHA (1 << 22)
-#define RISCV_HWPROBE_EXT_ZVKNHB (1 << 23)
-#define RISCV_HWPROBE_EXT_ZVKSED (1 << 24)
-#define RISCV_HWPROBE_EXT_ZVKSH (1 << 25)
-#define RISCV_HWPROBE_EXT_ZVKT (1 << 26)
-#define RISCV_HWPROBE_EXT_ZFH (1 << 27)
-#define RISCV_HWPROBE_EXT_ZFHMIN (1 << 28)
-#define RISCV_HWPROBE_EXT_ZIHINTNTL (1 << 29)
-#define RISCV_HWPROBE_EXT_ZVFH (1 << 30)
-#define RISCV_HWPROBE_EXT_ZVFHMIN (1 << 31)
-#define RISCV_HWPROBE_EXT_ZFA (1ULL << 32)
-#define RISCV_HWPROBE_EXT_ZTSO (1ULL << 33)
-#define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34)
-#define RISCV_HWPROBE_EXT_ZICOND (1ULL << 35)
-#define RISCV_HWPROBE_KEY_CPUPERF_0 5
-#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
-#define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0)
-#define RISCV_HWPROBE_MISALIGNED_SLOW (2 << 0)
-#define RISCV_HWPROBE_MISALIGNED_FAST (3 << 0)
-#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
-#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
-#define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6
-/* Increase RISCV_HWPROBE_MAX_KEY when adding items. */
-
-/* Flags */
-#define RISCV_HWPROBE_WHICH_CPUS (1 << 0)
-
/* Size definition for CPU sets. */
#define __CPU_SETSIZE 1024
#define __NCPUBITS (8 * sizeof(unsigned long int))
More information about the llvm-commits
mailing list