macro_rules! is_riscv_feature_detected {
("rv32i") => { ... };
("rv32e") => { ... };
("rv64i") => { ... };
("rv128i") => { ... };
("unaligned-scalar-mem") => { ... };
("unaligned-vector-mem") => { ... };
("zicsr") => { ... };
("zicntr") => { ... };
("zihpm") => { ... };
("zifencei") => { ... };
("zihintntl") => { ... };
("zihintpause") => { ... };
("zimop") => { ... };
("zicbom") => { ... };
("zicboz") => { ... };
("zicond") => { ... };
("m") => { ... };
("a") => { ... };
("zalrsc") => { ... };
("zaamo") => { ... };
("zawrs") => { ... };
("zabha") => { ... };
("zacas") => { ... };
("zam") => { ... };
("ztso") => { ... };
("f") => { ... };
("d") => { ... };
("q") => { ... };
("zfh") => { ... };
("zfhmin") => { ... };
("zfa") => { ... };
("zfbfmin") => { ... };
("zfinx") => { ... };
("zdinx") => { ... };
("zhinx") => { ... };
("zhinxmin") => { ... };
("c") => { ... };
("zca") => { ... };
("zcf") => { ... };
("zcd") => { ... };
("zcb") => { ... };
("zcmop") => { ... };
("b") => { ... };
("zba") => { ... };
("zbb") => { ... };
("zbc") => { ... };
("zbs") => { ... };
("zbkb") => { ... };
("zbkc") => { ... };
("zbkx") => { ... };
("zknd") => { ... };
("zkne") => { ... };
("zknh") => { ... };
("zksed") => { ... };
("zksh") => { ... };
("zkr") => { ... };
("zkn") => { ... };
("zks") => { ... };
("zk") => { ... };
("zkt") => { ... };
("v") => { ... };
("zve32x") => { ... };
("zve32f") => { ... };
("zve64x") => { ... };
("zve64f") => { ... };
("zve64d") => { ... };
("zvfh") => { ... };
("zvfhmin") => { ... };
("zvfbfmin") => { ... };
("zvfbfwma") => { ... };
("zvbb") => { ... };
("zvbc") => { ... };
("zvkb") => { ... };
("zvkg") => { ... };
("zvkned") => { ... };
("zvknha") => { ... };
("zvknhb") => { ... };
("zvksed") => { ... };
("zvksh") => { ... };
("zvkn") => { ... };
("zvknc") => { ... };
("zvkng") => { ... };
("zvks") => { ... };
("zvksc") => { ... };
("zvksg") => { ... };
("zvkt") => { ... };
("j") => { ... };
("p") => { ... };
($t:tt,) => { ... };
($t:tt) => { ... };
}
Expand description
A macro to test at runtime whether instruction sets are available on RISC-V platforms.
RISC-V standard defined the base sets and the extension sets. The base sets are RV32I, RV64I, RV32E or RV128I. Any RISC-V platform must support one base set and/or multiple extension sets.
Any RISC-V standard instruction sets can be in state of either ratified, frozen or draft. The version and status of current standard instruction sets can be checked out from preface section of the ISA manual.
Platform may define and support their own custom instruction sets with ISA prefix X. These sets are highly platform specific and should be detected with their own platform support crates.
§Platform-specific/agnostic Behavior and Availability
Runtime detection depends on the platform-specific feature detection facility and its availability per feature is highly platform/version-specific.
Still, a best-effort attempt is performed to enable subset/dependent
features if a superset feature is enabled regardless of the platform.
For instance, if the A extension ("a"
) is enabled, its subsets (the
Zalrsc and Zaamo extensions; "zalrsc"
and "zaamo"
) are also enabled.
Likewise, if the F extension ("f"
) is enabled, one of its dependencies
(the Zicsr extension "zicsr"
) is also enabled.
§Unprivileged Specification
The supported ratified RISC-V instruction sets are as follows (OS columns denote runtime feature detection support with or without the minimum supported version):
Literal | Extension | Linux |
---|---|---|
"a" | A | Yes 1 |
"b" | B | 6.5 |
"c" | C | Yes |
"d" | D | Yes |
"f" | F | Yes |
"m" | M | Yes 1 |
"q" | Q | No |
"v" | V | 6.5 |
"zaamo" | Zaamo | 6.15 1 2 |
"zabha" | Zabha | 6.16 |
"zacas" | Zacas | 6.8 |
"zalrsc" | Zalrsc | 6.15 1 2 |
"zawrs" | Zawrs | 6.11 |
"zba" | Zba | 6.5 |
"zbb" | Zbb | 6.5 |
"zbc" | Zbc | 6.8 |
"zbkb" | Zbkb | 6.8 |
"zbkc" | Zbkc | 6.8 |
"zbkx" | Zbkx | 6.8 |
"zbs" | Zbs | 6.5 |
"zca" | Zca | 6.11 2 |
"zcb" | Zcb | 6.11 |
"zcd" | Zcd | 6.11 2 |
"zcf" | Zcf | 6.11 2 |
"zcmop" | Zcmop | 6.11 |
"zdinx" | Zdinx | No |
"zfa" | Zfa | 6.8 |
"zfbfmin" | Zfbfmin | 6.15 |
"zfh" | Zfh | 6.8 |
"zfhmin" | Zfhmin | 6.8 |
"zfinx" | Zfinx | No |
"zhinx" | Zhinx | No |
"zhinxmin" | Zhinxmin | No |
"zicbom" | Zicbom | 6.15 |
"zicboz" | Zicboz | 6.7 |
"zicntr" | Zicntr | 6.15 1 3 |
"zicond" | Zicond | 6.8 |
"zicsr" | Zicsr | No 1 2 |
"zifencei" | Zifencei | No 1 |
"zihintntl" | Zihintntl | 6.8 |
"zihintpause" | Zihintpause | 6.10 |
"zihpm" | Zihpm | 6.15 3 |
"zimop" | Zimop | 6.11 |
"zk" | Zk | No 4 |
"zkn" | Zkn | 6.8 |
"zknd" | Zknd | 6.8 |
"zkne" | Zkne | 6.8 |
"zknh" | Zknh | 6.8 |
"zkr" | Zkr | No 4 |
"zks" | Zks | 6.8 |
"zksed" | Zksed | 6.8 |
"zksh" | Zksh | 6.8 |
"zkt" | Zkt | 6.8 |
"ztso" | Ztso | 6.8 |
"zvbb" | Zvbb | 6.8 |
"zvbc" | Zvbc | 6.8 |
"zve32f" | Zve32f | 6.11 2 |
"zve32x" | Zve32x | 6.11 2 |
"zve64d" | Zve64d | 6.11 2 |
"zve64f" | Zve64f | 6.11 2 |
"zve64x" | Zve64x | 6.11 2 |
"zvfbfmin" | Zvfbfmin | 6.15 |
"zvfbfwma" | Zvfbfwma | 6.15 |
"zvfh" | Zvfh | 6.8 |
"zvfhmin" | Zvfhmin | 6.8 |
"zvkb" | Zvkb | 6.8 |
"zvkg" | Zvkg | 6.8 |
"zvkn" | Zvkn | 6.8 |
"zvknc" | Zvknc | 6.8 |
"zvkned" | Zvkned | 6.8 |
"zvkng" | Zvkng | 6.8 |
"zvknha" | Zvknha | 6.8 |
"zvknhb" | Zvknhb | 6.8 |
"zvks" | Zvks | 6.8 |
"zvksc" | Zvksc | 6.8 |
"zvksed" | Zvksed | 6.8 |
"zvksg" | Zvksg | 6.8 |
"zvksh" | Zvksh | 6.8 |
"zvkt" | Zvkt | 6.8 |
There’s also bases and extensions marked as standard instruction set, but they are in frozen or draft state. These instruction sets are also reserved by this macro and can be detected in the future platforms.
Draft RISC-V instruction sets:
- RV128I:
"rv128i"
- J:
"j"
- P:
"p"
- Zam:
"zam"
§Performance Hints
The two features below define performance hints for unaligned scalar/vector memory accesses, respectively. If enabled, it denotes that corresponding unaligned memory access is reasonably fast.
"unaligned-scalar-mem"
- Runtime detection requires Linux kernel version 6.4 or later.
"unaligned-vector-mem"
- Runtime detection requires Linux kernel version 6.13 or later.
Or enabled when the IMA base behavior is detected on the Linux kernel version 6.4 or later (for bases, the only matching one – either
"rv32i"
or"rv64i"
– is enabled). ↩ 1 2 3 4 5 6 7 8 9Or enabled as a dependency of another extension (a superset) even if runtime detection of this feature itself is not supported (as long as the runtime detection of the superset is supported). ↩ 1 2 3 4 5 6 7 8 9 10 11
Even if this extension is available, it does not necessarily mean all performance counters are accessible. For example, accesses to all performance counters except
time
(wall-clock) are blocked by default on the Linux kernel version 6.6 or later. Also beware that, even if performance counters likecycle
andinstret
are accessible, their value can be unreliable (e.g. returning the constant value) under certain circumstances. ↩ 1 2Linux does not report existence of this extension even if supported by the hardware mainly because the
seed
CSR on the Zkr extension (which provides hardware-based randomness) is normally inaccessible from the user mode. For the Zk extension features except this CSR, check existence of both"zkn"
and"zkt"
features instead. ↩ 1 2