about summary refs log tree commit diff
path: root/library/stdarch/crates/std_detect
diff options
context:
space:
mode:
authorAdam Gemmell <adam.gemmell@arm.com>2021-05-28 01:37:20 +0100
committerGitHub <noreply@github.com>2021-05-28 01:37:20 +0100
commit1069e6643997c2c2a0a348be12c8996e7338ce1d (patch)
tree3b3437cf6afdcd6b84bb2a802106db9a190c528d /library/stdarch/crates/std_detect
parent3c3db50bbf13353fdbda9a3d38b0c2ba55950335 (diff)
downloadrust-1069e6643997c2c2a0a348be12c8996e7338ce1d.tar.gz
rust-1069e6643997c2c2a0a348be12c8996e7338ce1d.zip
Update aarch64 linux feature detection (#1146)
Diffstat (limited to 'library/stdarch/crates/std_detect')
-rw-r--r--library/stdarch/crates/std_detect/src/detect/arch/aarch64.rs138
-rw-r--r--library/stdarch/crates/std_detect/src/detect/arch/arm.rs6
-rw-r--r--library/stdarch/crates/std_detect/src/detect/bit.rs2
-rw-r--r--library/stdarch/crates/std_detect/src/detect/os/aarch64.rs12
-rw-r--r--library/stdarch/crates/std_detect/src/detect/os/freebsd/aarch64.rs3
-rw-r--r--library/stdarch/crates/std_detect/src/detect/os/freebsd/auxvec.rs9
-rw-r--r--library/stdarch/crates/std_detect/src/detect/os/linux/aarch64.rs204
-rw-r--r--library/stdarch/crates/std_detect/src/detect/os/linux/arm.rs13
-rw-r--r--library/stdarch/crates/std_detect/src/detect/os/windows/aarch64.rs6
-rw-r--r--library/stdarch/crates/std_detect/tests/cpu-detection.rs40
10 files changed, 368 insertions, 65 deletions
diff --git a/library/stdarch/crates/std_detect/src/detect/arch/aarch64.rs b/library/stdarch/crates/std_detect/src/detect/arch/aarch64.rs
index 761cde9583d..81979ba9672 100644
--- a/library/stdarch/crates/std_detect/src/detect/arch/aarch64.rs
+++ b/library/stdarch/crates/std_detect/src/detect/arch/aarch64.rs
@@ -4,35 +4,145 @@ features! {
     @TARGET: aarch64;
     @MACRO_NAME: is_aarch64_feature_detected;
     @MACRO_ATTRS:
-    /// Checks if `aarch64` feature is enabled.
+    /// This macro tests, at runtime, whether an `aarch64` feature is enabled on aarch64 platforms.
+    /// Currently most features are only supported on linux-based platforms.
+    ///
+    /// This macro takes one argument which is a string literal of the feature being tested for.
+    /// The feature names are mostly taken from their FEAT_* definitiions in the [ARM Architecture
+    /// Reference Manual][docs].
+    ///
+    /// ## Supported arguments
+    ///
+    /// * `"asimd"` or "neon" - FEAT_AdvSIMD
+    /// * `"pmull"` - FEAT_PMULL
+    /// * `"fp"` - FEAT_FP
+    /// * `"fp16"` - FEAT_FP16
+    /// * `"sve"` - FEAT_SVE
+    /// * `"crc"` - FEAT_CRC
+    /// * `"lse"` - FEAT_LSE
+    /// * `"lse2"` - FEAT_LSE2
+    /// * `"rdm"` - FEAT_RDM
+    /// * `"rcpc"` - FEAT_LRCPC
+    /// * `"rcpc2"` - FEAT_LRCPC2
+    /// * `"dotprod"` - FEAT_DotProd
+    /// * `"tme"` - FEAT_TME
+    /// * `"fhm"` - FEAT_FHM
+    /// * `"dit"` - FEAT_DIT
+    /// * `"flagm"` - FEAT_FLAGM
+    /// * `"ssbs"` - FEAT_SSBS
+    /// * `"sb"` - FEAT_SB
+    /// * `"pauth"` - FEAT_PAuth
+    /// * `"dpb"` - FEAT_DPB
+    /// * `"dpb2"` - FEAT_DPB2
+    /// * `"sve2"` - FEAT_SVE2
+    /// * `"sve2-aes"` - FEAT_SVE2_AES
+    /// * `"sve2-sm4"` - FEAT_SVE2_SM4
+    /// * `"sve2-sha3"` - FEAT_SVE2_SHA3
+    /// * `"sve2-bitperm"` - FEAT_SVE2_BitPerm
+    /// * `"frintts"` - FEAT_FRINTTS
+    /// * `"i8mm"` - FEAT_I8MM
+    /// * `"f32mm"` - FEAT_F32MM
+    /// * `"f64mm"` - FEAT_F64MM
+    /// * `"bf16"` - FEAT_BF16
+    /// * `"rand"` - FEAT_RNG
+    /// * `"bti"` - FEAT_BTI
+    /// * `"mte"` - FEAT_MTE
+    /// * `"jsconv"` - FEAT_JSCVT
+    /// * `"fcma"` - FEAT_FCMA
+    /// * `"aes"` - FEAT_AES
+    /// * `"sha2"` - FEAT_SHA1 & FEAT_SHA256
+    /// * `"sha3"` - FEAT_SHA512 & FEAT_SHA3
+    /// * `"sm4"` - FEAT_SM3 & FEAT_SM4
+    ///
+    /// [docs]: https://developer.arm.com/documentation/ddi0487/latest
     #[unstable(feature = "stdsimd", issue = "27731")]
     @BIND_FEATURE_NAME: "asimd"; "neon";
     @NO_RUNTIME_DETECTION: "ras";
     @NO_RUNTIME_DETECTION: "v8.1a";
     @NO_RUNTIME_DETECTION: "v8.2a";
     @NO_RUNTIME_DETECTION: "v8.3a";
+    @NO_RUNTIME_DETECTION: "v8.4a";
+    @NO_RUNTIME_DETECTION: "v8.5a";
+    @NO_RUNTIME_DETECTION: "v8.6a";
+    @NO_RUNTIME_DETECTION: "v8.7a";
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] asimd: "neon";
-    /// ARM Advanced SIMD (ASIMD)
+    /// FEAT_AdvSIMD (Advanced SIMD/NEON)
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] pmull: "pmull";
-    /// Polynomial Multiply
+    /// FEAT_PMULL (Polynomial Multiply)
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] fp: "fp";
-    /// Floating point support
+    /// FEAT_FP (Floating point support)
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] fp16: "fp16";
-    /// Half-float support.
+    /// FEAT_FP16 (Half-float support)
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] sve: "sve";
-    /// Scalable Vector Extension (SVE)
+    /// FEAT_SVE (Scalable Vector Extension)
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] crc: "crc";
-    /// CRC32 (Cyclic Redundancy Check)
-    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] crypto: "crypto";
-    /// Crypto: AES + PMULL + SHA1 + SHA2
+    /// FEAT_CRC32 (Cyclic Redundancy Check)
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] lse: "lse";
-    /// Atomics (Large System Extension)
+    /// FEAT_LSE (Large System Extension - atomics)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] lse2: "lse2";
+    /// FEAT_LSE2 (unaligned and register-pair atomics)
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] rdm: "rdm";
-    /// Rounding Double Multiply (ASIMDRDM)
+    /// FEAT_RDM (Rounding Doubling Multiply - ASIMDRDM)
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] rcpc: "rcpc";
-    /// Release consistent Processor consistent (RcPc)
+    /// FEAT_LRCPC (Release consistent Processor consistent)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] rcpc2: "rcpc2";
+    /// FEAT_LRCPC2 (RCPC with immediate offsets)
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] dotprod: "dotprod";
-    /// Vector Dot-Product (ASIMDDP)
+    /// FEAT_DotProd (Vector Dot-Product - ASIMDDP)
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] tme: "tme";
-    /// Transactional Memory Extensions (TME)
+    /// FEAT_TME (Transactional Memory Extensions)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] fhm: "fhm";
+    /// FEAT_FHM (fp16 multiplication instructions)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] dit: "dit";
+    /// FEAT_DIT (Data Independent Timing instructions)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] flagm: "flagm";
+    /// FEAT_FLAGM (flag manipulation instructions)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] ssbs: "ssbs";
+    /// FEAT_SSBS (speculative store bypass safe)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] sb: "sb";
+    /// FEAT_SB (speculation barrier)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] pauth: "pauth";
+    /// FEAT_PAuth (pointer authentication)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] dpb: "dpb";
+    /// FEAT_DPB (aka dcpop - data cache clean to point of persistance)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] dpb2: "dpb2";
+    /// FEAT_DPB2 (aka dcpodp - data cache clean to point of deep persistance)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] sve2: "sve2";
+    /// FEAT_SVE2 (Scalable Vector Extension 2)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] sve2_aes: "sve2-aes";
+    /// FEAT_SVE_AES (SVE2 AES crypto)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] sve2_sm4: "sve2-sm4";
+    /// FEAT_SVE_SM4 (SVE2 SM4 crypto)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] sve2_sha3: "sve2-sha3";
+    /// FEAT_SVE_SHA3 (SVE2 SHA3 crypto)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] sve2_bitperm: "sve2-bitperm";
+    /// FEAT_SVE_BitPerm (SVE2 bit permutation instructions)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] frintts: "frintts";
+    /// FEAT_FRINTTS (float to integer rounding instructions)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] i8mm: "i8mm";
+    /// FEAT_I8MM (integer matrix multiplication, plus ASIMD support)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] f32mm: "f32mm";
+    /// FEAT_F32MM (single-precision matrix multiplication)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] f64mm: "f64mm";
+    /// FEAT_F64MM (double-precision matrix multiplication)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] bf16: "bf16";
+    /// FEAT_BF16 (BFloat16 type, plus MM instructions, plus ASIMD support)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] rand: "rand";
+    /// FEAT_RNG (Random Number Generator)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] bti: "bti";
+    /// FEAT_BTI (Branch Target Identification)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] mte: "mte";
+    /// FEAT_MTE (Memory Tagging Extension)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] jsconv: "jsconv";
+    /// FEAT_JSCVT (JavaScript float conversion instructions)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] fcma: "fcma";
+    /// FEAT_FCMA (float complex number operations)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] aes: "aes";
+    /// FEAT_AES (AES instructions)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] sha2: "sha2";
+    /// FEAT_SHA1 & FEAT_SHA256 (SHA1 & SHA2-256 instructions)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] sha3: "sha3";
+    /// FEAT_SHA512 & FEAT_SHA3 (SHA2-512 & SHA3 instructions)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] sm4: "sm4";
+    /// FEAT_SM3 & FEAT_SM4 (SM3 & SM4 instructions)
 }
diff --git a/library/stdarch/crates/std_detect/src/detect/arch/arm.rs b/library/stdarch/crates/std_detect/src/detect/arch/arm.rs
index 46fd56384be..d96514c8449 100644
--- a/library/stdarch/crates/std_detect/src/detect/arch/arm.rs
+++ b/library/stdarch/crates/std_detect/src/detect/arch/arm.rs
@@ -17,5 +17,9 @@ features! {
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] crc: "crc";
     /// CRC32 (Cyclic Redundancy Check)
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] crypto: "crypto";
-    /// Crypto: AES + PMULL + SHA1 + SHA2
+    /// Crypto: AES + PMULL + SHA1 + SHA256. Prefer using the individual features where possible.
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] aes: "aes";
+    /// FEAT_AES (AES instructions)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] sha2: "sha2";
+    /// FEAT_SHA1 & FEAT_SHA256 (SHA1 & SHA2-256 instructions)
 }
diff --git a/library/stdarch/crates/std_detect/src/detect/bit.rs b/library/stdarch/crates/std_detect/src/detect/bit.rs
index 578f0b16b74..6f06c5523e4 100644
--- a/library/stdarch/crates/std_detect/src/detect/bit.rs
+++ b/library/stdarch/crates/std_detect/src/detect/bit.rs
@@ -4,6 +4,6 @@
 #[allow(dead_code)]
 #[inline]
 pub(crate) fn test(x: usize, bit: u32) -> bool {
-    debug_assert!(bit < 32, "bit index out-of-bounds");
+    debug_assert!(bit < usize::BITS, "bit index out-of-bounds");
     x & (1 << bit) != 0
 }
diff --git a/library/stdarch/crates/std_detect/src/detect/os/aarch64.rs b/library/stdarch/crates/std_detect/src/detect/os/aarch64.rs
index 2f289f58074..0fd2702731f 100644
--- a/library/stdarch/crates/std_detect/src/detect/os/aarch64.rs
+++ b/library/stdarch/crates/std_detect/src/detect/os/aarch64.rs
@@ -41,13 +41,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
             );
         }
 
-        let aes = bits_shift(aa64isar0, 7, 4) >= 1;
-        let pmull = bits_shift(aa64isar0, 7, 4) >= 2;
-        let sha1 = bits_shift(aa64isar0, 11, 8) >= 1;
-        let sha2 = bits_shift(aa64isar0, 15, 12) >= 1;
-        enable_feature(Feature::pmull, pmull);
-        // Crypto is specified as AES + PMULL + SHA1 + SHA2 per LLVM/hosts.cpp
-        enable_feature(Feature::crypto, aes && pmull && sha1 && sha2);
+        enable_feature(Feature::pmull, bits_shift(aa64isar0, 7, 4) >= 2);
         enable_feature(Feature::tme, bits_shift(aa64isar0, 27, 24) == 1);
         enable_feature(Feature::lse, bits_shift(aa64isar0, 23, 20) >= 1);
         enable_feature(Feature::crc, bits_shift(aa64isar0, 19, 16) >= 1);
@@ -72,6 +66,10 @@ pub(crate) fn detect_features() -> cache::Initializer {
         // supported, it also requires half-float support:
         enable_feature(Feature::asimd, fp && asimd && (!fphp | asimdhp));
         // SIMD extensions require SIMD support:
+        enable_feature(Feature::aes, asimd && bits_shift(aa64isar0, 7, 4) >= 1);
+        let sha1 = bits_shift(aa64isar0, 11, 8) >= 1;
+        let sha2 = bits_shift(aa64isar0, 15, 12) >= 1;
+        enable_feature(Feature::sha2, asimd && sha1 && sha2);
         enable_feature(Feature::rdm, asimd && bits_shift(aa64isar0, 31, 28) >= 1);
         enable_feature(
             Feature::dotprod,
diff --git a/library/stdarch/crates/std_detect/src/detect/os/freebsd/aarch64.rs b/library/stdarch/crates/std_detect/src/detect/os/freebsd/aarch64.rs
index 7e086ca057b..7d972b373f8 100644
--- a/library/stdarch/crates/std_detect/src/detect/os/freebsd/aarch64.rs
+++ b/library/stdarch/crates/std_detect/src/detect/os/freebsd/aarch64.rs
@@ -1,6 +1,6 @@
 //! Run-time feature detection for Aarch64 on FreeBSD.
 
-pub use super::super::aarch64::detect_features;
+pub(crate) use super::super::aarch64::detect_features;
 
 #[cfg(test)]
 mod tests {
@@ -12,7 +12,6 @@ mod tests {
         println!("fp16: {:?}", is_aarch64_feature_detected!("fp16"));
         println!("sve: {:?}", is_aarch64_feature_detected!("sve"));
         println!("crc: {:?}", is_aarch64_feature_detected!("crc"));
-        println!("crypto: {:?}", is_aarch64_feature_detected!("crypto"));
         println!("lse: {:?}", is_aarch64_feature_detected!("lse"));
         println!("rdm: {:?}", is_aarch64_feature_detected!("rdm"));
         println!("rcpc: {:?}", is_aarch64_feature_detected!("rcpc"));
diff --git a/library/stdarch/crates/std_detect/src/detect/os/freebsd/auxvec.rs b/library/stdarch/crates/std_detect/src/detect/os/freebsd/auxvec.rs
index 832ce2252ed..f12476adac5 100644
--- a/library/stdarch/crates/std_detect/src/detect/os/freebsd/auxvec.rs
+++ b/library/stdarch/crates/std_detect/src/detect/os/freebsd/auxvec.rs
@@ -1,5 +1,12 @@
 //! Parses ELF auxiliary vectors.
-#![cfg_attr(any(target_arch = "arm", target_arch = "powerpc64"), allow(dead_code))]
+#![cfg_attr(
+    any(
+        target_arch = "aarch64",
+        target_arch = "arm",
+        target_arch = "powerpc64"
+    ),
+    allow(dead_code)
+)]
 
 /// Key to access the CPU Hardware capabilities bitfield.
 pub(crate) const AT_HWCAP: usize = 25;
diff --git a/library/stdarch/crates/std_detect/src/detect/os/linux/aarch64.rs b/library/stdarch/crates/std_detect/src/detect/os/linux/aarch64.rs
index 80c36e9b997..4dc63620578 100644
--- a/library/stdarch/crates/std_detect/src/detect/os/linux/aarch64.rs
+++ b/library/stdarch/crates/std_detect/src/detect/os/linux/aarch64.rs
@@ -20,11 +20,13 @@ pub(crate) fn detect_features() -> cache::Initializer {
 
 /// These values are part of the platform-specific [asm/hwcap.h][hwcap] .
 ///
+/// The names match those used for cpuinfo.
+///
 /// [hwcap]: https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/hwcap.h
 struct AtHwcap {
     fp: bool,    // 0
     asimd: bool, // 1
-    // evtstrm: bool, // 2
+    // evtstrm: bool, // 2 No LLVM support
     aes: bool,     // 3
     pmull: bool,   // 4
     sha1: bool,    // 5
@@ -33,18 +35,46 @@ struct AtHwcap {
     atomics: bool, // 8
     fphp: bool,    // 9
     asimdhp: bool, // 10
-    // cpuid: bool, // 11
+    // cpuid: bool, // 11 No LLVM support
     asimdrdm: bool, // 12
-    // jscvt: bool, // 13
-    // fcma: bool, // 14
-    lrcpc: bool, // 15
-    // dcpop: bool, // 16
-    // sha3: bool, // 17
-    // sm3: bool, // 18
-    // sm4: bool, // 19
-    asimddp: bool, // 20
-    // sha512: bool, // 21
-    sve: bool, // 22
+    jscvt: bool,    // 13
+    fcma: bool,     // 14
+    lrcpc: bool,    // 15
+    dcpop: bool,    // 16
+    sha3: bool,     // 17
+    sm3: bool,      // 18
+    sm4: bool,      // 19
+    asimddp: bool,  // 20
+    sha512: bool,   // 21
+    sve: bool,      // 22
+    fhm: bool,      // 23
+    dit: bool,      // 24
+    uscat: bool,    // 25
+    ilrcpc: bool,   // 26
+    flagm: bool,    // 27
+    ssbs: bool,     // 28
+    sb: bool,       // 29
+    paca: bool,     // 30
+    pacg: bool,     // 31
+    dcpodp: bool,   // 32
+    sve2: bool,     // 33
+    sveaes: bool,   // 34
+    // svepmull: bool, // 35 No LLVM support
+    svebitperm: bool, // 36
+    svesha3: bool,    // 37
+    svesm4: bool,     // 38
+    // flagm2: bool, // 39 No LLVM support
+    frint: bool, // 40
+    // svei8mm: bool, // 41 See i8mm feature
+    svef32mm: bool, // 42
+    svef64mm: bool, // 43
+    // svebf16: bool, // 44 See bf16 feature
+    i8mm: bool, // 45
+    bf16: bool, // 46
+    // dgh: bool, // 47 No LLVM support
+    rng: bool, // 48
+    bti: bool, // 49
+    mte: bool, // 50
 }
 
 impl From<auxvec::AuxVec> for AtHwcap {
@@ -64,16 +94,44 @@ impl From<auxvec::AuxVec> for AtHwcap {
             asimdhp: bit::test(auxv.hwcap, 10),
             // cpuid: bit::test(auxv.hwcap, 11),
             asimdrdm: bit::test(auxv.hwcap, 12),
-            // jscvt: bit::test(auxv.hwcap, 13),
-            // fcma: bit::test(auxv.hwcap, 14),
+            jscvt: bit::test(auxv.hwcap, 13),
+            fcma: bit::test(auxv.hwcap, 14),
             lrcpc: bit::test(auxv.hwcap, 15),
-            // dcpop: bit::test(auxv.hwcap, 16),
-            // sha3: bit::test(auxv.hwcap, 17),
-            // sm3: bit::test(auxv.hwcap, 18),
-            // sm4: bit::test(auxv.hwcap, 19),
+            dcpop: bit::test(auxv.hwcap, 16),
+            sha3: bit::test(auxv.hwcap, 17),
+            sm3: bit::test(auxv.hwcap, 18),
+            sm4: bit::test(auxv.hwcap, 19),
             asimddp: bit::test(auxv.hwcap, 20),
-            // sha512: bit::test(auxv.hwcap, 21),
+            sha512: bit::test(auxv.hwcap, 21),
             sve: bit::test(auxv.hwcap, 22),
+            fhm: bit::test(auxv.hwcap, 23),
+            dit: bit::test(auxv.hwcap, 24),
+            uscat: bit::test(auxv.hwcap, 25),
+            ilrcpc: bit::test(auxv.hwcap, 26),
+            flagm: bit::test(auxv.hwcap, 27),
+            ssbs: bit::test(auxv.hwcap, 28),
+            sb: bit::test(auxv.hwcap, 29),
+            paca: bit::test(auxv.hwcap, 30),
+            pacg: bit::test(auxv.hwcap, 31),
+            dcpodp: bit::test(auxv.hwcap, 32),
+            sve2: bit::test(auxv.hwcap, 33),
+            sveaes: bit::test(auxv.hwcap, 34),
+            // svepmull: bit::test(auxv.hwcap, 35),
+            svebitperm: bit::test(auxv.hwcap, 36),
+            svesha3: bit::test(auxv.hwcap, 37),
+            svesm4: bit::test(auxv.hwcap, 38),
+            // flagm2: bit::test(auxv.hwcap, 39),
+            frint: bit::test(auxv.hwcap, 40),
+            // svei8mm: bit::test(auxv.hwcap, 41),
+            svef32mm: bit::test(auxv.hwcap, 42),
+            svef64mm: bit::test(auxv.hwcap, 43),
+            // svebf16: bit::test(auxv.hwcap, 44),
+            i8mm: bit::test(auxv.hwcap, 45),
+            bf16: bit::test(auxv.hwcap, 46),
+            // dgh: bit::test(auxv.hwcap, 47),
+            rng: bit::test(auxv.hwcap, 48),
+            bti: bit::test(auxv.hwcap, 49),
+            mte: bit::test(auxv.hwcap, 50),
         }
     }
 }
@@ -100,16 +158,44 @@ impl From<super::cpuinfo::CpuInfo> for AtHwcap {
             asimdhp: f.has("asimdhp"),
             // cpuid: f.has("cpuid"),
             asimdrdm: f.has("asimdrdm"),
-            // jscvt: f.has("jscvt"),
-            // fcma: f.has("fcma"),
+            jscvt: f.has("jscvt"),
+            fcma: f.has("fcma"),
             lrcpc: f.has("lrcpc"),
-            // dcpop: f.has("dcpop"),
-            // sha3: f.has("sha3"),
-            // sm3: f.has("sm3"),
-            // sm4: f.has("sm4"),
+            dcpop: f.has("dcpop"),
+            sha3: f.has("sha3"),
+            sm3: f.has("sm3"),
+            sm4: f.has("sm4"),
             asimddp: f.has("asimddp"),
-            // sha512: f.has("sha512"),
+            sha512: f.has("sha512"),
             sve: f.has("sve"),
+            fhm: f.has("asimdfhm"),
+            dit: f.has("dit"),
+            uscat: f.has("uscat"),
+            ilrcpc: f.has("ilrcpc"),
+            flagm: f.has("flagm"),
+            ssbs: f.has("ssbs"),
+            sb: f.has("sb"),
+            paca: f.has("paca"),
+            pacg: f.has("pacg"),
+            dcpodp: f.has("dcpodp"),
+            sve2: f.has("sve2"),
+            sveaes: f.has("sveaes"),
+            // svepmull: f.has("svepmull"),
+            svebitperm: f.has("svebitperm"),
+            svesha3: f.has("svesha3"),
+            svesm4: f.has("svesm4"),
+            // flagm2: f.has("flagm2"),
+            frint: f.has("frint"),
+            // svei8mm: f.has("svei8mm"),
+            svef32mm: f.has("svef32mm"),
+            svef64mm: f.has("svef64mm"),
+            // svebf16: f.has("svebf16"),
+            i8mm: f.has("i8mm"),
+            bf16: f.has("bf16"),
+            // dgh: f.has("dgh"),
+            rng: f.has("rng"),
+            bti: f.has("bti"),
+            mte: f.has("mte"),
         }
     }
 }
@@ -117,8 +203,8 @@ impl From<super::cpuinfo::CpuInfo> for AtHwcap {
 impl AtHwcap {
     /// Initializes the cache from the feature -bits.
     ///
-    /// The features are enabled approximately like in LLVM host feature detection:
-    /// https://github.com/llvm-mirror/llvm/blob/master/lib/Support/Host.cpp#L1273
+    /// The feature dependencies here come directly from LLVM's feature definintions:
+    /// https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/AArch64/AArch64.td
     fn cache(self) -> cache::Initializer {
         let mut value = cache::Initializer::default();
         {
@@ -131,25 +217,73 @@ impl AtHwcap {
             enable_feature(Feature::fp, self.fp);
             // Half-float support requires float support
             enable_feature(Feature::fp16, self.fp && self.fphp);
+            // FHM (fp16fml in LLVM) requires half float support
+            enable_feature(Feature::fhm, self.fphp && self.fhm);
             enable_feature(Feature::pmull, self.pmull);
             enable_feature(Feature::crc, self.crc32);
             enable_feature(Feature::lse, self.atomics);
+            enable_feature(Feature::lse2, self.uscat);
             enable_feature(Feature::rcpc, self.lrcpc);
+            // RCPC2 (rcpc-immo in LLVM) requires RCPC support
+            enable_feature(Feature::rcpc2, self.ilrcpc && self.lrcpc);
+            enable_feature(Feature::dit, self.dit);
+            enable_feature(Feature::flagm, self.flagm);
+            enable_feature(Feature::ssbs, self.ssbs);
+            enable_feature(Feature::sb, self.sb);
+            // FEAT_PAuth provides both paca & pacg
+            enable_feature(Feature::pauth, self.paca && self.pacg);
+            enable_feature(Feature::dpb, self.dcpop);
+            enable_feature(Feature::dpb2, self.dcpodp);
+            enable_feature(Feature::rand, self.rng);
+            enable_feature(Feature::bti, self.bti);
+            enable_feature(Feature::mte, self.mte);
+            // jsconv requires float support
+            enable_feature(Feature::jsconv, self.jscvt && self.fp);
+            enable_feature(Feature::rdm, self.asimdrdm);
+            enable_feature(Feature::dotprod, self.asimddp);
+            enable_feature(Feature::frintts, self.frint);
+
+            // FEAT_I8MM & FEAT_BF16 also include optional SVE components which linux exposes
+            // separately. We ignore that distinction here.
+            enable_feature(Feature::i8mm, self.i8mm);
+            enable_feature(Feature::bf16, self.bf16);
 
-            // SIMD support requires float support - if half-floats are
+            // ASIMD support requires float support - if half-floats are
             // supported, it also requires half-float support:
             let asimd = self.fp && self.asimd && (!self.fphp | self.asimdhp);
             enable_feature(Feature::asimd, asimd);
-            // SIMD extensions require SIMD support:
-            enable_feature(Feature::rdm, self.asimdrdm && asimd);
-            enable_feature(Feature::dotprod, self.asimddp && asimd);
+            // ASIMD extensions require ASIMD support:
+            enable_feature(Feature::fcma, self.fcma && asimd);
             enable_feature(Feature::sve, self.sve && asimd);
 
-            // Crypto is specified as AES + PMULL + SHA1 + SHA2 per LLVM/hosts.cpp
+            // SVE extensions require SVE & ASIMD
+            enable_feature(Feature::f32mm, self.svef32mm && self.sve && asimd);
+            enable_feature(Feature::f64mm, self.svef64mm && self.sve && asimd);
+
+            // Cryptographic extensions require ASIMD
+            enable_feature(Feature::aes, self.aes && asimd);
+            enable_feature(Feature::sha2, self.sha1 && self.sha2 && asimd);
+            // SHA512/SHA3 require SHA1 & SHA256
+            enable_feature(
+                Feature::sha3,
+                self.sha512 && self.sha3 && self.sha1 && self.sha2 && asimd,
+            );
+            enable_feature(Feature::sm4, self.sm3 && self.sm4 && asimd);
+
+            // SVE2 requires SVE
+            let sve2 = self.sve2 && self.sve && asimd;
+            enable_feature(Feature::sve2, sve2);
+            // SVE2 extensions require SVE2 and crypto features
+            enable_feature(Feature::sve2_aes, self.sveaes && sve2 && self.aes);
+            enable_feature(
+                Feature::sve2_sm4,
+                self.svesm4 && sve2 && self.sm3 && self.sm4,
+            );
             enable_feature(
-                Feature::crypto,
-                self.aes && self.pmull && self.sha1 && self.sha2,
+                Feature::sve2_sha3,
+                self.svesha3 && sve2 && self.sha512 && self.sha3 && self.sha1 && self.sha2,
             );
+            enable_feature(Feature::sve2_bitperm, self.svebitperm && self.sve2);
         }
         value
     }
diff --git a/library/stdarch/crates/std_detect/src/detect/os/linux/arm.rs b/library/stdarch/crates/std_detect/src/detect/os/linux/arm.rs
index 66cfd05e806..7383e487f1c 100644
--- a/library/stdarch/crates/std_detect/src/detect/os/linux/arm.rs
+++ b/library/stdarch/crates/std_detect/src/detect/os/linux/arm.rs
@@ -28,6 +28,13 @@ pub(crate) fn detect_features() -> cache::Initializer {
                 && bit::test(auxv.hwcap2, 2)
                 && bit::test(auxv.hwcap2, 3),
         );
+        enable_feature(&mut value, Feature::aes, bit::test(auxv.hwcap2, 0));
+        // SHA2 requires SHA1 & SHA2 features
+        enable_feature(
+            &mut value,
+            Feature::sha2,
+            bit::test(auxv.hwcap2, 2) && bit::test(auxv.hwcap2, 3),
+        );
         return value;
     }
 
@@ -48,6 +55,12 @@ pub(crate) fn detect_features() -> cache::Initializer {
                 && c.field("Features").has("sha1")
                 && c.field("Features").has("sha2"),
         );
+        enable_feature(&mut value, Feature::aes, c.field("Features").has("aes"));
+        enable_feature(
+            &mut value,
+            Feature::sha2,
+            c.field("Features").has("sha1") && c.field("Features").has("sha2"),
+        );
         return value;
     }
     value
diff --git a/library/stdarch/crates/std_detect/src/detect/os/windows/aarch64.rs b/library/stdarch/crates/std_detect/src/detect/os/windows/aarch64.rs
index 3c5edfb44ab..051ad6d1bfc 100644
--- a/library/stdarch/crates/std_detect/src/detect/os/windows/aarch64.rs
+++ b/library/stdarch/crates/std_detect/src/detect/os/windows/aarch64.rs
@@ -42,13 +42,17 @@ pub(crate) fn detect_features() -> cache::Initializer {
             // PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE means aes, sha1, sha2 and
             // pmull support
             enable_feature(
-                Feature::crypto,
+                Feature::aes,
                 IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != FALSE,
             );
             enable_feature(
                 Feature::pmull,
                 IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != FALSE,
             );
+            enable_feature(
+                Feature::sha2,
+                IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != FALSE,
+            );
         }
     }
     value
diff --git a/library/stdarch/crates/std_detect/tests/cpu-detection.rs b/library/stdarch/crates/std_detect/tests/cpu-detection.rs
index 8f29ea45cde..adbe4fa9a77 100644
--- a/library/stdarch/crates/std_detect/tests/cpu-detection.rs
+++ b/library/stdarch/crates/std_detect/tests/cpu-detection.rs
@@ -26,6 +26,8 @@ fn arm_linux() {
     println!("pmull: {}", is_arm_feature_detected!("pmull"));
     println!("crc: {}", is_arm_feature_detected!("crc"));
     println!("crypto: {}", is_arm_feature_detected!("crypto"));
+    println!("aes: {}", is_arm_feature_detected!("aes"));
+    println!("sha2: {}", is_arm_feature_detected!("sha2"));
 }
 
 #[test]
@@ -34,18 +36,50 @@ fn arm_linux() {
     any(target_os = "linux", target_os = "android")
 ))]
 fn aarch64_linux() {
+    println!("asimd: {}", is_aarch64_feature_detected!("asimd"));
+    println!("neon: {}", is_aarch64_feature_detected!("neon"));
+    println!("pmull: {}", is_aarch64_feature_detected!("pmull"));
     println!("fp: {}", is_aarch64_feature_detected!("fp"));
     println!("fp16: {}", is_aarch64_feature_detected!("fp16"));
-    println!("neon: {}", is_aarch64_feature_detected!("neon"));
-    println!("asimd: {}", is_aarch64_feature_detected!("asimd"));
     println!("sve: {}", is_aarch64_feature_detected!("sve"));
     println!("crc: {}", is_aarch64_feature_detected!("crc"));
-    println!("crypto: {}", is_aarch64_feature_detected!("crypto"));
     println!("lse: {}", is_aarch64_feature_detected!("lse"));
+    println!("lse2: {}", is_aarch64_feature_detected!("lse2"));
     println!("rdm: {}", is_aarch64_feature_detected!("rdm"));
     println!("rcpc: {}", is_aarch64_feature_detected!("rcpc"));
+    println!("rcpc2: {}", is_aarch64_feature_detected!("rcpc2"));
     println!("dotprod: {}", is_aarch64_feature_detected!("dotprod"));
     println!("tme: {}", is_aarch64_feature_detected!("tme"));
+    println!("fhm: {}", is_aarch64_feature_detected!("fhm"));
+    println!("dit: {}", is_aarch64_feature_detected!("dit"));
+    println!("flagm: {}", is_aarch64_feature_detected!("flagm"));
+    println!("ssbs: {}", is_aarch64_feature_detected!("ssbs"));
+    println!("sb: {}", is_aarch64_feature_detected!("sb"));
+    println!("pauth: {}", is_aarch64_feature_detected!("pauth"));
+    println!("dpb: {}", is_aarch64_feature_detected!("dpb"));
+    println!("dpb2: {}", is_aarch64_feature_detected!("dpb2"));
+    println!("sve2: {}", is_aarch64_feature_detected!("sve2"));
+    println!("sve2-aes: {}", is_aarch64_feature_detected!("sve2-aes"));
+    println!("sve2-sm4: {}", is_aarch64_feature_detected!("sve2-sm4"));
+    println!("sve2-sha3: {}", is_aarch64_feature_detected!("sve2-sha3"));
+    println!(
+        "sve2-bitperm: {}",
+        is_aarch64_feature_detected!("sve2-bitperm")
+    );
+    println!("frintts: {}", is_aarch64_feature_detected!("frintts"));
+    println!("i8mm: {}", is_aarch64_feature_detected!("i8mm"));
+    println!("f32mm: {}", is_aarch64_feature_detected!("f32mm"));
+    println!("f64mm: {}", is_aarch64_feature_detected!("f64mm"));
+    println!("bf16: {}", is_aarch64_feature_detected!("bf16"));
+    println!("rand: {}", is_aarch64_feature_detected!("rand"));
+    println!("bti: {}", is_aarch64_feature_detected!("bti"));
+    println!("mte: {}", is_aarch64_feature_detected!("mte"));
+    println!("jsconv: {}", is_aarch64_feature_detected!("jsconv"));
+    println!("fcma: {}", is_aarch64_feature_detected!("fcma"));
+    println!("aes: {}", is_aarch64_feature_detected!("aes"));
+    println!("sha2: {}", is_aarch64_feature_detected!("sha2"));
+    println!("sha3: {}", is_aarch64_feature_detected!("sha3"));
+    println!("sm4: {}", is_aarch64_feature_detected!("sm4"));
 }
 
 #[test]