All RISC-V Features are reordered for better maintainability.
The author has a plan to add many RISC-V ratified extensions (mainly
discoverable from Linux) and this is a part of preparation.
Sections are divided as follows:
* Base ISAs
* "I"-related
* Extensions formerly a part of the base "I" extension
but divided later (now all of them are ratified).
* Other user-mode extensions "Zi*".
* "M"-related (currently "M" only)
* "A"-related
"A", "Za*" and "Ztso" which is named differently but absolutely
related to memory operations.
* Base FP extensions
* Base FP extensions using integer registers
* "C"-related (currently "C" only)
* "B"-related (except cryptography-related "Zbk*")
* Scalar cryptography extensions (including "Zbk*")
* Base Vector extensions (currently "V" only)
* Ratified privileged extensions
* Non-extensions and non-ratified extensions which is *not*
going to be ratified, at least in the draft form
The last section needs some explanation.
"S" is not an extension (although some buggy implementations such as QEMU
up to 7.0 emitted this character as well as "U" as an extension) and the
DeviceTree parser in the Linux kernel explicitly workarounds this issue.
There's no plan for ratification of the single-letter "J" extension
(there's a room for redefinition like the "B" extension but unlikely).
Instead, pointer masking extensions including "Supm" is one of the results
of the task group discussing J extension*s*.
There's also an instruction in the "Zfa" extension which accelerates
FP-to-int conversion matching JavaScript semantics.
"P" is being actively discussed (and will result in a single-letter "P"
extension and various "Zp*" extensions) but it seems there needs some time
until ratification.
And there's one Rust-specific issue: Rust implements Packed-SIMD intrinsics
based on an early draft of the "P" extension and they are *very unlikely*
kept as-is. For instance, `add16` does not follow standard RISC-V
instruction naming (ADD16 is the name from the Andes' proposal) and
going to be renamed.
Before moving "P" to above, we have to clearly understand what the final
"P" extension will be and resolve existing intrinsics.
std::detect - Rust's standard library run-time CPU feature detection
The private std::detect module implements run-time feature detection in Rust's
standard library. This allows detecting whether the CPU the binary runs on
supports certain features, like SIMD instructions.
Usage
std::detect APIs are available as part of libstd. Prefer using it via the
standard library than through this crate. Unstable features of std::detect are
available on nightly Rust behind various feature-gates.
If you need run-time feature detection in #[no_std] environments, Rust core
library cannot help you. By design, Rust core is platform independent, but
performing run-time feature detection requires a certain level of cooperation
from the platform.
You can then manually include std_detect as a dependency to get similar
run-time feature detection support than the one offered by Rust's standard
library. We intend to make std_detect more flexible and configurable in this
regard to better serve the needs of #[no_std] targets.
Features
-
std_detect_dlsym_getauxval(enabled by default, requireslibc): Enable to uselibc::dlsymto query whethergetauxvalis linked into the binary. When this is not the case, this feature allows other fallback methods to perform run-time feature detection. When this feature is disabled,std_detectassumes thatgetauxvalis linked to the binary. If that is not the case the behavior is undefined.Note: This feature is ignored on
*-linux-gnu*and*-android*targets because we can safely assumegetauxvalis linked to the binary.*-linux-gnu*targets (since Rust 1.64) have glibc requirements higher than glibc 2.16 that addedgetauxval.*-android*targets (since Rust 1.68) have the minimum supported API level higher than Android 4.3 (API level 18) that addedgetauxval.
-
std_detect_file_io(enabled by default, requiresstd): Enable to perform run-time feature detection using file APIs (e.g./proc/cpuinfo, etc.) if other more performant methods fail. This feature requireslibstdas a dependency, preventing the crate from working on applications in whichstdis not available.
Platform support
-
All
x86/x86_64targets are supported on all platforms by querying thecpuidinstruction directly for the features supported by the hardware and the operating system.std_detectassumes that the binary is an user-space application. If you need raw support for queryingcpuid, consider using thecupidcrate. -
Linux/Android:
arm{32, 64},mips{32,64}{,el},powerpc{32,64}{,le},riscv{32,64},loongarch64,s390x:std_detectsupports these on Linux by querying ELF auxiliary vectors (usinggetauxvalwhen available), and if that fails, by querying/proc/cpuinfo.arm64: partial support for doing run-time feature detection by directly queryingmrsis implemented for Linux >= 4.11, but not enabled by default.
-
FreeBSD:
arm32,powerpc64:std_detectsupports these on FreeBSD by querying ELF auxiliary vectors usingsysctl.arm64: run-time feature detection is implemented by directly queryingmrs.
-
OpenBSD:
arm64: run-time feature detection is implemented by queryingsysctl.
-
Windows:
arm64: run-time feature detection is implemented by queryingIsProcessorFeaturePresent.
License
This project is licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in std_detect by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.