Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 55 additions & 14 deletions cpufeatures/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,54 @@ Supports `no_std` as well as mobile targets including iOS and Android,
providing an alternative to the `std`-dependent `is_x86_feature_detected!`
macro.

[Documentation][docs-link]

# Supported target architectures
This crate is intended as a stopgap until Rust [RFC 2725] adding first-class
target feature detection macros to `libcore` is implemented.

## Example
```
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub mod x86_backend {
// This macro creates `cpuid_aes_sha` module
cpufeatures::new!(cpuid_aes_sha, "aes", "sha");

pub fn run() {
// `token` is a Zero Sized Type (ZST) value, which guarantees
// that underlying static storage got properly initialized,
// which allows to omit initialization branch
let token: cpuid_aes_sha::InitToken = cpuid_aes_sha::init();

if token.get() {
println!("CPU supports both SHA and AES extensions");
} else {
println!("SHA and AES extensions are not supported");
}

// If stored value needed only once you can get stored value
// omitting the token
let val = cpuid_aes_sha::get();
assert_eq!(val, token.get());

// Additionally you can get both token and value
let (token, val) = cpuid_aes_sha::init_get();
assert_eq!(val, token.get());
}
}
```

Note that if all tested target features are enabled via compiler options
(e.g. by using `RUSTFLAGS`), the `get` method will always return `true`
and `init` will not use CPUID instruction. Such behavior allows
compiler to completely eliminate fallback code.

After first call macro caches result and returns it in subsequent
calls, thus runtime overhead for them is minimal.

## Supported target architectures

*NOTE: target features with an asterisk are unstable (nightly-only) and subject
to change to match upstream name changes in the Rust standard library.
to change to match upstream name changes in the Rust standard library.*

## `aarch64`
### `aarch64`

Linux, iOS, and macOS/ARM only (ARM64 does not support OS-independent feature detection)

Expand All @@ -31,7 +71,7 @@ Target features:
- `sha2`*
- `sha3`*

## `loongarch64`
### `loongarch64`

Linux only (LoongArch64 does not support OS-independent feature detection)

Expand All @@ -51,7 +91,7 @@ Target features:
- `lbt.mips`*
- `ptw`*

## `x86`/`x86_64`
### `x86`/`x86_64`

OS independent and `no_std`-friendly

Expand All @@ -73,7 +113,7 @@ Target features:
- `avx512vbmi2`*
- `bmi1`
- `bmi2`
- `fma`,
- `fma`
- `mmx`
- `pclmulqdq`
- `popcnt`
Expand All @@ -87,12 +127,12 @@ Target features:
- `sse4.1`
- `sse4.2`
- `ssse3`
- `sha512`*
- `sm3`*
- `sm4`*
- `sha512`
- `sm3`
- `sm4`

If you would like detection support for a target feature which is not on
this list, please [open a GitHub issue].
this list, please [open a GitHub issue][github-issue].

## License

Expand Down Expand Up @@ -124,6 +164,7 @@ dual licensed as above, without any additional terms or conditions.

[//]: # (general links)

[RustCrypto]: https://github.com/rustcrypto
[RustCrypto]: https://github.com/RustCrypto
[RustCrypto/utils#378]: https://github.com/RustCrypto/utils/issues/378
[open a GitHub issue]: https://github.com/RustCrypto/utils/issues/new?title=cpufeatures:%20requesting%20support%20for%20CHANGEME%20target%20feature
[RFC 2725]: https://github.com/rust-lang/rfcs/pull/2725
[github-issue]: https://github.com/RustCrypto/utils/issues/new?title=cpufeatures:%20requesting%20support%20for%20CHANGEME%20target%20feature
123 changes: 1 addition & 122 deletions cpufeatures/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,126 +1,5 @@
//! This crate provides macros for runtime CPU feature detection. It's intended
//! as a stopgap until Rust [RFC 2725] adding first-class target feature detection
//! macros to `libcore` is implemented.
//!
//! # Supported target architectures
//!
//! *NOTE: target features with an asterisk are unstable (nightly-only) and
//! subject to change to match upstream name changes in the Rust standard
//! library.
//!
//! ## `aarch64`
//!
//! Linux, iOS, and macOS/ARM only (ARM64 does not support OS-independent feature detection)
//!
//! Target features:
//!
//! - `aes`*
//! - `sha2`*
//! - `sha3`*
//!
//! Linux only
//!
//! - `sm4`*
//!
//! ## `loongarch64`
//!
//! Linux only (LoongArch64 does not support OS-independent feature detection)
//!
//! Target features:
//!
//! - `lam`*
//! - `ual`*
//! - `fpu`*
//! - `lsx`*
//! - `lasx`*
//! - `crc32`*
//! - `complex`*
//! - `crypto`*
//! - `lvz`*
//! - `lbt.x86`*
//! - `lbt.arm`*
//! - `lbt.mips`*
//! - `ptw`*
//!
//! ## `x86`/`x86_64`
//!
//! OS independent and `no_std`-friendly
//!
//! Target features:
//!
//! - `adx`
//! - `aes`
//! - `avx`
//! - `avx2`
//! - `avx512bw`*
//! - `avx512cd`*
//! - `avx512dq`*
//! - `avx512er`*
//! - `avx512f`*
//! - `avx512ifma`*
//! - `avx512pf`*
//! - `avx512vl`*
//! - `bmi1`
//! - `bmi2`
//! - `fma`,
//! - `mmx`
//! - `pclmulqdq`
//! - `popcnt`
//! - `rdrand`
//! - `rdseed`
//! - `sgx`
//! - `sha`
//! - `sse`
//! - `sse2`
//! - `sse3`
//! - `sse4.1`
//! - `sse4.2`
//! - `ssse3`
//!
//! If you would like detection support for a target feature which is not on
//! this list, please [open a GitHub issue][gh].
//!
//! # Example
//! ```
//! # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
//! # {
//! // This macro creates `cpuid_aes_sha` module
//! cpufeatures::new!(cpuid_aes_sha, "aes", "sha");
//!
//! // `token` is a Zero Sized Type (ZST) value, which guarantees
//! // that underlying static storage got properly initialized,
//! // which allows to omit initialization branch
//! let token: cpuid_aes_sha::InitToken = cpuid_aes_sha::init();
//!
//! if token.get() {
//! println!("CPU supports both SHA and AES extensions");
//! } else {
//! println!("SHA and AES extensions are not supported");
//! }
//!
//! // If stored value needed only once you can get stored value
//! // omitting the token
//! let val = cpuid_aes_sha::get();
//! assert_eq!(val, token.get());
//!
//! // Additionally you can get both token and value
//! let (token, val) = cpuid_aes_sha::init_get();
//! assert_eq!(val, token.get());
//! # }
//! ```
//!
//! Note that if all tested target features are enabled via compiler options
//! (e.g. by using `RUSTFLAGS`), the `get` method will always return `true`
//! and `init` will not use CPUID instruction. Such behavior allows
//! compiler to completely eliminate fallback code.
//!
//! After first call macro caches result and returns it in subsequent
//! calls, thus runtime overhead for them is minimal.
//!
//! [RFC 2725]: https://github.com/rust-lang/rfcs/pull/2725
//! [gh]: https://github.com/RustCrypto/utils/issues/new?title=cpufeatures:%20requesting%20support%20for%20CHANGEME%20target%20feature

#![no_std]
#![doc = include_str!("../README.md")]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
Expand Down
Loading