diff options
Diffstat (limited to 'library/std_detect/src')
| -rw-r--r-- | library/std_detect/src/detect/arch/loongarch.rs | 3 | ||||
| -rw-r--r-- | library/std_detect/src/detect/arch/mod.rs | 36 | ||||
| -rw-r--r-- | library/std_detect/src/detect/arch/riscv.rs | 197 | ||||
| -rw-r--r-- | library/std_detect/src/detect/arch/x86.rs | 6 | ||||
| -rw-r--r-- | library/std_detect/src/detect/cache.rs | 14 | ||||
| -rw-r--r-- | library/std_detect/src/detect/mod.rs | 36 | ||||
| -rw-r--r-- | library/std_detect/src/detect/os/freebsd/mod.rs | 13 | ||||
| -rw-r--r-- | library/std_detect/src/detect/os/linux/auxvec.rs | 9 | ||||
| -rw-r--r-- | library/std_detect/src/detect/os/linux/auxvec/tests.rs | 8 | ||||
| -rw-r--r-- | library/std_detect/src/detect/os/linux/loongarch.rs | 13 | ||||
| -rw-r--r-- | library/std_detect/src/detect/os/linux/mod.rs | 25 | ||||
| -rw-r--r-- | library/std_detect/src/detect/os/riscv.rs | 22 | ||||
| -rw-r--r-- | library/std_detect/src/detect/os/x86.rs | 66 | ||||
| -rw-r--r-- | library/std_detect/src/lib.rs | 2 |
14 files changed, 276 insertions, 174 deletions
diff --git a/library/std_detect/src/detect/arch/loongarch.rs b/library/std_detect/src/detect/arch/loongarch.rs index 68fc600fa8e..d5a442fbbb8 100644 --- a/library/std_detect/src/detect/arch/loongarch.rs +++ b/library/std_detect/src/detect/arch/loongarch.rs @@ -8,6 +8,7 @@ features! { /// Checks if `loongarch` feature is enabled. /// Supported arguments are: /// + /// * `"32s"` /// * `"f"` /// * `"d"` /// * `"frecipe"` @@ -22,6 +23,8 @@ features! { /// * `"lvz"` /// * `"ual"` #[stable(feature = "stdarch_loongarch_feature", since = "1.89.0")] + @FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] _32s: "32s"; + /// 32S @FEATURE: #[stable(feature = "stdarch_loongarch_feature", since = "1.89.0")] f: "f"; /// F @FEATURE: #[stable(feature = "stdarch_loongarch_feature", since = "1.89.0")] d: "d"; diff --git a/library/std_detect/src/detect/arch/mod.rs b/library/std_detect/src/detect/arch/mod.rs index b0be554ed89..c066b9cc681 100644 --- a/library/std_detect/src/detect/arch/mod.rs +++ b/library/std_detect/src/detect/arch/mod.rs @@ -1,7 +1,5 @@ #![allow(dead_code)] -use cfg_if::cfg_if; - // Export the macros for all supported architectures. #[macro_use] mod x86; @@ -24,38 +22,48 @@ mod loongarch; #[macro_use] mod s390x; -cfg_if! { - if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { +cfg_select! { + any(target_arch = "x86", target_arch = "x86_64") => { #[stable(feature = "simd_x86", since = "1.27.0")] pub use x86::*; - } else if #[cfg(target_arch = "arm")] { + } + target_arch = "arm" => { #[unstable(feature = "stdarch_arm_feature_detection", issue = "111190")] pub use arm::*; - } else if #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] { + } + any(target_arch = "aarch64", target_arch = "arm64ec") => { #[stable(feature = "simd_aarch64", since = "1.60.0")] pub use aarch64::*; - } else if #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] { + } + any(target_arch = "riscv32", target_arch = "riscv64") => { #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] pub use riscv::*; - } else if #[cfg(target_arch = "powerpc")] { + } + target_arch = "powerpc" => { #[unstable(feature = "stdarch_powerpc_feature_detection", issue = "111191")] pub use powerpc::*; - } else if #[cfg(target_arch = "powerpc64")] { + } + target_arch = "powerpc64" => { #[unstable(feature = "stdarch_powerpc_feature_detection", issue = "111191")] pub use powerpc64::*; - } else if #[cfg(target_arch = "mips")] { + } + target_arch = "mips" => { #[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")] pub use mips::*; - } else if #[cfg(target_arch = "mips64")] { + } + target_arch = "mips64" => { #[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")] pub use mips64::*; - } else if #[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))] { + } + any(target_arch = "loongarch32", target_arch = "loongarch64") => { #[stable(feature = "stdarch_loongarch_feature", since = "1.89.0")] pub use loongarch::*; - } else if #[cfg(target_arch = "s390x")] { + } + target_arch = "s390x" => { #[unstable(feature = "stdarch_s390x_feature_detection", issue = "135413")] pub use s390x::*; - } else { + } + _ => { // Unimplemented architecture: #[doc(hidden)] pub(crate) enum Feature { diff --git a/library/std_detect/src/detect/arch/riscv.rs b/library/std_detect/src/detect/arch/riscv.rs index 1d21b1d4855..1e57d09edb1 100644 --- a/library/std_detect/src/detect/arch/riscv.rs +++ b/library/std_detect/src/detect/arch/riscv.rs @@ -37,90 +37,121 @@ features! { /// /// # Unprivileged Specification /// - /// The supported ratified RISC-V instruction sets are as follows: + /// The supported ratified RISC-V instruction sets are as follows (OS + /// columns denote runtime feature detection support with or without the + /// minimum supported version): /// - /// * RV32E: `"rv32e"` - /// * RV32I: `"rv32i"` - /// * RV64I: `"rv64i"` - /// * A: `"a"` - /// * Zaamo: `"zaamo"` - /// * Zalrsc: `"zalrsc"` - /// * B: `"b"` - /// * Zba: `"zba"` - /// * Zbb: `"zbb"` - /// * Zbs: `"zbs"` - /// * C: `"c"` - /// * Zca: `"zca"` - /// * Zcd: `"zcd"` (if D is enabled) - /// * Zcf: `"zcf"` (if F is enabled on RV32) - /// * D: `"d"` - /// * F: `"f"` - /// * M: `"m"` - /// * Q: `"q"` - /// * V: `"v"` - /// * Zve32x: `"zve32x"` - /// * Zve32f: `"zve32f"` - /// * Zve64x: `"zve64x"` - /// * Zve64f: `"zve64f"` - /// * Zve64d: `"zve64d"` - /// * Zicbom: `"zicbom"` - /// * Zicboz: `"zicboz"` - /// * Zicntr: `"zicntr"` - /// * Zicond: `"zicond"` - /// * Zicsr: `"zicsr"` - /// * Zifencei: `"zifencei"` - /// * Zihintntl: `"zihintntl"` - /// * Zihintpause: `"zihintpause"` - /// * Zihpm: `"zihpm"` - /// * Zimop: `"zimop"` - /// * Zabha: `"zabha"` - /// * Zacas: `"zacas"` - /// * Zawrs: `"zawrs"` - /// * Zfa: `"zfa"` - /// * Zfbfmin: `"zfbfmin"` - /// * Zfh: `"zfh"` - /// * Zfhmin: `"zfhmin"` - /// * Zfinx: `"zfinx"` - /// * Zdinx: `"zdinx"` - /// * Zhinx: `"zhinx"` - /// * Zhinxmin: `"zhinxmin"` - /// * Zcb: `"zcb"` - /// * Zcmop: `"zcmop"` - /// * Zbc: `"zbc"` - /// * Zbkb: `"zbkb"` - /// * Zbkc: `"zbkc"` - /// * Zbkx: `"zbkx"` - /// * Zk: `"zk"` - /// * Zkn: `"zkn"` - /// * Zknd: `"zknd"` - /// * Zkne: `"zkne"` - /// * Zknh: `"zknh"` - /// * Zkr: `"zkr"` - /// * Zks: `"zks"` - /// * Zksed: `"zksed"` - /// * Zksh: `"zksh"` - /// * Zkt: `"zkt"` - /// * Zvbb: `"zvbb"` - /// * Zvbc: `"zvbc"` - /// * Zvfbfmin: `"zvfbfmin"` - /// * Zvfbfwma: `"zvfbfwma"` - /// * Zvfh: `"zvfh"` - /// * Zvfhmin: `"zvfhmin"` - /// * Zvkb: `"zvkb"` - /// * Zvkg: `"zvkg"` - /// * Zvkn: `"zvkn"` - /// * Zvkned: `"zvkned"` - /// * Zvknha: `"zvknha"` - /// * Zvknhb: `"zvknhb"` - /// * Zvknc: `"zvknc"` - /// * Zvkng: `"zvkng"` - /// * Zvks: `"zvks"` - /// * Zvksed: `"zvksed"` - /// * Zvksh: `"zvksh"` - /// * Zvksc: `"zvksc"` - /// * Zvksg: `"zvksg"` - /// * Zvkt: `"zvkt"` - /// * Ztso: `"ztso"` + /// | Literal | Base | Linux | + /// |:---------- |:------- |:---------- | + /// | `"rv32e"` | RV32E | No | + /// | `"rv32i"` | RV32I | Yes [^ima] | + /// | `"rv64i"` | RV64I | Yes [^ima] | + /// + /// | Literal | Extension | Linux | + /// |:--------------- |:----------- |:------------------- | + /// | `"a"` | A | Yes [^ima] | + /// | `"b"` | B | 6.5 | + /// | `"c"` | C | Yes | + /// | `"d"` | D | Yes | + /// | `"f"` | F | Yes | + /// | `"m"` | M | Yes [^ima] | + /// | `"q"` | Q | No | + /// | `"v"` | V | 6.5 | + /// | `"zaamo"` | Zaamo | 6.15 [^ima] [^dep] | + /// | `"zabha"` | Zabha | 6.16 | + /// | `"zacas"` | Zacas | 6.8 | + /// | `"zalrsc"` | Zalrsc | 6.15 [^ima] [^dep] | + /// | `"zawrs"` | Zawrs | 6.11 | + /// | `"zba"` | Zba | 6.5 | + /// | `"zbb"` | Zbb | 6.5 | + /// | `"zbc"` | Zbc | 6.8 | + /// | `"zbkb"` | Zbkb | 6.8 | + /// | `"zbkc"` | Zbkc | 6.8 | + /// | `"zbkx"` | Zbkx | 6.8 | + /// | `"zbs"` | Zbs | 6.5 | + /// | `"zca"` | Zca | 6.11 [^dep] | + /// | `"zcb"` | Zcb | 6.11 | + /// | `"zcd"` | Zcd | 6.11 [^dep] | + /// | `"zcf"` | Zcf | 6.11 [^dep] | + /// | `"zcmop"` | Zcmop | 6.11 | + /// | `"zdinx"` | Zdinx | No | + /// | `"zfa"` | Zfa | 6.8 | + /// | `"zfbfmin"` | Zfbfmin | 6.15 | + /// | `"zfh"` | Zfh | 6.8 | + /// | `"zfhmin"` | Zfhmin | 6.8 | + /// | `"zfinx"` | Zfinx | No | + /// | `"zhinx"` | Zhinx | No | + /// | `"zhinxmin"` | Zhinxmin | No | + /// | `"zicbom"` | Zicbom | 6.15 | + /// | `"zicboz"` | Zicboz | 6.7 | + /// | `"zicntr"` | Zicntr | 6.15 [^ima] [^cntr] | + /// | `"zicond"` | Zicond | 6.8 | + /// | `"zicsr"` | Zicsr | No [^ima] [^dep] | + /// | `"zifencei"` | Zifencei | No [^ima] | + /// | `"zihintntl"` | Zihintntl | 6.8 | + /// | `"zihintpause"` | Zihintpause | 6.10 | + /// | `"zihpm"` | Zihpm | 6.15 [^cntr] | + /// | `"zimop"` | Zimop | 6.11 | + /// | `"zk"` | Zk | No [^zkr] | + /// | `"zkn"` | Zkn | 6.8 | + /// | `"zknd"` | Zknd | 6.8 | + /// | `"zkne"` | Zkne | 6.8 | + /// | `"zknh"` | Zknh | 6.8 | + /// | `"zkr"` | Zkr | No [^zkr] | + /// | `"zks"` | Zks | 6.8 | + /// | `"zksed"` | Zksed | 6.8 | + /// | `"zksh"` | Zksh | 6.8 | + /// | `"zkt"` | Zkt | 6.8 | + /// | `"ztso"` | Ztso | 6.8 | + /// | `"zvbb"` | Zvbb | 6.8 | + /// | `"zvbc"` | Zvbc | 6.8 | + /// | `"zve32f"` | Zve32f | 6.11 [^dep] | + /// | `"zve32x"` | Zve32x | 6.11 [^dep] | + /// | `"zve64d"` | Zve64d | 6.11 [^dep] | + /// | `"zve64f"` | Zve64f | 6.11 [^dep] | + /// | `"zve64x"` | Zve64x | 6.11 [^dep] | + /// | `"zvfbfmin"` | Zvfbfmin | 6.15 | + /// | `"zvfbfwma"` | Zvfbfwma | 6.15 | + /// | `"zvfh"` | Zvfh | 6.8 | + /// | `"zvfhmin"` | Zvfhmin | 6.8 | + /// | `"zvkb"` | Zvkb | 6.8 | + /// | `"zvkg"` | Zvkg | 6.8 | + /// | `"zvkn"` | Zvkn | 6.8 | + /// | `"zvknc"` | Zvknc | 6.8 | + /// | `"zvkned"` | Zvkned | 6.8 | + /// | `"zvkng"` | Zvkng | 6.8 | + /// | `"zvknha"` | Zvknha | 6.8 | + /// | `"zvknhb"` | Zvknhb | 6.8 | + /// | `"zvks"` | Zvks | 6.8 | + /// | `"zvksc"` | Zvksc | 6.8 | + /// | `"zvksed"` | Zvksed | 6.8 | + /// | `"zvksg"` | Zvksg | 6.8 | + /// | `"zvksh"` | Zvksh | 6.8 | + /// | `"zvkt"` | Zvkt | 6.8 | + /// + /// [^ima]: Or enabled when the IMA base behavior is detected on the Linux + /// kernel version 6.4 or later (for bases, the only matching one -- either + /// `"rv32i"` or `"rv64i"` -- is enabled). + /// + /// [^cntr]: Even if this extension is available, it does not necessarily + /// mean all performance counters are accessible. + /// For example, accesses to all performance counters except `time` + /// (wall-clock) are blocked by default on the Linux kernel + /// version 6.6 or later. + /// Also beware that, even if performance counters like `cycle` and + /// `instret` are accessible, their value can be unreliable (e.g. returning + /// the constant value) under certain circumstances. + /// + /// [^dep]: Or enabled as a dependency of another extension (a superset) + /// even if runtime detection of this feature itself is not supported (as + /// long as the runtime detection of the superset is supported). + /// + /// [^zkr]: Linux does not report existence of this extension even if + /// supported by the hardware mainly because the `seed` CSR on the Zkr + /// extension (which provides hardware-based randomness) is normally + /// inaccessible from the user mode. + /// For the Zk extension features except this CSR, check existence of both + /// `"zkn"` and `"zkt"` features instead. /// /// There's also bases and extensions marked as standard instruction set, /// but they are in frozen or draft state. These instruction sets are also diff --git a/library/std_detect/src/detect/arch/x86.rs b/library/std_detect/src/detect/arch/x86.rs index 28b3e3cfb35..bd749b88f56 100644 --- a/library/std_detect/src/detect/arch/x86.rs +++ b/library/std_detect/src/detect/arch/x86.rs @@ -233,6 +233,12 @@ features! { /// AMX-TF32 (TensorFloat32 Operations) @FEATURE: #[unstable(feature = "x86_amx_intrinsics", issue = "126622")] amx_transpose: "amx-transpose"; /// AMX-TRANSPOSE (Matrix Transpose Operations) + @FEATURE: #[unstable(feature = "apx_target_feature", issue = "139284")] apxf: "apxf"; + /// APX-F (Advanced Performance Extensions - Foundation) + @FEATURE: #[unstable(feature = "avx10_target_feature", issue = "138843")] avx10_1: "avx10.1"; + /// AVX10.1 + @FEATURE: #[unstable(feature = "avx10_target_feature", issue = "138843")] avx10_2: "avx10.2"; + /// AVX10.2 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] f16c: "f16c"; /// F16C (Conversions between IEEE-754 `binary16` and `binary32` formats) @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] fma: "fma"; diff --git a/library/std_detect/src/detect/cache.rs b/library/std_detect/src/detect/cache.rs index 1a42e091463..c0c0b7b7f86 100644 --- a/library/std_detect/src/detect/cache.rs +++ b/library/std_detect/src/detect/cache.rs @@ -101,8 +101,8 @@ impl Cache { } } -cfg_if::cfg_if! { - if #[cfg(feature = "std_detect_env_override")] { +cfg_select! { + feature = "std_detect_env_override" => { #[inline] fn disable_features(disable: &[u8], value: &mut Initializer) { if let Ok(disable) = core::str::from_utf8(disable) { @@ -116,8 +116,8 @@ cfg_if::cfg_if! { fn initialize(mut value: Initializer) -> Initializer { use core::ffi::CStr; const RUST_STD_DETECT_UNSTABLE: &CStr = c"RUST_STD_DETECT_UNSTABLE"; - cfg_if::cfg_if! { - if #[cfg(windows)] { + cfg_select! { + windows => { use alloc::vec; #[link(name = "kernel32")] unsafe extern "system" { @@ -132,7 +132,8 @@ cfg_if::cfg_if! { disable_features(&env[..len as usize], &mut value); } } - } else { + } + _ => { let env = unsafe { libc::getenv(RUST_STD_DETECT_UNSTABLE.as_ptr()) }; @@ -146,7 +147,8 @@ cfg_if::cfg_if! { do_initialize(value); value } - } else { + } + _ => { #[inline] fn initialize(value: Initializer) -> Initializer { do_initialize(value); diff --git a/library/std_detect/src/detect/mod.rs b/library/std_detect/src/detect/mod.rs index f936a5a1345..2bc6e9a24db 100644 --- a/library/std_detect/src/detect/mod.rs +++ b/library/std_detect/src/detect/mod.rs @@ -17,8 +17,6 @@ //! due to security concerns (x86 is the big exception). These functions are //! implemented in the `os/{target_os}.rs` modules. -use cfg_if::cfg_if; - #[macro_use] mod macros; @@ -34,8 +32,8 @@ pub(crate) use self::arch::Feature; mod bit; mod cache; -cfg_if! { - if #[cfg(miri)] { +cfg_select! { + miri => { // When running under miri all target-features that are not enabled at // compile-time are reported as disabled at run-time. // @@ -43,35 +41,42 @@ cfg_if! { // this run-time detection logic is never called. #[path = "os/other.rs"] mod os; - } else if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { + } + any(target_arch = "x86", target_arch = "x86_64") => { // On x86/x86_64 no OS specific functionality is required. #[path = "os/x86.rs"] mod os; - } else if #[cfg(all(any(target_os = "linux", target_os = "android"), feature = "libc"))] { + } + all(any(target_os = "linux", target_os = "android"), feature = "libc") => { #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] #[path = "os/riscv.rs"] mod riscv; #[path = "os/linux/mod.rs"] mod os; - } else if #[cfg(all(target_os = "freebsd", feature = "libc"))] { + } + all(target_os = "freebsd", feature = "libc") => { #[cfg(target_arch = "aarch64")] #[path = "os/aarch64.rs"] mod aarch64; #[path = "os/freebsd/mod.rs"] mod os; - } else if #[cfg(all(target_os = "openbsd", target_arch = "aarch64", feature = "libc"))] { + } + all(target_os = "openbsd", target_arch = "aarch64", feature = "libc") => { #[allow(dead_code)] // we don't use code that calls the mrs instruction. #[path = "os/aarch64.rs"] mod aarch64; #[path = "os/openbsd/aarch64.rs"] mod os; - } else if #[cfg(all(target_os = "windows", any(target_arch = "aarch64", target_arch = "arm64ec")))] { + } + all(target_os = "windows", any(target_arch = "aarch64", target_arch = "arm64ec")) => { #[path = "os/windows/aarch64.rs"] mod os; - } else if #[cfg(all(target_vendor = "apple", target_arch = "aarch64", feature = "libc"))] { + } + all(target_vendor = "apple", target_arch = "aarch64", feature = "libc") => { #[path = "os/darwin/aarch64.rs"] mod os; - } else { + } + _ => { #[path = "os/other.rs"] mod os; } @@ -89,8 +94,8 @@ fn check_for(x: Feature) -> bool { /// is `true` if the feature is supported by the host and `false` otherwise. #[unstable(feature = "stdarch_internal", issue = "none")] pub fn features() -> impl Iterator<Item = (&'static str, bool)> { - cfg_if! { - if #[cfg(any( + cfg_select! { + any( target_arch = "x86", target_arch = "x86_64", target_arch = "arm", @@ -105,7 +110,7 @@ pub fn features() -> impl Iterator<Item = (&'static str, bool)> { target_arch = "loongarch32", target_arch = "loongarch64", target_arch = "s390x", - ))] { + ) => { (0_u8..Feature::_last as u8).map(|discriminant: u8| { #[allow(bindings_with_variant_name)] // RISC-V has Feature::f let f: Feature = unsafe { core::mem::transmute(discriminant) }; @@ -113,8 +118,7 @@ pub fn features() -> impl Iterator<Item = (&'static str, bool)> { let enabled: bool = check_for(f); (name, enabled) }) - } else { - None.into_iter() } + _ => None.into_iter(), } } diff --git a/library/std_detect/src/detect/os/freebsd/mod.rs b/library/std_detect/src/detect/os/freebsd/mod.rs index ade7fb6269d..7de9250e835 100644 --- a/library/std_detect/src/detect/os/freebsd/mod.rs +++ b/library/std_detect/src/detect/os/freebsd/mod.rs @@ -2,17 +2,20 @@ mod auxvec; -cfg_if::cfg_if! { - if #[cfg(target_arch = "aarch64")] { +cfg_select! { + target_arch = "aarch64" => { mod aarch64; pub(crate) use self::aarch64::detect_features; - } else if #[cfg(target_arch = "arm")] { + } + target_arch = "arm" => { mod arm; pub(crate) use self::arm::detect_features; - } else if #[cfg(target_arch = "powerpc64")] { + } + target_arch = "powerpc64" => { mod powerpc; pub(crate) use self::powerpc::detect_features; - } else { + } + _ => { use crate::detect::cache; /// Performs run-time feature detection. pub(crate) fn detect_features() -> cache::Initializer { diff --git a/library/std_detect/src/detect/os/linux/auxvec.rs b/library/std_detect/src/detect/os/linux/auxvec.rs index 443caaaa186..75e01bdc449 100644 --- a/library/std_detect/src/detect/os/linux/auxvec.rs +++ b/library/std_detect/src/detect/os/linux/auxvec.rs @@ -131,15 +131,15 @@ pub(crate) fn auxv() -> Result<AuxVec, ()> { /// `getauxval` function. If the function is not linked, this function return `Err`. fn getauxval(key: usize) -> Result<usize, ()> { type F = unsafe extern "C" fn(libc::c_ulong) -> libc::c_ulong; - cfg_if::cfg_if! { - if #[cfg(all( + cfg_select! { + all( feature = "std_detect_dlsym_getauxval", not(all( target_os = "linux", any(target_env = "gnu", target_env = "musl", target_env = "ohos"), )), not(target_os = "android"), - ))] { + ) => { let ffi_getauxval: F = unsafe { let ptr = libc::dlsym(libc::RTLD_DEFAULT, c"getauxval".as_ptr()); if ptr.is_null() { @@ -147,7 +147,8 @@ fn getauxval(key: usize) -> Result<usize, ()> { } core::mem::transmute(ptr) }; - } else { + } + _ => { let ffi_getauxval: F = libc::getauxval; } } diff --git a/library/std_detect/src/detect/os/linux/auxvec/tests.rs b/library/std_detect/src/detect/os/linux/auxvec/tests.rs index 536615fa272..631a3e5e9ef 100644 --- a/library/std_detect/src/detect/os/linux/auxvec/tests.rs +++ b/library/std_detect/src/detect/os/linux/auxvec/tests.rs @@ -42,8 +42,8 @@ fn auxv_dump() { } #[cfg(feature = "std_detect_file_io")] -cfg_if::cfg_if! { - if #[cfg(target_arch = "arm")] { +cfg_select! { + target_arch = "arm" => { // The tests below can be executed under qemu, where we do not have access to the test // files on disk, so we need to embed them with `include_bytes!`. #[test] @@ -62,7 +62,8 @@ cfg_if::cfg_if! { assert_eq!(v.hwcap, 126614527); assert_eq!(v.hwcap2, 0); } - } else if #[cfg(target_arch = "aarch64")] { + } + target_arch = "aarch64" => { #[cfg(target_endian = "little")] #[test] fn linux_artificial_aarch64() { @@ -81,6 +82,7 @@ cfg_if::cfg_if! { assert_eq!(v.hwcap2, 0); } } + _ => {} } #[test] diff --git a/library/std_detect/src/detect/os/linux/loongarch.rs b/library/std_detect/src/detect/os/linux/loongarch.rs index e97fda11d08..74415266f8b 100644 --- a/library/std_detect/src/detect/os/linux/loongarch.rs +++ b/library/std_detect/src/detect/os/linux/loongarch.rs @@ -17,22 +17,21 @@ pub(crate) fn detect_features() -> cache::Initializer { // The values are part of the platform-specific [cpucfg] // // [cpucfg]: LoongArch Reference Manual Volume 1: Basic Architecture v1.1 + let cpucfg1: usize; let cpucfg2: usize; - unsafe { - asm!( - "cpucfg {}, {}", - out(reg) cpucfg2, in(reg) 2, - options(pure, nomem, preserves_flags, nostack) - ); - } let cpucfg3: usize; unsafe { asm!( "cpucfg {}, {}", + "cpucfg {}, {}", + "cpucfg {}, {}", + out(reg) cpucfg1, in(reg) 1, + out(reg) cpucfg2, in(reg) 2, out(reg) cpucfg3, in(reg) 3, options(pure, nomem, preserves_flags, nostack) ); } + enable_feature(&mut value, Feature::_32s, bit::test(cpucfg1, 0) || bit::test(cpucfg1, 1)); enable_feature(&mut value, Feature::frecipe, bit::test(cpucfg2, 25)); enable_feature(&mut value, Feature::div32, bit::test(cpucfg2, 26)); enable_feature(&mut value, Feature::lam_bh, bit::test(cpucfg2, 27)); diff --git a/library/std_detect/src/detect/os/linux/mod.rs b/library/std_detect/src/detect/os/linux/mod.rs index 5ae2aaeab5b..5273c16c089 100644 --- a/library/std_detect/src/detect/os/linux/mod.rs +++ b/library/std_detect/src/detect/os/linux/mod.rs @@ -37,29 +37,36 @@ fn read_file(orig_path: &str) -> Result<Vec<u8>, alloc::string::String> { } } -cfg_if::cfg_if! { - if #[cfg(target_arch = "aarch64")] { +cfg_select! { + target_arch = "aarch64" => { mod aarch64; pub(crate) use self::aarch64::detect_features; - } else if #[cfg(target_arch = "arm")] { + } + target_arch = "arm" => { mod arm; pub(crate) use self::arm::detect_features; - } else if #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] { + } + any(target_arch = "riscv32", target_arch = "riscv64") => { mod riscv; pub(crate) use self::riscv::detect_features; - } else if #[cfg(any(target_arch = "mips", target_arch = "mips64"))] { + } + any(target_arch = "mips", target_arch = "mips64") => { mod mips; pub(crate) use self::mips::detect_features; - } else if #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] { + } + any(target_arch = "powerpc", target_arch = "powerpc64") => { mod powerpc; pub(crate) use self::powerpc::detect_features; - } else if #[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))] { + } + any(target_arch = "loongarch32", target_arch = "loongarch64") => { mod loongarch; pub(crate) use self::loongarch::detect_features; - } else if #[cfg(target_arch = "s390x")] { + } + target_arch = "s390x" => { mod s390x; pub(crate) use self::s390x::detect_features; - } else { + } + _ => { use crate::detect::cache; /// Performs run-time feature detection. pub(crate) fn detect_features() -> cache::Initializer { diff --git a/library/std_detect/src/detect/os/riscv.rs b/library/std_detect/src/detect/os/riscv.rs index c6acbd3525b..9b9e0cba09d 100644 --- a/library/std_detect/src/detect/os/riscv.rs +++ b/library/std_detect/src/detect/os/riscv.rs @@ -119,11 +119,31 @@ pub(crate) fn imply_features(mut value: cache::Initializer) -> cache::Initialize imply!(d | zfhmin | zfa => f); imply!(zfbfmin => f); // and some of (not all) "Zfh" instructions. - // Relatively complex implication rules from the "C" extension. + // Relatively complex implication rules around the "C" extension. + // (from "C" and some others) imply!(c => zca); imply!(c & d => zcd); #[cfg(target_arch = "riscv32")] imply!(c & f => zcf); + // (to "C"; defined as superset) + cfg_select! { + target_arch = "riscv32" => { + if value.test(Feature::d as u32) { + imply!(zcf & zcd => c); + } else if value.test(Feature::f as u32) { + imply!(zcf => c); + } else { + imply!(zca => c); + } + } + _ => { + if value.test(Feature::d as u32) { + imply!(zcd => c); + } else { + imply!(zca => c); + } + } + } imply!(zicntr | zihpm | f | zfinx | zve32x => zicsr); diff --git a/library/std_detect/src/detect/os/x86.rs b/library/std_detect/src/detect/os/x86.rs index 20f848ab05c..cf11d833312 100644 --- a/library/std_detect/src/detect/os/x86.rs +++ b/library/std_detect/src/detect/os/x86.rs @@ -137,6 +137,32 @@ pub(crate) fn detect_features() -> cache::Initializer { enable(ebx, 2, Feature::widekl); } + // This detects ABM on AMD CPUs and LZCNT on Intel CPUs. + // On intel CPUs with popcnt, lzcnt implements the + // "missing part" of ABM, so we map both to the same + // internal feature. + // + // The `is_x86_feature_detected!("lzcnt")` macro then + // internally maps to Feature::abm. + enable(extended_proc_info_ecx, 5, Feature::lzcnt); + + // As Hygon Dhyana originates from AMD technology and shares most of the architecture with + // AMD's family 17h, but with different CPU Vendor ID("HygonGenuine")/Family series + // number(Family 18h). + // + // For CPUID feature bits, Hygon Dhyana(family 18h) share the same definition with AMD + // family 17h. + // + // Related AMD CPUID specification is https://www.amd.com/system/files/TechDocs/25481.pdf. + // Related Hygon kernel patch can be found on + // http://lkml.kernel.org/r/5ce86123a7b9dad925ac583d88d2f921040e859b.1538583282.git.puwen@hygon.cn + if vendor_id == *b"AuthenticAMD" || vendor_id == *b"HygonGenuine" { + // These features are available on AMD arch CPUs: + enable(extended_proc_info_ecx, 6, Feature::sse4a); + enable(extended_proc_info_ecx, 21, Feature::tbm); + enable(extended_proc_info_ecx, 11, Feature::xop); + } + // `XSAVE` and `AVX` support: let cpu_xsave = bit::test(proc_info_ecx as usize, 26); if cpu_xsave { @@ -161,6 +187,7 @@ pub(crate) fn detect_features() -> cache::Initializer { // * AVX -> `XCR0.AVX[2]` // * AVX-512 -> `XCR0.AVX-512[7:5]`. // * AMX -> `XCR0.AMX[18:17]` + // * APX -> `XCR0.APX[19]` // // by setting the corresponding bits of `XCR0` to `1`. // @@ -173,6 +200,8 @@ pub(crate) fn detect_features() -> cache::Initializer { let os_avx512_support = xcr0 & 0xe0 == 0xe0; // Test `XCR0.AMX[18:17]` with the mask `0b110_0000_0000_0000_0000 == 0x60000` let os_amx_support = xcr0 & 0x60000 == 0x60000; + // Test `XCR0.APX[19]` with the mask `0b1000_0000_0000_0000_0000 == 0x80000` + let os_apx_support = xcr0 & 0x80000 == 0x80000; // Only if the OS and the CPU support saving/restoring the AVX // registers we enable `xsave` support: @@ -262,33 +291,20 @@ pub(crate) fn detect_features() -> cache::Initializer { enable(amx_feature_flags_eax, 8, Feature::amx_movrs); } } - } - } - // This detects ABM on AMD CPUs and LZCNT on Intel CPUs. - // On intel CPUs with popcnt, lzcnt implements the - // "missing part" of ABM, so we map both to the same - // internal feature. - // - // The `is_x86_feature_detected!("lzcnt")` macro then - // internally maps to Feature::abm. - enable(extended_proc_info_ecx, 5, Feature::lzcnt); + if os_apx_support { + enable(extended_features_edx_leaf_1, 21, Feature::apxf); + } - // As Hygon Dhyana originates from AMD technology and shares most of the architecture with - // AMD's family 17h, but with different CPU Vendor ID("HygonGenuine")/Family series - // number(Family 18h). - // - // For CPUID feature bits, Hygon Dhyana(family 18h) share the same definition with AMD - // family 17h. - // - // Related AMD CPUID specification is https://www.amd.com/system/files/TechDocs/25481.pdf. - // Related Hygon kernel patch can be found on - // http://lkml.kernel.org/r/5ce86123a7b9dad925ac583d88d2f921040e859b.1538583282.git.puwen@hygon.cn - if vendor_id == *b"AuthenticAMD" || vendor_id == *b"HygonGenuine" { - // These features are available on AMD arch CPUs: - enable(extended_proc_info_ecx, 6, Feature::sse4a); - enable(extended_proc_info_ecx, 21, Feature::tbm); - enable(extended_proc_info_ecx, 11, Feature::xop); + let avx10_1 = enable(extended_features_edx_leaf_1, 19, Feature::avx10_1); + if avx10_1 { + let CpuidResult { ebx, .. } = unsafe { __cpuid(0x24) }; + let avx10_version = ebx & 0xff; + if avx10_version >= 2 { + value.set(Feature::avx10_2 as u32); + } + } + } } } diff --git a/library/std_detect/src/lib.rs b/library/std_detect/src/lib.rs index ab1b77bad5b..73e2f5dd964 100644 --- a/library/std_detect/src/lib.rs +++ b/library/std_detect/src/lib.rs @@ -15,7 +15,7 @@ //! * `s390x`: [`is_s390x_feature_detected`] #![unstable(feature = "stdarch_internal", issue = "none")] -#![feature(staged_api, doc_cfg, allow_internal_unstable)] +#![feature(staged_api, cfg_select, doc_cfg, allow_internal_unstable)] #![deny(rust_2018_idioms)] #![allow(clippy::shadow_reuse)] #![cfg_attr(test, allow(unused_imports))] |
