is_riscv_feature_detected in std::arch - Rust
Description: Check for the presence of a CPU feature at runtime.

## is_riscv_feature_detected

# Macro is_riscv_feature_detected

1.78.0 · Source

    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

Check for the presence of a CPU feature at runtime.

When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`) the macro expands to `true`.

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 | Base | Linux
--- | --- | ---
`"rv32e"` | RV32E | No
`"rv32i"` | RV32I | Yes 1
`"rv64i"` | RV64I | Yes 1

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.

1. 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 9

2. Or 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

3. 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 like `cycle` and `instret` are accessible, their value can be unreliable (e.g. returning the constant value) under certain circumstances. ↩ 1 2

4. Linux 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