1//! Run-time feature detection on RISC-V.
23#[doc = r" Check for the presence of a CPU feature at runtime."]
#[doc = r""]
#[doc =
r" When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`)"]
#[doc = r" the macro expands to `true`."]
#[doc = r""]
#[doc = r" RISC-V standard defined the base sets and the extension sets."]
#[doc =
r" The base sets are RV32I, RV64I, RV32E or RV128I. Any RISC-V platform"]
#[doc = r" must support one base set and/or multiple extension sets."]
#[doc = r""]
#[doc =
r" Any RISC-V standard instruction sets can be in state of either ratified,"]
#[doc =
r" frozen or draft. The version and status of current standard instruction"]
#[doc = r" sets can be checked out from preface section of the [ISA manual]."]
#[doc = r""]
#[doc =
r" Platform may define and support their own custom instruction sets with"]
#[doc =
r" ISA prefix X. These sets are highly platform specific and should be"]
#[doc = r" detected with their own platform support crates."]
#[doc = r""]
#[doc = r" [ISA manual]: https://riscv.org/specifications/ratified/"]
#[doc = r""]
#[doc = r" # Platform-specific/agnostic Behavior and Availability"]
#[doc = r""]
#[doc =
r" Runtime detection depends on the platform-specific feature detection"]
#[doc = r" facility and its availability per feature is"]
#[doc = r" highly platform/version-specific."]
#[doc = r""]
#[doc =
r" Still, a best-effort attempt is performed to enable subset/dependent"]
#[doc =
r" features if a superset feature is enabled regardless of the platform."]
#[doc =
r#" For instance, if the A extension (`"a"`) is enabled, its subsets (the"#]
#[doc =
r#" Zalrsc and Zaamo extensions; `"zalrsc"` and `"zaamo"`) are also enabled."#]
#[doc =
r#" Likewise, if the F extension (`"f"`) is enabled, one of its dependencies"#]
#[doc = r#" (the Zicsr extension `"zicsr"`) is also enabled."#]
#[doc = r""]
#[doc = r" # Unprivileged Specification"]
#[doc = r""]
#[doc = r" The supported ratified RISC-V instruction sets are as follows (OS"]
#[doc =
r" columns denote runtime feature detection support with or without the"]
#[doc = r" minimum supported version):"]
#[doc = r""]
#[doc = r" | Literal | Base | Linux |"]
#[doc = r" |:---------- |:------- |:---------- |"]
#[doc = r#" | `"rv32e"` | RV32E | No |"#]
#[doc = r#" | `"rv32i"` | RV32I | Yes [^ima] |"#]
#[doc = r#" | `"rv64i"` | RV64I | Yes [^ima] |"#]
#[doc = r""]
#[doc = r" | Literal | Extension | Linux |"]
#[doc = r" |:--------------- |:----------- |:------------------- |"]
#[doc = r#" | `"a"` | A | Yes [^ima] |"#]
#[doc = r#" | `"b"` | B | 6.5 |"#]
#[doc = r#" | `"c"` | C | Yes |"#]
#[doc = r#" | `"d"` | D | Yes |"#]
#[doc = r#" | `"f"` | F | Yes |"#]
#[doc = r#" | `"m"` | M | Yes [^ima] |"#]
#[doc = r#" | `"q"` | Q | No |"#]
#[doc = r#" | `"v"` | V | 6.5 |"#]
#[doc = r#" | `"zaamo"` | Zaamo | 6.15 [^ima] [^dep] |"#]
#[doc = r#" | `"zabha"` | Zabha | 6.16 |"#]
#[doc = r#" | `"zacas"` | Zacas | 6.8 |"#]
#[doc = r#" | `"zalrsc"` | Zalrsc | 6.15 [^ima] [^dep] |"#]
#[doc = r#" | `"zawrs"` | Zawrs | 6.11 |"#]
#[doc = r#" | `"zba"` | Zba | 6.5 |"#]
#[doc = r#" | `"zbb"` | Zbb | 6.5 |"#]
#[doc = r#" | `"zbc"` | Zbc | 6.8 |"#]
#[doc = r#" | `"zbkb"` | Zbkb | 6.8 |"#]
#[doc = r#" | `"zbkc"` | Zbkc | 6.8 |"#]
#[doc = r#" | `"zbkx"` | Zbkx | 6.8 |"#]
#[doc = r#" | `"zbs"` | Zbs | 6.5 |"#]
#[doc = r#" | `"zca"` | Zca | 6.11 [^dep] |"#]
#[doc = r#" | `"zcb"` | Zcb | 6.11 |"#]
#[doc = r#" | `"zcd"` | Zcd | 6.11 [^dep] |"#]
#[doc = r#" | `"zcf"` | Zcf | 6.11 [^dep] |"#]
#[doc = r#" | `"zcmop"` | Zcmop | 6.11 |"#]
#[doc = r#" | `"zdinx"` | Zdinx | No |"#]
#[doc = r#" | `"zfa"` | Zfa | 6.8 |"#]
#[doc = r#" | `"zfbfmin"` | Zfbfmin | 6.15 |"#]
#[doc = r#" | `"zfh"` | Zfh | 6.8 |"#]
#[doc = r#" | `"zfhmin"` | Zfhmin | 6.8 |"#]
#[doc = r#" | `"zfinx"` | Zfinx | No |"#]
#[doc = r#" | `"zhinx"` | Zhinx | No |"#]
#[doc = r#" | `"zhinxmin"` | Zhinxmin | No |"#]
#[doc = r#" | `"zicbom"` | Zicbom | 6.15 |"#]
#[doc = r#" | `"zicboz"` | Zicboz | 6.7 |"#]
#[doc = r#" | `"zicntr"` | Zicntr | 6.15 [^ima] [^cntr] |"#]
#[doc = r#" | `"zicond"` | Zicond | 6.8 |"#]
#[doc = r#" | `"zicsr"` | Zicsr | No [^ima] [^dep] |"#]
#[doc = r#" | `"zifencei"` | Zifencei | No [^ima] |"#]
#[doc = r#" | `"zihintntl"` | Zihintntl | 6.8 |"#]
#[doc = r#" | `"zihintpause"` | Zihintpause | 6.10 |"#]
#[doc = r#" | `"zihpm"` | Zihpm | 6.15 [^cntr] |"#]
#[doc = r#" | `"zimop"` | Zimop | 6.11 |"#]
#[doc = r#" | `"zk"` | Zk | No [^zkr] |"#]
#[doc = r#" | `"zkn"` | Zkn | 6.8 |"#]
#[doc = r#" | `"zknd"` | Zknd | 6.8 |"#]
#[doc = r#" | `"zkne"` | Zkne | 6.8 |"#]
#[doc = r#" | `"zknh"` | Zknh | 6.8 |"#]
#[doc = r#" | `"zkr"` | Zkr | No [^zkr] |"#]
#[doc = r#" | `"zks"` | Zks | 6.8 |"#]
#[doc = r#" | `"zksed"` | Zksed | 6.8 |"#]
#[doc = r#" | `"zksh"` | Zksh | 6.8 |"#]
#[doc = r#" | `"zkt"` | Zkt | 6.8 |"#]
#[doc = r#" | `"ztso"` | Ztso | 6.8 |"#]
#[doc = r#" | `"zvbb"` | Zvbb | 6.8 |"#]
#[doc = r#" | `"zvbc"` | Zvbc | 6.8 |"#]
#[doc = r#" | `"zve32f"` | Zve32f | 6.11 [^dep] |"#]
#[doc = r#" | `"zve32x"` | Zve32x | 6.11 [^dep] |"#]
#[doc = r#" | `"zve64d"` | Zve64d | 6.11 [^dep] |"#]
#[doc = r#" | `"zve64f"` | Zve64f | 6.11 [^dep] |"#]
#[doc = r#" | `"zve64x"` | Zve64x | 6.11 [^dep] |"#]
#[doc = r#" | `"zvfbfmin"` | Zvfbfmin | 6.15 |"#]
#[doc = r#" | `"zvfbfwma"` | Zvfbfwma | 6.15 |"#]
#[doc = r#" | `"zvfh"` | Zvfh | 6.8 |"#]
#[doc = r#" | `"zvfhmin"` | Zvfhmin | 6.8 |"#]
#[doc = r#" | `"zvkb"` | Zvkb | 6.8 |"#]
#[doc = r#" | `"zvkg"` | Zvkg | 6.8 |"#]
#[doc = r#" | `"zvkn"` | Zvkn | 6.8 |"#]
#[doc = r#" | `"zvknc"` | Zvknc | 6.8 |"#]
#[doc = r#" | `"zvkned"` | Zvkned | 6.8 |"#]
#[doc = r#" | `"zvkng"` | Zvkng | 6.8 |"#]
#[doc = r#" | `"zvknha"` | Zvknha | 6.8 |"#]
#[doc = r#" | `"zvknhb"` | Zvknhb | 6.8 |"#]
#[doc = r#" | `"zvks"` | Zvks | 6.8 |"#]
#[doc = r#" | `"zvksc"` | Zvksc | 6.8 |"#]
#[doc = r#" | `"zvksed"` | Zvksed | 6.8 |"#]
#[doc = r#" | `"zvksg"` | Zvksg | 6.8 |"#]
#[doc = r#" | `"zvksh"` | Zvksh | 6.8 |"#]
#[doc = r#" | `"zvkt"` | Zvkt | 6.8 |"#]
#[doc = r""]
#[doc =
r" [^ima]: Or enabled when the IMA base behavior is detected on the Linux"]
#[doc =
r" kernel version 6.4 or later (for bases, the only matching one -- either"]
#[doc = r#" `"rv32i"` or `"rv64i"` -- is enabled)."#]
#[doc = r""]
#[doc =
r" [^cntr]: Even if this extension is available, it does not necessarily"]
#[doc = r" mean all performance counters are accessible."]
#[doc = r" For example, accesses to all performance counters except `time`"]
#[doc = r" (wall-clock) are blocked by default on the Linux kernel"]
#[doc = r" version 6.6 or later."]
#[doc = r" Also beware that, even if performance counters like `cycle` and"]
#[doc =
r" `instret` are accessible, their value can be unreliable (e.g. returning"]
#[doc = r" the constant value) under certain circumstances."]
#[doc = r""]
#[doc =
r" [^dep]: Or enabled as a dependency of another extension (a superset)"]
#[doc =
r" even if runtime detection of this feature itself is not supported (as"]
#[doc = r" long as the runtime detection of the superset is supported)."]
#[doc = r""]
#[doc = r" [^zkr]: Linux does not report existence of this extension even if"]
#[doc =
r" supported by the hardware mainly because the `seed` CSR on the Zkr"]
#[doc = r" extension (which provides hardware-based randomness) is normally"]
#[doc = r" inaccessible from the user mode."]
#[doc =
r" For the Zk extension features except this CSR, check existence of both"]
#[doc = r#" `"zkn"` and `"zkt"` features instead."#]
#[doc = r""]
#[doc =
r" There's also bases and extensions marked as standard instruction set,"]
#[doc =
r" but they are in frozen or draft state. These instruction sets are also"]
#[doc =
r" reserved by this macro and can be detected in the future platforms."]
#[doc = r""]
#[doc = r" Draft RISC-V instruction sets:"]
#[doc = r""]
#[doc = r#" * RV128I: `"rv128i"`"#]
#[doc = r#" * J: `"j"`"#]
#[doc = r#" * P: `"p"`"#]
#[doc = r#" * Zam: `"zam"`"#]
#[doc = r""]
#[doc = r" # Performance Hints"]
#[doc = r""]
#[doc = r" The two features below define performance hints for unaligned"]
#[doc =
r" scalar/vector memory accesses, respectively. If enabled, it denotes that"]
#[doc = r" corresponding unaligned memory access is reasonably fast."]
#[doc = r""]
#[doc = r#" * `"unaligned-scalar-mem"`"#]
#[doc = r" * Runtime detection requires Linux kernel version 6.4 or later."]
#[doc = r#" * `"unaligned-vector-mem"`"#]
#[doc =
r" * Runtime detection requires Linux kernel version 6.13 or later."]
#[stable(feature = "riscv_ratified", since = "1.78.0")]
#[macro_export]
macro_rules! is_riscv_feature_detected {
("rv32i") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("rv32e") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("rv64i") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("rv128i") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("unaligned-scalar-mem") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("unaligned-vector-mem") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zicsr") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zicntr") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zihpm") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zifencei") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zihintntl") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zihintpause") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zimop") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zicbom") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zicboz") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zicond") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("m") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("a") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zalrsc") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zaamo") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zawrs") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zabha") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zacas") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zam") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("ztso") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("f") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("d") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("q") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zfh") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zfhmin") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zfa") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zfbfmin") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zfinx") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zdinx") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zhinx") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zhinxmin") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("c") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zca") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zcf") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zcd") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zcb") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zcmop") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("b") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zba") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zbb") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zbc") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zbs") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zbkb") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zbkc") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zbkx") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zknd") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zkne") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zknh") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zksed") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zksh") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zkr") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zkn") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zks") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zk") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zkt") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("v") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zve32x") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zve32f") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zve64x") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zve64f") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zve64d") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvfh") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvfhmin") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvfbfmin") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvfbfwma") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvbb") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvbc") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvkb") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvkg") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvkned") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvknha") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvknhb") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvksed") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvksh") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvkn") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvknc") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvkng") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvks") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvksc") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvksg") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("zvkt") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("j") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ("p") =>
{
compile_error!
(concat!
(r#"This macro cannot be used on the current target.
You can prevent it from being used in other architectures by
guarding it behind a cfg("#,
stringify! (any(target_arch = "riscv32", target_arch = "riscv64")),
")."))
}; ($t : tt,) => { crate :: is_riscv_feature_detected ! ($t); }; ($t : tt)
=>
{
compile_error!
(concat!
(concat! ("unknown ", stringify! (riscv)), concat!
(" target feature: ", $t)))
};
}
#[deny(unexpected_cfgs)]
#[deny(unfulfilled_lint_expectations)]
const _: () =
{
#[allow(unexpected_cfgs, reason = "rv32i")]
{ false };
#[allow(unexpected_cfgs, reason = "rv32e")]
{ false };
#[allow(unexpected_cfgs, reason = "rv64i")]
{ false };
#[allow(unexpected_cfgs, reason = "rv128i")]
{ false };
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
#[allow(unexpected_cfgs, reason = "zam")]
{ false };
false;
;
false;
;
false;
;
#[allow(unexpected_cfgs, reason = "q")]
{ false };
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
#[allow(unexpected_cfgs, reason = "zcf")]
{ false };
#[allow(unexpected_cfgs, reason = "zcd")]
{ false };
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
false;
;
#[allow(unexpected_cfgs, reason = "j")]
{ false };
#[allow(unexpected_cfgs, reason = "p")]
{ false };
};features! {
4 @TARGET: riscv;
5 @CFG: any(target_arch = "riscv32", target_arch = "riscv64");
6 @MACRO_NAME: is_riscv_feature_detected;
7 @MACRO_ATTRS:
8/// Check for the presence of a CPU feature at runtime.
9 ///
10 /// When the feature is known to be enabled at compile time (e.g. via `-Ctarget-feature`)
11 /// the macro expands to `true`.
12 ///
13 /// RISC-V standard defined the base sets and the extension sets.
14 /// The base sets are RV32I, RV64I, RV32E or RV128I. Any RISC-V platform
15 /// must support one base set and/or multiple extension sets.
16 ///
17 /// Any RISC-V standard instruction sets can be in state of either ratified,
18 /// frozen or draft. The version and status of current standard instruction
19 /// sets can be checked out from preface section of the [ISA manual].
20 ///
21 /// Platform may define and support their own custom instruction sets with
22 /// ISA prefix X. These sets are highly platform specific and should be
23 /// detected with their own platform support crates.
24 ///
25 /// [ISA manual]: https://riscv.org/specifications/ratified/
26 ///
27 /// # Platform-specific/agnostic Behavior and Availability
28 ///
29 /// Runtime detection depends on the platform-specific feature detection
30 /// facility and its availability per feature is
31 /// highly platform/version-specific.
32 ///
33 /// Still, a best-effort attempt is performed to enable subset/dependent
34 /// features if a superset feature is enabled regardless of the platform.
35 /// For instance, if the A extension (`"a"`) is enabled, its subsets (the
36 /// Zalrsc and Zaamo extensions; `"zalrsc"` and `"zaamo"`) are also enabled.
37 /// Likewise, if the F extension (`"f"`) is enabled, one of its dependencies
38 /// (the Zicsr extension `"zicsr"`) is also enabled.
39 ///
40 /// # Unprivileged Specification
41 ///
42 /// The supported ratified RISC-V instruction sets are as follows (OS
43 /// columns denote runtime feature detection support with or without the
44 /// minimum supported version):
45 ///
46 /// | Literal | Base | Linux |
47 /// |:---------- |:------- |:---------- |
48 /// | `"rv32e"` | RV32E | No |
49 /// | `"rv32i"` | RV32I | Yes [^ima] |
50 /// | `"rv64i"` | RV64I | Yes [^ima] |
51 ///
52 /// | Literal | Extension | Linux |
53 /// |:--------------- |:----------- |:------------------- |
54 /// | `"a"` | A | Yes [^ima] |
55 /// | `"b"` | B | 6.5 |
56 /// | `"c"` | C | Yes |
57 /// | `"d"` | D | Yes |
58 /// | `"f"` | F | Yes |
59 /// | `"m"` | M | Yes [^ima] |
60 /// | `"q"` | Q | No |
61 /// | `"v"` | V | 6.5 |
62 /// | `"zaamo"` | Zaamo | 6.15 [^ima] [^dep] |
63 /// | `"zabha"` | Zabha | 6.16 |
64 /// | `"zacas"` | Zacas | 6.8 |
65 /// | `"zalrsc"` | Zalrsc | 6.15 [^ima] [^dep] |
66 /// | `"zawrs"` | Zawrs | 6.11 |
67 /// | `"zba"` | Zba | 6.5 |
68 /// | `"zbb"` | Zbb | 6.5 |
69 /// | `"zbc"` | Zbc | 6.8 |
70 /// | `"zbkb"` | Zbkb | 6.8 |
71 /// | `"zbkc"` | Zbkc | 6.8 |
72 /// | `"zbkx"` | Zbkx | 6.8 |
73 /// | `"zbs"` | Zbs | 6.5 |
74 /// | `"zca"` | Zca | 6.11 [^dep] |
75 /// | `"zcb"` | Zcb | 6.11 |
76 /// | `"zcd"` | Zcd | 6.11 [^dep] |
77 /// | `"zcf"` | Zcf | 6.11 [^dep] |
78 /// | `"zcmop"` | Zcmop | 6.11 |
79 /// | `"zdinx"` | Zdinx | No |
80 /// | `"zfa"` | Zfa | 6.8 |
81 /// | `"zfbfmin"` | Zfbfmin | 6.15 |
82 /// | `"zfh"` | Zfh | 6.8 |
83 /// | `"zfhmin"` | Zfhmin | 6.8 |
84 /// | `"zfinx"` | Zfinx | No |
85 /// | `"zhinx"` | Zhinx | No |
86 /// | `"zhinxmin"` | Zhinxmin | No |
87 /// | `"zicbom"` | Zicbom | 6.15 |
88 /// | `"zicboz"` | Zicboz | 6.7 |
89 /// | `"zicntr"` | Zicntr | 6.15 [^ima] [^cntr] |
90 /// | `"zicond"` | Zicond | 6.8 |
91 /// | `"zicsr"` | Zicsr | No [^ima] [^dep] |
92 /// | `"zifencei"` | Zifencei | No [^ima] |
93 /// | `"zihintntl"` | Zihintntl | 6.8 |
94 /// | `"zihintpause"` | Zihintpause | 6.10 |
95 /// | `"zihpm"` | Zihpm | 6.15 [^cntr] |
96 /// | `"zimop"` | Zimop | 6.11 |
97 /// | `"zk"` | Zk | No [^zkr] |
98 /// | `"zkn"` | Zkn | 6.8 |
99 /// | `"zknd"` | Zknd | 6.8 |
100 /// | `"zkne"` | Zkne | 6.8 |
101 /// | `"zknh"` | Zknh | 6.8 |
102 /// | `"zkr"` | Zkr | No [^zkr] |
103 /// | `"zks"` | Zks | 6.8 |
104 /// | `"zksed"` | Zksed | 6.8 |
105 /// | `"zksh"` | Zksh | 6.8 |
106 /// | `"zkt"` | Zkt | 6.8 |
107 /// | `"ztso"` | Ztso | 6.8 |
108 /// | `"zvbb"` | Zvbb | 6.8 |
109 /// | `"zvbc"` | Zvbc | 6.8 |
110 /// | `"zve32f"` | Zve32f | 6.11 [^dep] |
111 /// | `"zve32x"` | Zve32x | 6.11 [^dep] |
112 /// | `"zve64d"` | Zve64d | 6.11 [^dep] |
113 /// | `"zve64f"` | Zve64f | 6.11 [^dep] |
114 /// | `"zve64x"` | Zve64x | 6.11 [^dep] |
115 /// | `"zvfbfmin"` | Zvfbfmin | 6.15 |
116 /// | `"zvfbfwma"` | Zvfbfwma | 6.15 |
117 /// | `"zvfh"` | Zvfh | 6.8 |
118 /// | `"zvfhmin"` | Zvfhmin | 6.8 |
119 /// | `"zvkb"` | Zvkb | 6.8 |
120 /// | `"zvkg"` | Zvkg | 6.8 |
121 /// | `"zvkn"` | Zvkn | 6.8 |
122 /// | `"zvknc"` | Zvknc | 6.8 |
123 /// | `"zvkned"` | Zvkned | 6.8 |
124 /// | `"zvkng"` | Zvkng | 6.8 |
125 /// | `"zvknha"` | Zvknha | 6.8 |
126 /// | `"zvknhb"` | Zvknhb | 6.8 |
127 /// | `"zvks"` | Zvks | 6.8 |
128 /// | `"zvksc"` | Zvksc | 6.8 |
129 /// | `"zvksed"` | Zvksed | 6.8 |
130 /// | `"zvksg"` | Zvksg | 6.8 |
131 /// | `"zvksh"` | Zvksh | 6.8 |
132 /// | `"zvkt"` | Zvkt | 6.8 |
133 ///
134 /// [^ima]: Or enabled when the IMA base behavior is detected on the Linux
135 /// kernel version 6.4 or later (for bases, the only matching one -- either
136 /// `"rv32i"` or `"rv64i"` -- is enabled).
137 ///
138 /// [^cntr]: Even if this extension is available, it does not necessarily
139 /// mean all performance counters are accessible.
140 /// For example, accesses to all performance counters except `time`
141 /// (wall-clock) are blocked by default on the Linux kernel
142 /// version 6.6 or later.
143 /// Also beware that, even if performance counters like `cycle` and
144 /// `instret` are accessible, their value can be unreliable (e.g. returning
145 /// the constant value) under certain circumstances.
146 ///
147 /// [^dep]: Or enabled as a dependency of another extension (a superset)
148 /// even if runtime detection of this feature itself is not supported (as
149 /// long as the runtime detection of the superset is supported).
150 ///
151 /// [^zkr]: Linux does not report existence of this extension even if
152 /// supported by the hardware mainly because the `seed` CSR on the Zkr
153 /// extension (which provides hardware-based randomness) is normally
154 /// inaccessible from the user mode.
155 /// For the Zk extension features except this CSR, check existence of both
156 /// `"zkn"` and `"zkt"` features instead.
157 ///
158 /// There's also bases and extensions marked as standard instruction set,
159 /// but they are in frozen or draft state. These instruction sets are also
160 /// reserved by this macro and can be detected in the future platforms.
161 ///
162 /// Draft RISC-V instruction sets:
163 ///
164 /// * RV128I: `"rv128i"`
165 /// * J: `"j"`
166 /// * P: `"p"`
167 /// * Zam: `"zam"`
168 ///
169 /// # Performance Hints
170 ///
171 /// The two features below define performance hints for unaligned
172 /// scalar/vector memory accesses, respectively. If enabled, it denotes that
173 /// corresponding unaligned memory access is reasonably fast.
174 ///
175 /// * `"unaligned-scalar-mem"`
176 /// * Runtime detection requires Linux kernel version 6.4 or later.
177 /// * `"unaligned-vector-mem"`
178 /// * Runtime detection requires Linux kernel version 6.13 or later.
179#[stable(feature = "riscv_ratified", since = "1.78.0")]
180181@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] rv32i: "rv32i";
182 without cfg check: true;
183/// RV32I Base Integer Instruction Set
184@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] rv32e: "rv32e";
185 without cfg check: true;
186/// RV32E Base Integer Instruction Set
187@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] rv64i: "rv64i";
188 without cfg check: true;
189/// RV64I Base Integer Instruction Set
190@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] rv128i: "rv128i";
191 without cfg check: true;
192/// RV128I Base Integer Instruction Set
193194@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] unaligned_scalar_mem: "unaligned-scalar-mem";
195/// Has reasonably performant unaligned scalar
196@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] unaligned_vector_mem: "unaligned-vector-mem";
197/// Has reasonably performant unaligned vector
198199@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zicsr: "zicsr";
200/// "Zicsr" Extension for Control and Status Register (CSR) Instructions
201@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zicntr: "zicntr";
202/// "Zicntr" Extension for Base Counters and Timers
203@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zihpm: "zihpm";
204/// "Zihpm" Extension for Hardware Performance Counters
205@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zifencei: "zifencei";
206/// "Zifencei" Extension for Instruction-Fetch Fence
207208@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zihintntl: "zihintntl";
209/// "Zihintntl" Extension for Non-Temporal Locality Hints
210@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zihintpause: "zihintpause";
211/// "Zihintpause" Extension for Pause Hint
212@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zimop: "zimop";
213/// "Zimop" Extension for May-Be-Operations
214@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zicbom: "zicbom";
215/// "Zicbom" Extension for Cache-Block Management Instructions
216@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zicboz: "zicboz";
217/// "Zicboz" Extension for Cache-Block Zero Instruction
218@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zicond: "zicond";
219/// "Zicond" Extension for Integer Conditional Operations
220221@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] m: "m";
222/// "M" Extension for Integer Multiplication and Division
223224@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] a: "a";
225/// "A" Extension for Atomic Instructions
226@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zalrsc: "zalrsc";
227/// "Zalrsc" Extension for Load-Reserved/Store-Conditional Instructions
228@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zaamo: "zaamo";
229/// "Zaamo" Extension for Atomic Memory Operations
230@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zawrs: "zawrs";
231/// "Zawrs" Extension for Wait-on-Reservation-Set Instructions
232@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zabha: "zabha";
233/// "Zabha" Extension for Byte and Halfword Atomic Memory Operations
234@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zacas: "zacas";
235/// "Zacas" Extension for Atomic Compare-and-Swap (CAS) Instructions
236@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zam: "zam";
237 without cfg check: true;
238/// "Zam" Extension for Misaligned Atomics
239@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] ztso: "ztso";
240/// "Ztso" Extension for Total Store Ordering
241242@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] f: "f";
243/// "F" Extension for Single-Precision Floating-Point
244@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] d: "d";
245/// "D" Extension for Double-Precision Floating-Point
246@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] q: "q";
247 without cfg check: true;
248/// "Q" Extension for Quad-Precision Floating-Point
249@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zfh: "zfh";
250/// "Zfh" Extension for Half-Precision Floating-Point
251@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zfhmin: "zfhmin";
252/// "Zfhmin" Extension for Minimal Half-Precision Floating-Point
253@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zfa: "zfa";
254/// "Zfa" Extension for Additional Floating-Point Instructions
255@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zfbfmin: "zfbfmin";
256/// "Zfbfmin" Extension for Scalar BF16 Converts
257258@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zfinx: "zfinx";
259/// "Zfinx" Extension for Single-Precision Floating-Point in Integer Registers
260@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zdinx: "zdinx";
261/// "Zdinx" Extension for Double-Precision Floating-Point in Integer Registers
262@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zhinx: "zhinx";
263/// "Zhinx" Extension for Half-Precision Floating-Point in Integer Registers
264@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zhinxmin: "zhinxmin";
265/// "Zhinxmin" Extension for Minimal Half-Precision Floating-Point in Integer Registers
266267@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] c: "c";
268/// "C" Extension for Compressed Instructions
269@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zca: "zca";
270/// "Zca" Compressed Instructions excluding Floating-Point Loads/Stores
271@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zcf: "zcf";
272 without cfg check: true;
273/// "Zcf" Compressed Instructions for Single-Precision Floating-Point Loads/Stores on RV32
274@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zcd: "zcd";
275 without cfg check: true;
276/// "Zcd" Compressed Instructions for Double-Precision Floating-Point Loads/Stores
277@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zcb: "zcb";
278/// "Zcb" Simple Code-size Saving Compressed Instructions
279@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] zcmop: "zcmop";
280/// "Zcmop" Extension for Compressed May-Be-Operations
281282@FEATURE: #[stable(feature = "riscv_ratified_v2", since = "1.94.0")] b: "b";
283/// "B" Extension for Bit Manipulation
284@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zba: "zba";
285/// "Zba" Extension for Address Generation
286@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zbb: "zbb";
287/// "Zbb" Extension for Basic Bit-Manipulation
288@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zbc: "zbc";
289/// "Zbc" Extension for Carry-less Multiplication
290@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zbs: "zbs";
291/// "Zbs" Extension for Single-Bit Instructions
292293@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zbkb: "zbkb";
294/// "Zbkb" Extension for Bit-Manipulation for Cryptography
295@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zbkc: "zbkc";
296/// "Zbkc" Extension for Carry-less Multiplication for Cryptography
297@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zbkx: "zbkx";
298/// "Zbkx" Extension for Crossbar Permutations
299@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zknd: "zknd";
300/// "Zknd" Cryptography Extension for NIST Suite: AES Decryption
301@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zkne: "zkne";
302/// "Zkne" Cryptography Extension for NIST Suite: AES Encryption
303@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zknh: "zknh";
304/// "Zknh" Cryptography Extension for NIST Suite: Hash Function Instructions
305@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zksed: "zksed";
306/// "Zksed" Cryptography Extension for ShangMi Suite: SM4 Block Cipher Instructions
307@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zksh: "zksh";
308/// "Zksh" Cryptography Extension for ShangMi Suite: SM3 Hash Function Instructions
309@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zkr: "zkr";
310/// "Zkr" Entropy Source Extension
311@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zkn: "zkn";
312/// "Zkn" Cryptography Extension for NIST Algorithm Suite
313@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zks: "zks";
314/// "Zks" Cryptography Extension for ShangMi Algorithm Suite
315@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zk: "zk";
316/// "Zk" Cryptography Extension for Standard Scalar Cryptography
317@FEATURE: #[stable(feature = "riscv_ratified", since = "1.78.0")] zkt: "zkt";
318/// "Zkt" Cryptography Extension for Data Independent Execution Latency
319320@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] v: "v";
321/// "V" Extension for Vector Operations
322@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zve32x: "zve32x";
323/// "Zve32x" Vector Extension for Embedded Processors (32-bit+; Integer)
324@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zve32f: "zve32f";
325/// "Zve32f" Vector Extension for Embedded Processors (32-bit+; with Single-Precision Floating-Point)
326@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zve64x: "zve64x";
327/// "Zve64x" Vector Extension for Embedded Processors (64-bit+; Integer)
328@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zve64f: "zve64f";
329/// "Zve64f" Vector Extension for Embedded Processors (64-bit+; with Single-Precision Floating-Point)
330@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zve64d: "zve64d";
331/// "Zve64d" Vector Extension for Embedded Processors (64-bit+; with Double-Precision Floating-Point)
332@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvfh: "zvfh";
333/// "Zvfh" Vector Extension for Half-Precision Floating-Point
334@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvfhmin: "zvfhmin";
335/// "Zvfhmin" Vector Extension for Minimal Half-Precision Floating-Point
336@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvfbfmin: "zvfbfmin";
337/// "Zvfbfmin" Vector Extension for BF16 Converts
338@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvfbfwma: "zvfbfwma";
339/// "Zvfbfwma" Vector Extension for BF16 Widening Multiply-Add
340341@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvbb: "zvbb";
342/// "Zvbb" Extension for Vector Basic Bit-Manipulation
343@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvbc: "zvbc";
344/// "Zvbc" Extension for Vector Carryless Multiplication
345@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvkb: "zvkb";
346/// "Zvkb" Extension for Vector Cryptography Bit-Manipulation
347@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvkg: "zvkg";
348/// "Zvkg" Cryptography Extension for Vector GCM/GMAC
349@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvkned: "zvkned";
350/// "Zvkned" Cryptography Extension for NIST Suite: Vector AES Block Cipher
351@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvknha: "zvknha";
352/// "Zvknha" Cryptography Extension for Vector SHA-2 Secure Hash (SHA-256)
353@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvknhb: "zvknhb";
354/// "Zvknhb" Cryptography Extension for Vector SHA-2 Secure Hash (SHA-256/512)
355@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvksed: "zvksed";
356/// "Zvksed" Cryptography Extension for ShangMi Suite: Vector SM4 Block Cipher
357@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvksh: "zvksh";
358/// "Zvksh" Cryptography Extension for ShangMi Suite: Vector SM3 Secure Hash
359@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvkn: "zvkn";
360/// "Zvkn" Cryptography Extension for NIST Algorithm Suite
361@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvknc: "zvknc";
362/// "Zvknc" Cryptography Extension for NIST Algorithm Suite with Carryless Multiply
363@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvkng: "zvkng";
364/// "Zvkng" Cryptography Extension for NIST Algorithm Suite with GCM
365@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvks: "zvks";
366/// "Zvks" Cryptography Extension for ShangMi Algorithm Suite
367@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvksc: "zvksc";
368/// "Zvksc" Cryptography Extension for ShangMi Algorithm Suite with Carryless Multiply
369@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvksg: "zvksg";
370/// "Zvksg" Cryptography Extension for ShangMi Algorithm Suite with GCM
371@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvkt: "zvkt";
372/// "Zvkt" Extension for Vector Data-Independent Execution Latency
373374@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] j: "j";
375 without cfg check: true;
376/// "J" Extension for Dynamically Translated Languages
377@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] p: "p";
378 without cfg check: true;
379/// "P" Extension for Packed-SIMD Instructions
380}