Skip to content

Commit 5c86678

Browse files
committed
std_detect: RISC-V platform guide documentation
Since there's no architectural feature detection on RISC-V (unlike `CPUID` on x86 architectures and some system registers on Arm/AArch64), runtime feature detection entirely depends on the platform-specific facility. As a result, availability of each feature heavily depends on the platform and its version. To help users make a decision for feature checking on a RISC-V system, this commit adds a platform guide with minimum supported platform versions. Note: It intentionally omits the description of the reverse implication related to *extension groups* (such like implication of `B` *from* its members: `Zba`, `Zbb` and `Zbs` extensions) because it currently does not synchronize well with the `-Ctarget-feature` compiler option (due to missing reverse implication checks using `cfg` and due to constraints of the current Rust's feature handling). Instead, it describes forward implications (like `D` implying `F`) due to the fact that it relatively synchronizes well between Rust and `stdarch` for this kind of feature handling (not fully synchronized though).
1 parent d8785a3 commit 5c86678

File tree

1 file changed

+114
-78
lines changed
  • crates/std_detect/src/detect/arch

1 file changed

+114
-78
lines changed

Diff for: crates/std_detect/src/detect/arch/riscv.rs

+114-78
Original file line numberDiff line numberDiff line change
@@ -22,87 +22,121 @@ features! {
2222
///
2323
/// [ISA manual]: https://riscv.org/specifications/ratified/
2424
///
25+
/// # Platform-specific behavior and Availability
26+
///
27+
/// Runtime detection depends on the platform-specific feature detection
28+
/// facility and its availability per feature is
29+
/// highly platform/version-specific.
30+
///
31+
/// Still, a best-effort attempt is performed to enable subset/dependent
32+
/// features if a superset feature is enabled regardless of the platform.
33+
/// For instance, if the A extension (`"a"`) is enabled, its subsets (the
34+
/// Zalrsc and Zaamo extensions; `"zalrsc"` and `"zaamo"`) are also enabled.
35+
/// Likewise, if the F extension (`"f"`) is enabled, one of its dependencies
36+
/// (the Zicsr extension `"zicsr"`) is also enabled.
37+
///
2538
/// # Unprivileged Specification
2639
///
27-
/// The supported ratified RISC-V instruction sets are as follows:
40+
/// The supported ratified RISC-V instruction sets are as follows (OS
41+
/// columns denote runtime feature detection support with or without minimum
42+
/// kernel version; "No" by default):
43+
///
44+
/// | Literal | Base | Linux |
45+
/// |:---------- |:------- |:---------- |
46+
/// | `"rv32e"` | RV32E | |
47+
/// | `"rv32i"` | RV32I | Yes [^ima] |
48+
/// | `"rv64i"` | RV64I | Yes [^ima] |
49+
///
50+
/// | Literal | Extension | Linux |
51+
/// |:--------------- |:----------- |:------------------ |
52+
/// | `"a"` | A | Yes [^ima] |
53+
/// | `"b"` | B | 6.5 |
54+
/// | `"c"` | C | Yes |
55+
/// | `"d"` | D | Yes |
56+
/// | `"f"` | F | Yes |
57+
/// | `"m"` | M | Yes [^ima] |
58+
/// | `"q"` | Q | |
59+
/// | `"v"` | V | 6.5 |
60+
/// | `"zaamo"` | Zaamo | No [^ima] [^dep] |
61+
/// | `"zacas"` | Zacas | 6.8 |
62+
/// | `"zalrsc"` | Zalrsc | No [^ima] [^dep] |
63+
/// | `"zawrs"` | Zawrs | 6.11 |
64+
/// | `"zba"` | Zba | 6.5 |
65+
/// | `"zbb"` | Zbb | 6.5 |
66+
/// | `"zbc"` | Zbc | 6.8 |
67+
/// | `"zbkb"` | Zbkb | 6.8 |
68+
/// | `"zbkc"` | Zbkc | 6.8 |
69+
/// | `"zbkx"` | Zbkx | 6.8 |
70+
/// | `"zbs"` | Zbs | 6.5 |
71+
/// | `"zca"` | Zca | 6.11 [^dep] |
72+
/// | `"zcb"` | Zcb | 6.11 [^dep] |
73+
/// | `"zcd"` | Zcd | 6.11 [^dep] |
74+
/// | `"zcf"` | Zcf | 6.11 [^dep] |
75+
/// | `"zcmop"` | Zcmop | 6.11 |
76+
/// | `"zdinx"` | Zdinx | |
77+
/// | `"zfa"` | Zfa | 6.8 |
78+
/// | `"zfh"` | Zfh | 6.8 |
79+
/// | `"zfhmin"` | Zfhmin | 6.8 |
80+
/// | `"zfinx"` | Zfinx | |
81+
/// | `"zhinx"` | Zhinx | |
82+
/// | `"zhinxmin"` | Zhinxmin | |
83+
/// | `"zicboz"` | Zicboz | 6.7 |
84+
/// | `"zicond"` | Zicond | 6.8 |
85+
/// | `"zicntr"` | Zicntr | |
86+
/// | `"zicsr"` | Zicsr | No [^ima] [^dep] |
87+
/// | `"zifencei"` | Zifencei | No [^ima] |
88+
/// | `"zihintntl"` | Zihintntl | 6.8 |
89+
/// | `"zihintpause"` | Zihintpause | 6.10 |
90+
/// | `"zihpm"` | Zihpm | |
91+
/// | `"zimop"` | Zimop | 6.11 |
92+
/// | `"zk"` | Zk | No [^zkr] |
93+
/// | `"zkn"` | Zkn | 6.8 |
94+
/// | `"zknd"` | Zknd | 6.8 |
95+
/// | `"zkne"` | Zkne | 6.8 |
96+
/// | `"zknh"` | Zknh | 6.8 |
97+
/// | `"zkr"` | Zkr | No [^zkr] |
98+
/// | `"zks"` | Zks | 6.8 |
99+
/// | `"zksed"` | Zksed | 6.8 |
100+
/// | `"zksh"` | Zksh | 6.8 |
101+
/// | `"zkt"` | Zkt | 6.8 |
102+
/// | `"ztso"` | Ztso | 6.8 |
103+
/// | `"zvbb"` | Zvbb | 6.8 |
104+
/// | `"zvbc"` | Zvbc | 6.8 |
105+
/// | `"zve32f"` | Zve32f | 6.11 [^dep] |
106+
/// | `"zve32x"` | Zve32x | 6.11 [^dep] |
107+
/// | `"zve64d"` | Zve64d | 6.11 [^dep] |
108+
/// | `"zve64f"` | Zve64f | 6.11 [^dep] |
109+
/// | `"zve64x"` | Zve64x | 6.11 [^dep] |
110+
/// | `"zvfh"` | Zvfh | 6.8 |
111+
/// | `"zvfhmin"` | Zvfhmin | 6.8 |
112+
/// | `"zvkb"` | Zvkb | 6.8 |
113+
/// | `"zvkg"` | Zvkg | 6.8 |
114+
/// | `"zvkn"` | Zvkn | 6.8 |
115+
/// | `"zvknc"` | Zvknc | 6.8 |
116+
/// | `"zvkned"` | Zvkned | 6.8 |
117+
/// | `"zvkng"` | Zvkng | 6.8 |
118+
/// | `"zvknha"` | Zvknha | 6.8 |
119+
/// | `"zvknhb"` | Zvknhb | 6.8 |
120+
/// | `"zvks"` | Zvks | 6.8 |
121+
/// | `"zvksc"` | Zvksc | 6.8 |
122+
/// | `"zvksed"` | Zvksed | 6.8 |
123+
/// | `"zvksg"` | Zvksg | 6.8 |
124+
/// | `"zvksh"` | Zvksh | 6.8 |
125+
/// | `"zvkt"` | Zvkt | 6.8 |
126+
///
127+
/// [^ima]: Or enabled when the IMA base behavior is enabled on the Linux
128+
/// kernel version 6.4 or later (for bases, the only matching one -- either
129+
/// `"rv32i"` or `"rv64i"` -- is enabled).
130+
///
131+
/// [^dep]: Or enabled as a dependency of another extension (a superset)
132+
/// even if runtime detection of this feature itself is not supported (as
133+
/// long as the runtime detection of the superset is supported).
28134
///
29-
/// * RV32E: `"rv32e"`
30-
/// * RV32I: `"rv32i"`
31-
/// * RV64I: `"rv64i"`
32-
/// * A: `"a"`
33-
/// * Zaamo: `"zaamo"`
34-
/// * Zalrsc: `"zalrsc"`
35-
/// * B: `"b"`
36-
/// * Zba: `"zba"`
37-
/// * Zbb: `"zbb"`
38-
/// * Zbs: `"zbs"`
39-
/// * C: `"c"`
40-
/// * Zca: `"zca"`
41-
/// * Zcd: `"zcd"` (if D is enabled)
42-
/// * Zcf: `"zcf"` (if F is enabled on RV32)
43-
/// * D: `"d"`
44-
/// * F: `"f"`
45-
/// * M: `"m"`
46-
/// * Q: `"q"`
47-
/// * V: `"v"`
48-
/// * Zve32x: `"zve32x"`
49-
/// * Zve32f: `"zve32f"`
50-
/// * Zve64x: `"zve64x"`
51-
/// * Zve64f: `"zve64f"`
52-
/// * Zve64d: `"zve64d"`
53-
/// * Zicboz: `"zicboz"`
54-
/// * Zicntr: `"zicntr"`
55-
/// * Zicond: `"zicond"`
56-
/// * Zicsr: `"zicsr"`
57-
/// * Zifencei: `"zifencei"`
58-
/// * Zihintntl: `"zihintntl"`
59-
/// * Zihintpause: `"zihintpause"`
60-
/// * Zihpm: `"zihpm"`
61-
/// * Zimop: `"zimop"`
62-
/// * Zacas: `"zacas"`
63-
/// * Zawrs: `"zawrs"`
64-
/// * Zfa: `"zfa"`
65-
/// * Zfh: `"zfh"`
66-
/// * Zfhmin: `"zfhmin"`
67-
/// * Zfinx: `"zfinx"`
68-
/// * Zdinx: `"zdinx"`
69-
/// * Zhinx: `"zhinx"`
70-
/// * Zhinxmin: `"zhinxmin"`
71-
/// * Zcb: `"zcb"`
72-
/// * Zcmop: `"zcmop"`
73-
/// * Zbc: `"zbc"`
74-
/// * Zbkb: `"zbkb"`
75-
/// * Zbkc: `"zbkc"`
76-
/// * Zbkx: `"zbkx"`
77-
/// * Zk: `"zk"`
78-
/// * Zkn: `"zkn"`
79-
/// * Zknd: `"zknd"`
80-
/// * Zkne: `"zkne"`
81-
/// * Zknh: `"zknh"`
82-
/// * Zkr: `"zkr"`
83-
/// * Zks: `"zks"`
84-
/// * Zksed: `"zksed"`
85-
/// * Zksh: `"zksh"`
86-
/// * 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"`
105-
/// * Ztso: `"ztso"`
135+
/// [^zkr]: Linux does not report existence of this extension even if
136+
/// supported by the hardware mainly because the `seed` CSR is normally not
137+
/// exposed to the user mode.
138+
/// For the Zk extension features except this CSR, check existence of both
139+
/// `"zkn"` and `"zkt"` features instead.
106140
///
107141
/// There's also bases and extensions marked as standard instruction set,
108142
/// but they are in frozen or draft state. These instruction sets are also
@@ -122,7 +156,9 @@ features! {
122156
/// corresponding unaligned memory access is reasonably fast.
123157
///
124158
/// * `"unaligned-scalar-mem"`
159+
/// * Runtime detection requires Linux version 6.4 or later.
125160
/// * `"unaligned-vector-mem"`
161+
/// * Runtime detection requires Linux version 6.13 or later.
126162
#[stable(feature = "riscv_ratified", since = "1.78.0")]
127163

128164
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] rv32i: "rv32i";

0 commit comments

Comments
 (0)