cpufeatures 0.3.0

Lightweight runtime CPU feature detection for aarch64, loongarch64, and x86/x86_64 targets, with no_std support and support for mobile targets including Android and iOS
Documentation
# [RustCrypto]: CPU Feature Detection

[![crate][crate-image]][crate-link]
[![Docs][docs-image]][docs-link]
[![Build Status][build-image]][build-link]
![Apache2/MIT licensed][license-image]
![Rust Version][rustc-image]
[![Project Chat][chat-image]][chat-link]

Lightweight and efficient runtime CPU feature detection for `aarch64`, `loongarch64`, and
`x86`/`x86_64` targets.

Supports `no_std` as well as mobile targets including iOS and Android,
providing an alternative to the `std`-dependent `is_x86_feature_detected!`
macro.

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

## Example
```rust
#[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.*

### `aarch64`

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

Target features:

- `aes`*
- `sha2`*
- `sha3`*

### `loongarch64`

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

Target features:

- `32s`*
- `f`*
- `d`*
- `frecipe`*
- `div32`*
- `lsx`*
- `lasx`*
- `lam-bh`*
- `lamcas`*
- `ld-seq-sa`*
- `scq`*
- `lbt`*
- `lvz`*
- `ual`*

### `x86`/`x86_64`

OS independent and `no_std`-friendly

Target features:

- `adx`
- `aes`
- `avx`
- `avx2`
- `avx512bw`*
- `avx512cd`*
- `avx512dq`*
- `avx512er`*
- `avx512f`*
- `avx512ifma`*
- `avx512pf`*
- `avx512vl`*
- `avx512vbmi`*
- `avx512vbmi2`*
- `bmi1`
- `bmi2`
- `fma`
- `mmx`
- `pclmulqdq`
- `popcnt`
- `rdrand`
- `rdseed`
- `sgx`
- `sha`
- `sse`
- `sse2`
- `sse3`
- `sse4.1`
- `sse4.2`
- `ssse3`
- `sha512`
- `sm3`
- `sm4`

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

## License

Licensed under either of:

 * [Apache License, Version 2.0]http://www.apache.org/licenses/LICENSE-2.0
 * [MIT license]http://opensource.org/licenses/MIT

at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.

[//]: # (badges)

[crate-image]: https://img.shields.io/crates/v/cpufeatures.svg
[crate-link]: https://crates.io/crates/cpufeatures
[docs-image]: https://docs.rs/cpufeatures/badge.svg
[docs-link]: https://docs.rs/cpufeatures/
[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg
[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260052-utils
[build-image]: https://github.com/RustCrypto/utils/actions/workflows/cpufeatures.yml/badge.svg?branch=master
[build-link]: https://github.com/RustCrypto/utils/actions/workflows/cpufeatures.yml?query=branch:master

[//]: # (general links)

[RustCrypto]: https://github.com/RustCrypto
[RustCrypto/utils#378]: https://github.com/RustCrypto/utils/issues/378
[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