From 72b06329401feae8053ee2f711b66d19d555381a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Tue, 29 Jul 2025 18:13:48 +0300 Subject: [PATCH] cpufeatures: use `#![doc = include_str!("../README.md")]` --- cpufeatures/README.md | 69 ++++++++++++++++++----- cpufeatures/src/lib.rs | 123 +---------------------------------------- 2 files changed, 56 insertions(+), 136 deletions(-) diff --git a/cpufeatures/README.md b/cpufeatures/README.md index a59eef5f..7d478fd3 100644 --- a/cpufeatures/README.md +++ b/cpufeatures/README.md @@ -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) @@ -31,7 +71,7 @@ Target features: - `sha2`* - `sha3`* -## `loongarch64` +### `loongarch64` Linux only (LoongArch64 does not support OS-independent feature detection) @@ -51,7 +91,7 @@ Target features: - `lbt.mips`* - `ptw`* -## `x86`/`x86_64` +### `x86`/`x86_64` OS independent and `no_std`-friendly @@ -73,7 +113,7 @@ Target features: - `avx512vbmi2`* - `bmi1` - `bmi2` -- `fma`, +- `fma` - `mmx` - `pclmulqdq` - `popcnt` @@ -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 @@ -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 diff --git a/cpufeatures/src/lib.rs b/cpufeatures/src/lib.rs index bc4afd9a..d8d4322d 100644 --- a/cpufeatures/src/lib.rs +++ b/cpufeatures/src/lib.rs @@ -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"