Skip to content

Commit 5789d6e

Browse files
a4lgtaiki-e
andcommitted
RISC-V: riscv_hwprobe-based feature detection on Linux / Android
This commit implements `riscv_hwprobe`-based feature detection as available on newer versions of the Linux kernel. It also queries whether the vector extensions are enabled using `prctl` but this is not supported on QEMU's userland emulator (as of version 9.2.3) and use the auxiliary vector as a fallback. Currently, all extensions discoverable from the Linux kernel version 6.14 and related extension groups (except "Supm", which reports the existence of `prctl`-based pointer masking control and too OS-dependent) are implemented. Co-Authored-By: Taiki Endo <[email protected]>
1 parent bed976a commit 5789d6e

File tree

5 files changed

+492
-5
lines changed

5 files changed

+492
-5
lines changed

crates/std_detect/README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,14 @@ crate from working on applications in which `std` is not available.
5656
[`cupid`](https://crates.io/crates/cupid) crate.
5757

5858
* Linux/Android:
59-
* `arm{32, 64}`, `mips{32,64}{,el}`, `powerpc{32,64}{,le}`, `riscv{32,64}`, `loongarch64`, `s390x`:
59+
* `arm{32, 64}`, `mips{32,64}{,el}`, `powerpc{32,64}{,le}`, `loongarch64`, `s390x`:
6060
`std_detect` supports these on Linux by querying ELF auxiliary vectors (using `getauxval`
6161
when available), and if that fails, by querying `/proc/cpuinfo`.
6262
* `arm64`: partial support for doing run-time feature detection by directly
6363
querying `mrs` is implemented for Linux >= 4.11, but not enabled by default.
64+
* `riscv{32,64}`:
65+
`std_detect` supports these on Linux by querying `riscv_hwprobe`, and
66+
by querying ELF auxiliary vectors (using `getauxval` when available).
6467

6568
* FreeBSD:
6669
* `arm32`, `powerpc64`: `std_detect` supports these on FreeBSD by querying ELF

crates/std_detect/src/detect/arch/riscv.rs

+130
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,39 @@ features! {
3737
/// * Zbb: `"zbb"`
3838
/// * Zbs: `"zbs"`
3939
/// * C: `"c"`
40+
/// * Zca: `"zca"`
41+
/// * Zcd: `"zcd"` (if D is enabled)
42+
/// * Zcf: `"zcf"` (if F is enabled on RV32)
4043
/// * D: `"d"`
4144
/// * F: `"f"`
4245
/// * M: `"m"`
4346
/// * Q: `"q"`
4447
/// * V: `"v"`
48+
/// * Zve32x: `"zve32x"`
49+
/// * Zve32f: `"zve32f"`
50+
/// * Zve64x: `"zve64x"`
51+
/// * Zve64f: `"zve64f"`
52+
/// * Zve64d: `"zve64d"`
53+
/// * Zicboz: `"zicboz"`
4554
/// * Zicntr: `"zicntr"`
55+
/// * Zicond: `"zicond"`
4656
/// * Zicsr: `"zicsr"`
4757
/// * Zifencei: `"zifencei"`
58+
/// * Zihintntl: `"zihintntl"`
4859
/// * Zihintpause: `"zihintpause"`
4960
/// * Zihpm: `"zihpm"`
61+
/// * Zimop: `"zimop"`
62+
/// * Zacas: `"zacas"`
63+
/// * Zawrs: `"zawrs"`
64+
/// * Zfa: `"zfa"`
5065
/// * Zfh: `"zfh"`
5166
/// * Zfhmin: `"zfhmin"`
5267
/// * Zfinx: `"zfinx"`
5368
/// * Zdinx: `"zdinx"`
5469
/// * Zhinx: `"zhinx"`
5570
/// * Zhinxmin: `"zhinxmin"`
71+
/// * Zcb: `"zcb"`
72+
/// * Zcmop: `"zcmop"`
5673
/// * Zbc: `"zbc"`
5774
/// * Zbkb: `"zbkb"`
5875
/// * Zbkc: `"zbkc"`
@@ -67,6 +84,24 @@ features! {
6784
/// * Zksed: `"zksed"`
6885
/// * Zksh: `"zksh"`
6986
/// * Zkt: `"zkt"`
87+
/// * Zvbb: `"zvbb"`
88+
/// * Zvbc: `"zvbc"`
89+
/// * Zvfh: `"zvfh"`
90+
/// * Zvfhmin: `"zvfhmin"`
91+
/// * Zvkb: `"zvkb"`
92+
/// * Zvkg: `"zvkg"`
93+
/// * Zvkn: `"zvkn"`
94+
/// * Zvkned: `"zvkned"`
95+
/// * Zvknha: `"zvknha"`
96+
/// * Zvknhb: `"zvknhb"`
97+
/// * Zvknc: `"zvknc"`
98+
/// * Zvkng: `"zvkng"`
99+
/// * Zvks: `"zvks"`
100+
/// * Zvksed: `"zvksed"`
101+
/// * Zvksh: `"zvksh"`
102+
/// * Zvksc: `"zvksc"`
103+
/// * Zvksg: `"zvksg"`
104+
/// * Zvkt: `"zvkt"`
70105
/// * Ztso: `"ztso"`
71106
///
72107
/// There's also bases and extensions marked as standard instruction set,
@@ -87,6 +122,15 @@ features! {
87122
/// * Svnapot: `"svnapot"`
88123
/// * Svpbmt: `"svpbmt"`
89124
/// * Svinval: `"svinval"`
125+
///
126+
/// # Performance Hints
127+
///
128+
/// The two features below define performance hints for unaligned
129+
/// scalar/vector memory accesses, respectively. If enabled, it denotes that
130+
/// corresponding unaligned memory access is reasonably fast.
131+
///
132+
/// * `"unaligned-scalar-mem"`
133+
/// * `"unaligned-vector-mem"`
90134
#[stable(feature = "riscv_ratified", since = "1.78.0")]
91135

92136
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] rv32i: "rv32i";
@@ -102,6 +146,11 @@ features! {
102146
without cfg check: true;
103147
/// RV128I Base Integer Instruction Set
104148
149+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] unaligned_scalar_mem: "unaligned-scalar-mem";
150+
/// Has reasonably performant unaligned scalar
151+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] unaligned_vector_mem: "unaligned-vector-mem";
152+
/// Has reasonably performant unaligned vector
153+
105154
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zicsr: "zicsr";
106155
without cfg check: true;
107156
/// "Zicsr" Extension for Control and Status Register (CSR) Instructions
@@ -115,9 +164,21 @@ features! {
115164
without cfg check: true;
116165
/// "Zifencei" Extension for Instruction-Fetch Fence
117166
167+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zihintntl: "zihintntl";
168+
without cfg check: true;
169+
/// "Zihintntl" Extension for Non-Temporal Locality Hints
118170
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zihintpause: "zihintpause";
119171
without cfg check: true;
120172
/// "Zihintpause" Extension for Pause Hint
173+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zimop: "zimop";
174+
without cfg check: true;
175+
/// "Zimop" Extension for May-Be-Operations
176+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zicboz: "zicboz";
177+
without cfg check: true;
178+
/// "Zicboz" Extension for Cache-Block Zero Instruction
179+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zicond: "zicond";
180+
without cfg check: true;
181+
/// "Zicond" Extension for Integer Conditional Operations
121182
122183
@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] m: "m";
123184
/// "M" Extension for Integer Multiplication and Division
@@ -128,6 +189,10 @@ features! {
128189
/// "Zalrsc" Extension for Load-Reserved/Store-Conditional Instructions
129190
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zaamo: "zaamo";
130191
/// "Zaamo" Extension for Atomic Memory Operations
192+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zawrs: "zawrs";
193+
/// "Zawrs" Extension for Wait-on-Reservation-Set instructions
194+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zacas: "zacas";
195+
/// "Zacas" Extension for Atomic Compare-and-Swap (CAS) Instructions
131196
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zam: "zam";
132197
without cfg check: true;
133198
/// "Zam" Extension for Misaligned Atomics
@@ -146,6 +211,9 @@ features! {
146211
/// "Zfh" Extension for Half-Precision Floating-Point
147212
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zfhmin: "zfhmin";
148213
/// "Zfhmin" Extension for Minimal Half-Precision Floating-Point
214+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zfa: "zfa";
215+
without cfg check: true;
216+
/// "Zfa" Extension for Additional Floating-Point Instructions
149217
150218
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zfinx: "zfinx";
151219
/// "Zfinx" Extension for Single-Precision Floating-Point in Integer Registers
@@ -158,6 +226,21 @@ features! {
158226
159227
@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] c: "c";
160228
/// "C" Extension for Compressed Instructions
229+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zca: "zca";
230+
without cfg check: true;
231+
/// "Zca" Compressed Instructions excluding Floating-Point Loads/Stores
232+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zcf: "zcf";
233+
without cfg check: true;
234+
/// "Zcf" Compressed Instructions for Single-Precision Floating-Point Loads/Stores on RV32
235+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zcd: "zcd";
236+
without cfg check: true;
237+
/// "Zcd" Compressed Instructions for Double-Precision Floating-Point Loads/Stores
238+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zcb: "zcb";
239+
without cfg check: true;
240+
/// "Zcb" Simple Code-size Saving Compressed Instructions
241+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zcmop: "zcmop";
242+
without cfg check: true;
243+
/// "Zcmop" Extension for Compressed May-Be-Operations
161244
162245
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] b: "b";
163246
without cfg check: true;
@@ -200,6 +283,53 @@ features! {
200283
201284
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] v: "v";
202285
/// "V" Extension for Vector Operations
286+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zve32x: "zve32x";
287+
/// "Zve32x" Vector Extension for Embedded Processors (32-bit+; Integer)
288+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zve32f: "zve32f";
289+
/// "Zve32f" Vector Extension for Embedded Processors (32-bit+; with Single-Precision Floating-Point)
290+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zve64x: "zve64x";
291+
/// "Zve64x" Vector Extension for Embedded Processors (64-bit+; Integer)
292+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zve64f: "zve64f";
293+
/// "Zve64f" Vector Extension for Embedded Processors (64-bit+; with Single-Precision Floating-Point)
294+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zve64d: "zve64d";
295+
/// "Zve64d" Vector Extension for Embedded Processors (64-bit+; with Double-Precision Floating-Point)
296+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvfh: "zvfh";
297+
/// "Zvfh" Vector Extension for Half-Precision Floating-Point
298+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvfhmin: "zvfhmin";
299+
/// "Zvfhmin" Vector Extension for Minimal Half-Precision Floating-Point
300+
301+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvbb: "zvbb";
302+
/// "Zvbb" Extension for Vector Basic Bit-Manipulation
303+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvbc: "zvbc";
304+
/// "Zvbc" Extension for Vector Carryless Multiplication
305+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvkb: "zvkb";
306+
/// "Zvkb" Extension for Vector Cryptography Bit-Manipulation
307+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvkg: "zvkg";
308+
/// "Zvkg" Cryptography Extension for Vector GCM/GMAC
309+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvkned: "zvkned";
310+
/// "Zvkned" Cryptography Extension for NIST Suite: Vector AES Block Cipher
311+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvknha: "zvknha";
312+
/// "Zvknha" Cryptography Extension for Vector SHA-2 Secure Hash (SHA-256)
313+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvknhb: "zvknhb";
314+
/// "Zvknhb" Cryptography Extension for Vector SHA-2 Secure Hash (SHA-256/512)
315+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvksed: "zvksed";
316+
/// "Zvksed" Cryptography Extension for ShangMi Suite: Vector SM4 Block Cipher
317+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvksh: "zvksh";
318+
/// "Zvksh" Cryptography Extension for ShangMi Suite: Vector SM3 Secure Hash
319+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvkn: "zvkn";
320+
/// "Zvkn" Cryptography Extension for NIST Algorithm Suite
321+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvknc: "zvknc";
322+
/// "Zvknc" Cryptography Extension for NIST Algorithm Suite with Carryless Multiply
323+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvkng: "zvkng";
324+
/// "Zvkng" Cryptography Extension for NIST Algorithm Suite with GCM
325+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvks: "zvks";
326+
/// "Zvks" Cryptography Extension for ShangMi Algorithm Suite
327+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvksc: "zvksc";
328+
/// "Zvksc" Cryptography Extension for ShangMi Algorithm Suite with Carryless Multiply
329+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvksg: "zvksg";
330+
/// "Zvksg" Cryptography Extension for ShangMi Algorithm Suite with GCM
331+
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvkt: "zvkt";
332+
/// "Zvkt" Extension for Vector Data-Independent Execution Latency
203333
204334
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] svnapot: "svnapot";
205335
without cfg check: true;

0 commit comments

Comments
 (0)