about summary refs log tree commit diff
path: root/library/std_detect
diff options
context:
space:
mode:
Diffstat (limited to 'library/std_detect')
-rw-r--r--library/std_detect/Cargo.toml5
-rw-r--r--library/std_detect/src/detect/arch/loongarch.rs3
-rw-r--r--library/std_detect/src/detect/arch/mod.rs36
-rw-r--r--library/std_detect/src/detect/arch/riscv.rs197
-rw-r--r--library/std_detect/src/detect/arch/x86.rs6
-rw-r--r--library/std_detect/src/detect/cache.rs14
-rw-r--r--library/std_detect/src/detect/mod.rs36
-rw-r--r--library/std_detect/src/detect/os/freebsd/mod.rs13
-rw-r--r--library/std_detect/src/detect/os/linux/auxvec.rs9
-rw-r--r--library/std_detect/src/detect/os/linux/auxvec/tests.rs8
-rw-r--r--library/std_detect/src/detect/os/linux/loongarch.rs13
-rw-r--r--library/std_detect/src/detect/os/linux/mod.rs25
-rw-r--r--library/std_detect/src/detect/os/riscv.rs22
-rw-r--r--library/std_detect/src/detect/os/x86.rs66
-rw-r--r--library/std_detect/src/lib.rs2
-rw-r--r--library/std_detect/tests/macro_trailing_commas.rs2
16 files changed, 280 insertions, 177 deletions
diff --git a/library/std_detect/Cargo.toml b/library/std_detect/Cargo.toml
index 8d91454726b..2739bb59230 100644
--- a/library/std_detect/Cargo.toml
+++ b/library/std_detect/Cargo.toml
@@ -21,9 +21,8 @@ is-it-maintained-open-issues = { repository = "rust-lang/stdarch" }
 maintenance = { status = "experimental" }
 
 [dependencies]
-cfg-if = "1.0.0"
-core = { path = "../core" }
-alloc = { path = "../alloc" }
+core = { version = "1.0.0", package = 'rustc-std-workspace-core' }
+alloc = { version = "1.0.0", package = 'rustc-std-workspace-alloc' }
 
 [target.'cfg(not(windows))'.dependencies]
 libc = { version = "0.2.0", optional = true, default-features = false }
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))]
diff --git a/library/std_detect/tests/macro_trailing_commas.rs b/library/std_detect/tests/macro_trailing_commas.rs
index 2fee0abdd57..6072ddf5ac4 100644
--- a/library/std_detect/tests/macro_trailing_commas.rs
+++ b/library/std_detect/tests/macro_trailing_commas.rs
@@ -69,6 +69,8 @@ fn aarch64() {
 #[test]
 #[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))]
 fn loongarch() {
+    let _ = is_loongarch_feature_detected!("32s");
+    let _ = is_loongarch_feature_detected!("32s",);
     let _ = is_loongarch_feature_detected!("lsx");
     let _ = is_loongarch_feature_detected!("lsx",);
 }