From b6f50eeab58f5c493e281130447669470bfb1b1b Mon Sep 17 00:00:00 2001
From: Adam Gemmell <adam.gemmell@arm.com>
Date: Wed, 28 Apr 2021 17:20:51 +0100
Subject: [PATCH 1/9] Update aarch64 linux feature detection

This commit doesn't add support for features not available in LLVM 12
---
 crates/std_detect/src/detect/arch/aarch64.rs  | 136 ++++++++++-
 crates/std_detect/src/detect/bit.rs           |   2 +-
 .../std_detect/src/detect/os/linux/aarch64.rs | 224 ++++++++++++++----
 crates/std_detect/tests/cpu-detection.rs      |  33 ++-
 4 files changed, 332 insertions(+), 63 deletions(-)

diff --git a/crates/std_detect/src/detect/arch/aarch64.rs b/crates/std_detect/src/detect/arch/aarch64.rs
index 761cde9583..d1fb08dcc1 100644
--- a/crates/std_detect/src/detect/arch/aarch64.rs
+++ b/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
+    /// * `"crypto"` - Cryptographic Extension (AES + PMULL + SHA1 + SHA2-256)
+    /// * `"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
+    /// * `"fptoint"` - 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
+    /// * `"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)
+    /// FEAT_CRC32 (Cyclic Redundancy Check)
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] crypto: "crypto";
-    /// Crypto: AES + PMULL + SHA1 + SHA2
+    /// Cryptographic Extension (AES + PMULL + SHA1 + SHA2-256)
     @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")] fptoint: "fptoint";
+    /// 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")] 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/crates/std_detect/src/detect/bit.rs b/crates/std_detect/src/detect/bit.rs
index 578f0b16b7..6f06c5523e 100644
--- a/crates/std_detect/src/detect/bit.rs
+++ b/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/crates/std_detect/src/detect/os/linux/aarch64.rs b/crates/std_detect/src/detect/os/linux/aarch64.rs
index 80c36e9b99..c4281156e4 100644
--- a/crates/std_detect/src/detect/os/linux/aarch64.rs
+++ b/crates/std_detect/src/detect/os/linux/aarch64.rs
@@ -20,31 +20,61 @@ 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
-    aes: bool,     // 3
-    pmull: bool,   // 4
-    sha1: bool,    // 5
-    sha2: bool,    // 6
-    crc32: bool,   // 7
-    atomics: bool, // 8
-    fphp: bool,    // 9
-    asimdhp: bool, // 10
-    // cpuid: bool, // 11
-    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
+    fp: bool,         // 0
+    asimd: bool,      // 1
+//  evtstrm: bool,    // 2 No LLVM support
+    aes: bool,        // 3
+    pmull: bool,      // 4
+    sha1: bool,       // 5
+    sha2: bool,       // 6
+    crc32: bool,      // 7
+    atomics: bool,    // 8
+    fphp: bool,       // 9
+    asimdhp: bool,    // 10
+//  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
+    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 {
@@ -53,7 +83,7 @@ impl From<auxvec::AuxVec> for AtHwcap {
         AtHwcap {
             fp: bit::test(auxv.hwcap, 0),
             asimd: bit::test(auxv.hwcap, 1),
-            // evtstrm: bit::test(auxv.hwcap, 2),
+//          evtstrm: bit::test(auxv.hwcap, 2),
             aes: bit::test(auxv.hwcap, 3),
             pmull: bit::test(auxv.hwcap, 4),
             sha1: bit::test(auxv.hwcap, 5),
@@ -62,18 +92,46 @@ impl From<auxvec::AuxVec> for AtHwcap {
             atomics: bit::test(auxv.hwcap, 8),
             fphp: bit::test(auxv.hwcap, 9),
             asimdhp: bit::test(auxv.hwcap, 10),
-            // cpuid: bit::test(auxv.hwcap, 11),
+//          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),
         }
     }
 }
@@ -89,7 +147,7 @@ impl From<super::cpuinfo::CpuInfo> for AtHwcap {
             // cover that yet.
             fp: f.has("fp"),
             asimd: f.has("asimd"),
-            // evtstrm: f.has("evtstrm"),
+//          evtstrm: f.has("evtstrm"),
             aes: f.has("aes"),
             pmull: f.has("pmull"),
             sha1: f.has("sha1"),
@@ -98,18 +156,46 @@ impl From<super::cpuinfo::CpuInfo> for AtHwcap {
             atomics: f.has("atomics"),
             fphp: f.has("fphp"),
             asimdhp: f.has("asimdhp"),
-            // cpuid: f.has("cpuid"),
+//          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,20 +217,64 @@ 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::fptoint, 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);
 
+            // 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::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::sve2_sha3, self.svesha3 && sve2 && self.sha512 && self.sha3 && self.sha1 && self.sha2);
+            enable_feature(Feature::sve2_bitperm, self.svebitperm && self.sve2);
+
             // Crypto is specified as AES + PMULL + SHA1 + SHA2 per LLVM/hosts.cpp
             enable_feature(
                 Feature::crypto,
diff --git a/crates/std_detect/tests/cpu-detection.rs b/crates/std_detect/tests/cpu-detection.rs
index 8f29ea45cd..8091d5ee6f 100644
--- a/crates/std_detect/tests/cpu-detection.rs
+++ b/crates/std_detect/tests/cpu-detection.rs
@@ -34,18 +34,47 @@ 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!("fptoint: {}", is_aarch64_feature_detected!("fptoint"));
+    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!("sha2: {}", is_aarch64_feature_detected!("sha2"));
+    println!("sha3: {}", is_aarch64_feature_detected!("sha3"));
+    println!("sm4: {}", is_aarch64_feature_detected!("sm4"));
 }
 
 #[test]

From f3f16466f68d52f38e3cd47fd49403650317f571 Mon Sep 17 00:00:00 2001
From: Adam Gemmell <adam.gemmell@arm.com>
Date: Wed, 19 May 2021 15:25:51 +0100
Subject: [PATCH 2/9] Rename fptoint to frintts

---
 crates/std_detect/src/detect/arch/aarch64.rs     | 4 ++--
 crates/std_detect/src/detect/os/linux/aarch64.rs | 2 +-
 crates/std_detect/tests/cpu-detection.rs         | 7 ++++---
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/crates/std_detect/src/detect/arch/aarch64.rs b/crates/std_detect/src/detect/arch/aarch64.rs
index d1fb08dcc1..4150b053e8 100644
--- a/crates/std_detect/src/detect/arch/aarch64.rs
+++ b/crates/std_detect/src/detect/arch/aarch64.rs
@@ -40,7 +40,7 @@ features! {
     /// * `"sve2-sm4"` - FEAT_SVE2_SM4
     /// * `"sve2-sha3"` - FEAT_SVE2_SHA3
     /// * `"sve2-bitperm"` - FEAT_SVE2_BitPerm
-    /// * `"fptoint"` - FEAT_FRINTTS
+    /// * `"frintts"` - FEAT_FRINTTS
     /// * `"i8mm"` - FEAT_I8MM
     /// * `"f32mm"` - FEAT_F32MM
     /// * `"f64mm"` - FEAT_F64MM
@@ -119,7 +119,7 @@ features! {
     /// 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")] fptoint: "fptoint";
+    @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)
diff --git a/crates/std_detect/src/detect/os/linux/aarch64.rs b/crates/std_detect/src/detect/os/linux/aarch64.rs
index c4281156e4..b89dac205c 100644
--- a/crates/std_detect/src/detect/os/linux/aarch64.rs
+++ b/crates/std_detect/src/detect/os/linux/aarch64.rs
@@ -241,7 +241,7 @@ impl AtHwcap {
             enable_feature(Feature::jsconv, self.jscvt && self.fp);
             enable_feature(Feature::rdm, self.asimdrdm);
             enable_feature(Feature::dotprod, self.asimddp);
-            enable_feature(Feature::fptoint, self.frint);
+            enable_feature(Feature::frintts, self.frint);
 
             // FEAT_I8MM & FEAT_BF16 also include optional SVE components which linux exposes
             // separately. We ignore that distinction here.
diff --git a/crates/std_detect/tests/cpu-detection.rs b/crates/std_detect/tests/cpu-detection.rs
index 8091d5ee6f..935e409fc4 100644
--- a/crates/std_detect/tests/cpu-detection.rs
+++ b/crates/std_detect/tests/cpu-detection.rs
@@ -25,7 +25,8 @@ fn arm_linux() {
     println!("neon: {}", is_arm_feature_detected!("neon"));
     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]
@@ -41,7 +42,6 @@ fn aarch64_linux() {
     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!("lse2: {}", is_aarch64_feature_detected!("lse2"));
     println!("rdm: {}", is_aarch64_feature_detected!("rdm"));
@@ -62,7 +62,7 @@ fn aarch64_linux() {
     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!("fptoint: {}", is_aarch64_feature_detected!("fptoint"));
+    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"));
@@ -72,6 +72,7 @@ fn aarch64_linux() {
     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"));

From e62f4e8aa7b097a41bc8e09e214223e79f9b631f Mon Sep 17 00:00:00 2001
From: Adam Gemmell <adam.gemmell@arm.com>
Date: Wed, 19 May 2021 15:27:58 +0100
Subject: [PATCH 3/9] Remove crypto feature. Add AES/SHA2 features to all
 arm/aarch64 platforms.

---
 crates/std_detect/src/detect/arch/aarch64.rs  |  6 +++---
 crates/std_detect/src/detect/arch/arm.rs      |  6 ++++--
 crates/std_detect/src/detect/os/aarch64.rs    | 12 +++++------
 .../std_detect/src/detect/os/linux/aarch64.rs |  7 +------
 crates/std_detect/src/detect/os/linux/arm.rs  | 21 +++++--------------
 .../src/detect/os/windows/aarch64.rs          |  6 +++++-
 6 files changed, 23 insertions(+), 35 deletions(-)

diff --git a/crates/std_detect/src/detect/arch/aarch64.rs b/crates/std_detect/src/detect/arch/aarch64.rs
index 4150b053e8..81979ba967 100644
--- a/crates/std_detect/src/detect/arch/aarch64.rs
+++ b/crates/std_detect/src/detect/arch/aarch64.rs
@@ -19,7 +19,6 @@ features! {
     /// * `"fp16"` - FEAT_FP16
     /// * `"sve"` - FEAT_SVE
     /// * `"crc"` - FEAT_CRC
-    /// * `"crypto"` - Cryptographic Extension (AES + PMULL + SHA1 + SHA2-256)
     /// * `"lse"` - FEAT_LSE
     /// * `"lse2"` - FEAT_LSE2
     /// * `"rdm"` - FEAT_RDM
@@ -50,6 +49,7 @@ features! {
     /// * `"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
@@ -77,8 +77,6 @@ features! {
     /// FEAT_SVE (Scalable Vector Extension)
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] crc: "crc";
     /// FEAT_CRC32 (Cyclic Redundancy Check)
-    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] crypto: "crypto";
-    /// Cryptographic Extension (AES + PMULL + SHA1 + SHA2-256)
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] lse: "lse";
     /// FEAT_LSE (Large System Extension - atomics)
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] lse2: "lse2";
@@ -139,6 +137,8 @@ features! {
     /// 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";
diff --git a/crates/std_detect/src/detect/arch/arm.rs b/crates/std_detect/src/detect/arch/arm.rs
index 46fd56384b..dea7ff75b4 100644
--- a/crates/std_detect/src/detect/arch/arm.rs
+++ b/crates/std_detect/src/detect/arch/arm.rs
@@ -16,6 +16,8 @@ features! {
     /// Polynomial Multiply
     @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
+    @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/crates/std_detect/src/detect/os/aarch64.rs b/crates/std_detect/src/detect/os/aarch64.rs
index 2f289f5807..0fd2702731 100644
--- a/crates/std_detect/src/detect/os/aarch64.rs
+++ b/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/crates/std_detect/src/detect/os/linux/aarch64.rs b/crates/std_detect/src/detect/os/linux/aarch64.rs
index b89dac205c..52936554cc 100644
--- a/crates/std_detect/src/detect/os/linux/aarch64.rs
+++ b/crates/std_detect/src/detect/os/linux/aarch64.rs
@@ -261,6 +261,7 @@ impl AtHwcap {
             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);
@@ -274,12 +275,6 @@ impl AtHwcap {
             enable_feature(Feature::sve2_sm4, self.svesm4 && sve2 && self.sm3 && self.sm4);
             enable_feature(Feature::sve2_sha3, self.svesha3 && sve2 && self.sha512 && self.sha3 && self.sha1 && self.sha2);
             enable_feature(Feature::sve2_bitperm, self.svebitperm && self.sve2);
-
-            // Crypto is specified as AES + PMULL + SHA1 + SHA2 per LLVM/hosts.cpp
-            enable_feature(
-                Feature::crypto,
-                self.aes && self.pmull && self.sha1 && self.sha2,
-            );
         }
         value
     }
diff --git a/crates/std_detect/src/detect/os/linux/arm.rs b/crates/std_detect/src/detect/os/linux/arm.rs
index 66cfd05e80..4a748b61f9 100644
--- a/crates/std_detect/src/detect/os/linux/arm.rs
+++ b/crates/std_detect/src/detect/os/linux/arm.rs
@@ -20,14 +20,9 @@ pub(crate) fn detect_features() -> cache::Initializer {
         enable_feature(&mut value, Feature::neon, bit::test(auxv.hwcap, 12));
         enable_feature(&mut value, Feature::pmull, bit::test(auxv.hwcap2, 1));
         enable_feature(&mut value, Feature::crc, bit::test(auxv.hwcap2, 4));
-        enable_feature(
-            &mut value,
-            Feature::crypto,
-            bit::test(auxv.hwcap2, 0)
-                && bit::test(auxv.hwcap2, 1)
-                && 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;
     }
 
@@ -40,14 +35,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
         );
         enable_feature(&mut value, Feature::pmull, c.field("Features").has("pmull"));
         enable_feature(&mut value, Feature::crc, c.field("Features").has("crc32"));
-        enable_feature(
-            &mut value,
-            Feature::crypto,
-            c.field("Features").has("aes")
-                && c.field("Features").has("pmull")
-                && 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/crates/std_detect/src/detect/os/windows/aarch64.rs b/crates/std_detect/src/detect/os/windows/aarch64.rs
index 3c5edfb44a..051ad6d1bf 100644
--- a/crates/std_detect/src/detect/os/windows/aarch64.rs
+++ b/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

From 0958d8e65910022e8eaf85cde852b8950afcd6ad Mon Sep 17 00:00:00 2001
From: Adam Gemmell <adam.gemmell@arm.com>
Date: Wed, 19 May 2021 15:31:20 +0100
Subject: [PATCH 4/9] Update core_arch tests for removal of crypto feature in
 rustc

---
 crates/core_arch/src/arm_shared/crypto.rs | 81 +++++++++++++++--------
 1 file changed, 54 insertions(+), 27 deletions(-)

diff --git a/crates/core_arch/src/arm_shared/crypto.rs b/crates/core_arch/src/arm_shared/crypto.rs
index b4d5b2978f..50492360e8 100644
--- a/crates/core_arch/src/arm_shared/crypto.rs
+++ b/crates/core_arch/src/arm_shared/crypto.rs
@@ -53,7 +53,8 @@ use stdarch_test::assert_instr;
 
 /// AES single round encryption.
 #[inline]
-#[target_feature(enable = "crypto")]
+#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
+#[cfg_attr(not(bootstrap), target_feature(enable = "aes"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(aese))]
 pub unsafe fn vaeseq_u8(data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
@@ -62,7 +63,8 @@ pub unsafe fn vaeseq_u8(data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
 
 /// AES single round decryption.
 #[inline]
-#[target_feature(enable = "crypto")]
+#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
+#[cfg_attr(not(bootstrap), target_feature(enable = "aes"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(aesd))]
 pub unsafe fn vaesdq_u8(data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
@@ -71,7 +73,8 @@ pub unsafe fn vaesdq_u8(data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
 
 /// AES mix columns.
 #[inline]
-#[target_feature(enable = "crypto")]
+#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
+#[cfg_attr(not(bootstrap), target_feature(enable = "aes"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(aesmc))]
 pub unsafe fn vaesmcq_u8(data: uint8x16_t) -> uint8x16_t {
@@ -80,7 +83,8 @@ pub unsafe fn vaesmcq_u8(data: uint8x16_t) -> uint8x16_t {
 
 /// AES inverse mix columns.
 #[inline]
-#[target_feature(enable = "crypto")]
+#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
+#[cfg_attr(not(bootstrap), target_feature(enable = "aes"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(aesimc))]
 pub unsafe fn vaesimcq_u8(data: uint8x16_t) -> uint8x16_t {
@@ -89,7 +93,8 @@ pub unsafe fn vaesimcq_u8(data: uint8x16_t) -> uint8x16_t {
 
 /// SHA1 fixed rotate.
 #[inline]
-#[target_feature(enable = "crypto")]
+#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
+#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1h))]
 pub unsafe fn vsha1h_u32(hash_e: u32) -> u32 {
@@ -98,7 +103,8 @@ pub unsafe fn vsha1h_u32(hash_e: u32) -> u32 {
 
 /// SHA1 hash update accelerator, choose.
 #[inline]
-#[target_feature(enable = "crypto")]
+#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
+#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1c))]
 pub unsafe fn vsha1cq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) -> uint32x4_t {
@@ -107,7 +113,8 @@ pub unsafe fn vsha1cq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) ->
 
 /// SHA1 hash update accelerator, majority.
 #[inline]
-#[target_feature(enable = "crypto")]
+#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
+#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1m))]
 pub unsafe fn vsha1mq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) -> uint32x4_t {
@@ -116,7 +123,8 @@ pub unsafe fn vsha1mq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) ->
 
 /// SHA1 hash update accelerator, parity.
 #[inline]
-#[target_feature(enable = "crypto")]
+#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
+#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1p))]
 pub unsafe fn vsha1pq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) -> uint32x4_t {
@@ -125,7 +133,8 @@ pub unsafe fn vsha1pq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) ->
 
 /// SHA1 schedule update accelerator, first part.
 #[inline]
-#[target_feature(enable = "crypto")]
+#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
+#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1su0))]
 pub unsafe fn vsha1su0q_u32(w0_3: uint32x4_t, w4_7: uint32x4_t, w8_11: uint32x4_t) -> uint32x4_t {
@@ -134,7 +143,8 @@ pub unsafe fn vsha1su0q_u32(w0_3: uint32x4_t, w4_7: uint32x4_t, w8_11: uint32x4_
 
 /// SHA1 schedule update accelerator, second part.
 #[inline]
-#[target_feature(enable = "crypto")]
+#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
+#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1su1))]
 pub unsafe fn vsha1su1q_u32(tw0_3: uint32x4_t, w12_15: uint32x4_t) -> uint32x4_t {
@@ -143,7 +153,8 @@ pub unsafe fn vsha1su1q_u32(tw0_3: uint32x4_t, w12_15: uint32x4_t) -> uint32x4_t
 
 /// SHA256 hash update accelerator.
 #[inline]
-#[target_feature(enable = "crypto")]
+#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
+#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha256h))]
 pub unsafe fn vsha256hq_u32(
@@ -156,7 +167,8 @@ pub unsafe fn vsha256hq_u32(
 
 /// SHA256 hash update accelerator, upper part.
 #[inline]
-#[target_feature(enable = "crypto")]
+#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
+#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha256h2))]
 pub unsafe fn vsha256h2q_u32(
@@ -169,7 +181,8 @@ pub unsafe fn vsha256h2q_u32(
 
 /// SHA256 schedule update accelerator, first part.
 #[inline]
-#[target_feature(enable = "crypto")]
+#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
+#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha256su0))]
 pub unsafe fn vsha256su0q_u32(w0_3: uint32x4_t, w4_7: uint32x4_t) -> uint32x4_t {
@@ -178,7 +191,8 @@ pub unsafe fn vsha256su0q_u32(w0_3: uint32x4_t, w4_7: uint32x4_t) -> uint32x4_t
 
 /// SHA256 schedule update accelerator, second part.
 #[inline]
-#[target_feature(enable = "crypto")]
+#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
+#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha256su1))]
 pub unsafe fn vsha256su1q_u32(
@@ -209,7 +223,8 @@ mod tests {
         );
     }
 
-    #[simd_test(enable = "crypto")]
+    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
+    #[cfg_attr(not(bootstrap), simd_test(enable = "aes"))]
     unsafe fn test_vaesdq_u8() {
         let data = mem::transmute(u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8));
         let key = mem::transmute(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7));
@@ -220,7 +235,8 @@ mod tests {
         );
     }
 
-    #[simd_test(enable = "crypto")]
+    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
+    #[cfg_attr(not(bootstrap), simd_test(enable = "aes"))]
     unsafe fn test_vaesmcq_u8() {
         let data = mem::transmute(u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8));
         let r: u8x16 = mem::transmute(vaesmcq_u8(data));
@@ -230,7 +246,8 @@ mod tests {
         );
     }
 
-    #[simd_test(enable = "crypto")]
+    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
+    #[cfg_attr(not(bootstrap), simd_test(enable = "aes"))]
     unsafe fn test_vaesimcq_u8() {
         let data = mem::transmute(u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8));
         let r: u8x16 = mem::transmute(vaesimcq_u8(data));
@@ -240,13 +257,15 @@ mod tests {
         );
     }
 
-    #[simd_test(enable = "crypto")]
+    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
+    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
     unsafe fn test_vsha1h_u32() {
         assert_eq!(vsha1h_u32(0x1234), 0x048d);
         assert_eq!(vsha1h_u32(0x5678), 0x159e);
     }
 
-    #[simd_test(enable = "crypto")]
+    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
+    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
     unsafe fn test_vsha1su0q_u32() {
         let r: u32x4 = mem::transmute(vsha1su0q_u32(
             mem::transmute(u32x4::new(0x1234_u32, 0x5678_u32, 0x9abc_u32, 0xdef0_u32)),
@@ -256,7 +275,8 @@ mod tests {
         assert_eq!(r, u32x4::new(0x9abc, 0xdef0, 0x1234, 0x5678));
     }
 
-    #[simd_test(enable = "crypto")]
+    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
+    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
     unsafe fn test_vsha1su1q_u32() {
         let r: u32x4 = mem::transmute(vsha1su1q_u32(
             mem::transmute(u32x4::new(0x1234, 0x5678, 0x9abc, 0xdef0)),
@@ -268,7 +288,8 @@ mod tests {
         );
     }
 
-    #[simd_test(enable = "crypto")]
+    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
+    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
     unsafe fn test_vsha1cq_u32() {
         let r: u32x4 = mem::transmute(vsha1cq_u32(
             mem::transmute(u32x4::new(0x1234, 0x5678, 0x9abc, 0xdef0)),
@@ -281,7 +302,8 @@ mod tests {
         );
     }
 
-    #[simd_test(enable = "crypto")]
+    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
+    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
     unsafe fn test_vsha1pq_u32() {
         let r: u32x4 = mem::transmute(vsha1pq_u32(
             mem::transmute(u32x4::new(0x1234, 0x5678, 0x9abc, 0xdef0)),
@@ -294,7 +316,8 @@ mod tests {
         );
     }
 
-    #[simd_test(enable = "crypto")]
+    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
+    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
     unsafe fn test_vsha1mq_u32() {
         let r: u32x4 = mem::transmute(vsha1mq_u32(
             mem::transmute(u32x4::new(0x1234, 0x5678, 0x9abc, 0xdef0)),
@@ -307,7 +330,8 @@ mod tests {
         );
     }
 
-    #[simd_test(enable = "crypto")]
+    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
+    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
     unsafe fn test_vsha256hq_u32() {
         let r: u32x4 = mem::transmute(vsha256hq_u32(
             mem::transmute(u32x4::new(0x1234, 0x5678, 0x9abc, 0xdef0)),
@@ -320,7 +344,8 @@ mod tests {
         );
     }
 
-    #[simd_test(enable = "crypto")]
+    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
+    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
     unsafe fn test_vsha256h2q_u32() {
         let r: u32x4 = mem::transmute(vsha256h2q_u32(
             mem::transmute(u32x4::new(0x1234, 0x5678, 0x9abc, 0xdef0)),
@@ -333,7 +358,8 @@ mod tests {
         );
     }
 
-    #[simd_test(enable = "crypto")]
+    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
+    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
     unsafe fn test_vsha256su0q_u32() {
         let r: u32x4 = mem::transmute(vsha256su0q_u32(
             mem::transmute(u32x4::new(0x1234, 0x5678, 0x9abc, 0xdef0)),
@@ -345,7 +371,8 @@ mod tests {
         );
     }
 
-    #[simd_test(enable = "crypto")]
+    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
+    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
     unsafe fn test_vsha256su1q_u32() {
         let r: u32x4 = mem::transmute(vsha256su1q_u32(
             mem::transmute(u32x4::new(0x1234, 0x5678, 0x9abc, 0xdef0)),

From 6a3b07bf6cb4e432f650c06de0afe52ace165a30 Mon Sep 17 00:00:00 2001
From: Adam Gemmell <adam.gemmell@arm.com>
Date: Wed, 19 May 2021 15:52:00 +0100
Subject: [PATCH 5/9] Fix aarch64 freebsd compilation

---
 crates/std_detect/src/detect/os/freebsd/aarch64.rs | 2 +-
 crates/std_detect/src/detect/os/freebsd/auxvec.rs  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/crates/std_detect/src/detect/os/freebsd/aarch64.rs b/crates/std_detect/src/detect/os/freebsd/aarch64.rs
index 7e086ca057..ed21252440 100644
--- a/crates/std_detect/src/detect/os/freebsd/aarch64.rs
+++ b/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 {
diff --git a/crates/std_detect/src/detect/os/freebsd/auxvec.rs b/crates/std_detect/src/detect/os/freebsd/auxvec.rs
index 832ce2252e..8b26dc35c5 100644
--- a/crates/std_detect/src/detect/os/freebsd/auxvec.rs
+++ b/crates/std_detect/src/detect/os/freebsd/auxvec.rs
@@ -1,5 +1,5 @@
 //! 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;

From cf5fb0923c54cc1e1999924a1d552331b501a423 Mon Sep 17 00:00:00 2001
From: Adam Gemmell <adam.gemmell@arm.com>
Date: Thu, 20 May 2021 12:16:58 +0100
Subject: [PATCH 6/9] Rustfmt style changes

---
 .../src/detect/os/freebsd/auxvec.rs           |   9 +-
 .../std_detect/src/detect/os/linux/aarch64.rs | 139 ++++++++++--------
 crates/std_detect/src/detect/os/linux/arm.rs  |  12 +-
 crates/std_detect/tests/cpu-detection.rs      |   5 +-
 4 files changed, 96 insertions(+), 69 deletions(-)

diff --git a/crates/std_detect/src/detect/os/freebsd/auxvec.rs b/crates/std_detect/src/detect/os/freebsd/auxvec.rs
index 8b26dc35c5..f12476adac 100644
--- a/crates/std_detect/src/detect/os/freebsd/auxvec.rs
+++ b/crates/std_detect/src/detect/os/freebsd/auxvec.rs
@@ -1,5 +1,12 @@
 //! Parses ELF auxiliary vectors.
-#![cfg_attr(any(target_arch = "aarch64", 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/crates/std_detect/src/detect/os/linux/aarch64.rs b/crates/std_detect/src/detect/os/linux/aarch64.rs
index 52936554cc..4dc6362057 100644
--- a/crates/std_detect/src/detect/os/linux/aarch64.rs
+++ b/crates/std_detect/src/detect/os/linux/aarch64.rs
@@ -24,57 +24,57 @@ pub(crate) fn detect_features() -> cache::Initializer {
 ///
 /// [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 No LLVM support
-    aes: bool,        // 3
-    pmull: bool,      // 4
-    sha1: bool,       // 5
-    sha2: bool,       // 6
-    crc32: bool,      // 7
-    atomics: bool,    // 8
-    fphp: bool,       // 9
-    asimdhp: bool,    // 10
-//  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
-    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
+    fp: bool,    // 0
+    asimd: bool, // 1
+    // evtstrm: bool, // 2 No LLVM support
+    aes: bool,     // 3
+    pmull: bool,   // 4
+    sha1: bool,    // 5
+    sha2: bool,    // 6
+    crc32: bool,   // 7
+    atomics: bool, // 8
+    fphp: bool,    // 9
+    asimdhp: bool, // 10
+    // 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
+    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
+    // 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 {
@@ -83,7 +83,7 @@ impl From<auxvec::AuxVec> for AtHwcap {
         AtHwcap {
             fp: bit::test(auxv.hwcap, 0),
             asimd: bit::test(auxv.hwcap, 1),
-//          evtstrm: bit::test(auxv.hwcap, 2),
+            // evtstrm: bit::test(auxv.hwcap, 2),
             aes: bit::test(auxv.hwcap, 3),
             pmull: bit::test(auxv.hwcap, 4),
             sha1: bit::test(auxv.hwcap, 5),
@@ -92,7 +92,7 @@ impl From<auxvec::AuxVec> for AtHwcap {
             atomics: bit::test(auxv.hwcap, 8),
             fphp: bit::test(auxv.hwcap, 9),
             asimdhp: bit::test(auxv.hwcap, 10),
-//          cpuid: bit::test(auxv.hwcap, 11),
+            // cpuid: bit::test(auxv.hwcap, 11),
             asimdrdm: bit::test(auxv.hwcap, 12),
             jscvt: bit::test(auxv.hwcap, 13),
             fcma: bit::test(auxv.hwcap, 14),
@@ -116,19 +116,19 @@ impl From<auxvec::AuxVec> for AtHwcap {
             dcpodp: bit::test(auxv.hwcap, 32),
             sve2: bit::test(auxv.hwcap, 33),
             sveaes: bit::test(auxv.hwcap, 34),
-//          svepmull: bit::test(auxv.hwcap, 35),
+            // 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),
+            // flagm2: bit::test(auxv.hwcap, 39),
             frint: bit::test(auxv.hwcap, 40),
-//          svei8mm: bit::test(auxv.hwcap, 41),
+            // svei8mm: bit::test(auxv.hwcap, 41),
             svef32mm: bit::test(auxv.hwcap, 42),
             svef64mm: bit::test(auxv.hwcap, 43),
-//          svebf16: bit::test(auxv.hwcap, 44),
+            // svebf16: bit::test(auxv.hwcap, 44),
             i8mm: bit::test(auxv.hwcap, 45),
             bf16: bit::test(auxv.hwcap, 46),
-//          dgh: bit::test(auxv.hwcap, 47),
+            // dgh: bit::test(auxv.hwcap, 47),
             rng: bit::test(auxv.hwcap, 48),
             bti: bit::test(auxv.hwcap, 49),
             mte: bit::test(auxv.hwcap, 50),
@@ -147,7 +147,7 @@ impl From<super::cpuinfo::CpuInfo> for AtHwcap {
             // cover that yet.
             fp: f.has("fp"),
             asimd: f.has("asimd"),
-//          evtstrm: f.has("evtstrm"),
+            // evtstrm: f.has("evtstrm"),
             aes: f.has("aes"),
             pmull: f.has("pmull"),
             sha1: f.has("sha1"),
@@ -156,7 +156,7 @@ impl From<super::cpuinfo::CpuInfo> for AtHwcap {
             atomics: f.has("atomics"),
             fphp: f.has("fphp"),
             asimdhp: f.has("asimdhp"),
-//          cpuid: f.has("cpuid"),
+            // cpuid: f.has("cpuid"),
             asimdrdm: f.has("asimdrdm"),
             jscvt: f.has("jscvt"),
             fcma: f.has("fcma"),
@@ -180,19 +180,19 @@ impl From<super::cpuinfo::CpuInfo> for AtHwcap {
             dcpodp: f.has("dcpodp"),
             sve2: f.has("sve2"),
             sveaes: f.has("sveaes"),
-//          svepmull: f.has("svepmull"),
+            // svepmull: f.has("svepmull"),
             svebitperm: f.has("svebitperm"),
             svesha3: f.has("svesha3"),
             svesm4: f.has("svesm4"),
-//          flagm2: f.has("flagm2"),
+            // flagm2: f.has("flagm2"),
             frint: f.has("frint"),
-//          svei8mm: f.has("svei8mm"),
+            // svei8mm: f.has("svei8mm"),
             svef32mm: f.has("svef32mm"),
             svef64mm: f.has("svef64mm"),
-//          svebf16: f.has("svebf16"),
+            // svebf16: f.has("svebf16"),
             i8mm: f.has("i8mm"),
             bf16: f.has("bf16"),
-//          dgh: f.has("dgh"),
+            // dgh: f.has("dgh"),
             rng: f.has("rng"),
             bti: f.has("bti"),
             mte: f.has("mte"),
@@ -264,7 +264,10 @@ impl AtHwcap {
             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::sha3,
+                self.sha512 && self.sha3 && self.sha1 && self.sha2 && asimd,
+            );
             enable_feature(Feature::sm4, self.sm3 && self.sm4 && asimd);
 
             // SVE2 requires SVE
@@ -272,8 +275,14 @@ impl AtHwcap {
             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::sve2_sha3, self.svesha3 && sve2 && self.sha512 && self.sha3 && self.sha1 && self.sha2);
+            enable_feature(
+                Feature::sve2_sm4,
+                self.svesm4 && sve2 && self.sm3 && self.sm4,
+            );
+            enable_feature(
+                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/crates/std_detect/src/detect/os/linux/arm.rs b/crates/std_detect/src/detect/os/linux/arm.rs
index 4a748b61f9..7601cf0a84 100644
--- a/crates/std_detect/src/detect/os/linux/arm.rs
+++ b/crates/std_detect/src/detect/os/linux/arm.rs
@@ -22,7 +22,11 @@ pub(crate) fn detect_features() -> cache::Initializer {
         enable_feature(&mut value, Feature::crc, bit::test(auxv.hwcap2, 4));
         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));
+        enable_feature(
+            &mut value,
+            Feature::sha2,
+            bit::test(auxv.hwcap2, 2) && bit::test(auxv.hwcap2, 3),
+        );
         return value;
     }
 
@@ -36,7 +40,11 @@ pub(crate) fn detect_features() -> cache::Initializer {
         enable_feature(&mut value, Feature::pmull, c.field("Features").has("pmull"));
         enable_feature(&mut value, Feature::crc, c.field("Features").has("crc32"));
         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"));
+        enable_feature(
+            &mut value,
+            Feature::sha2,
+            c.field("Features").has("sha1") && c.field("Features").has("sha2"),
+        );
         return value;
     }
     value
diff --git a/crates/std_detect/tests/cpu-detection.rs b/crates/std_detect/tests/cpu-detection.rs
index 935e409fc4..6dc2e839cc 100644
--- a/crates/std_detect/tests/cpu-detection.rs
+++ b/crates/std_detect/tests/cpu-detection.rs
@@ -61,7 +61,10 @@ fn aarch64_linux() {
     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!(
+        "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"));

From e72d1333502b18a5c33363fecabb8c693ac7cbb2 Mon Sep 17 00:00:00 2001
From: Adam Gemmell <adam.gemmell@arm.com>
Date: Fri, 21 May 2021 14:08:33 +0000
Subject: [PATCH 7/9] Replace simd_test macro

---
 crates/core_arch/src/arm_shared/crypto.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/crates/core_arch/src/arm_shared/crypto.rs b/crates/core_arch/src/arm_shared/crypto.rs
index 50492360e8..366a62d795 100644
--- a/crates/core_arch/src/arm_shared/crypto.rs
+++ b/crates/core_arch/src/arm_shared/crypto.rs
@@ -210,7 +210,8 @@ mod tests {
     use std::mem;
     use stdarch_test::simd_test;
 
-    #[simd_test(enable = "crypto")]
+    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
+    #[cfg_attr(not(bootstrap), simd_test(enable = "aes"))]
     unsafe fn test_vaeseq_u8() {
         let data = mem::transmute(u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8));
         let key = mem::transmute(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7));

From b639f40bd8675dbe0659d8e58324a9d374348760 Mon Sep 17 00:00:00 2001
From: Adam Gemmell <adam.gemmell@arm.com>
Date: Wed, 26 May 2021 13:47:19 +0000
Subject: [PATCH 8/9] Readd crypto for arm, as it's required for cryptographic
 intrinsics on LLVM <=12

---
 crates/core_arch/src/arm_shared/crypto.rs     | 115 +++++++++---------
 crates/std_detect/src/detect/arch/arm.rs      |   2 +
 .../src/detect/os/freebsd/aarch64.rs          |   1 -
 crates/std_detect/src/detect/os/linux/arm.rs  |  14 +++
 crates/std_detect/tests/cpu-detection.rs      |   1 +
 5 files changed, 76 insertions(+), 57 deletions(-)

diff --git a/crates/core_arch/src/arm_shared/crypto.rs b/crates/core_arch/src/arm_shared/crypto.rs
index 366a62d795..2d660fe79a 100644
--- a/crates/core_arch/src/arm_shared/crypto.rs
+++ b/crates/core_arch/src/arm_shared/crypto.rs
@@ -51,10 +51,13 @@ extern "C" {
 #[cfg(test)]
 use stdarch_test::assert_instr;
 
+// Rust compilers without 8a57820bca64a252489790a57cb5ea23db6f9198 need crypto (hence the bootstrap check)
+// LLVM builds without b8baa2a9132498ea286dbb0d03f005760ecc6fdb need crypto for arm (hence the target_arch check)
+
 /// AES single round encryption.
 #[inline]
-#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
-#[cfg_attr(not(bootstrap), target_feature(enable = "aes"))]
+#[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
+#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "aes"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(aese))]
 pub unsafe fn vaeseq_u8(data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
@@ -63,8 +66,8 @@ pub unsafe fn vaeseq_u8(data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
 
 /// AES single round decryption.
 #[inline]
-#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
-#[cfg_attr(not(bootstrap), target_feature(enable = "aes"))]
+#[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
+#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "aes"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(aesd))]
 pub unsafe fn vaesdq_u8(data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
@@ -73,8 +76,8 @@ pub unsafe fn vaesdq_u8(data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
 
 /// AES mix columns.
 #[inline]
-#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
-#[cfg_attr(not(bootstrap), target_feature(enable = "aes"))]
+#[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
+#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "aes"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(aesmc))]
 pub unsafe fn vaesmcq_u8(data: uint8x16_t) -> uint8x16_t {
@@ -83,8 +86,8 @@ pub unsafe fn vaesmcq_u8(data: uint8x16_t) -> uint8x16_t {
 
 /// AES inverse mix columns.
 #[inline]
-#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
-#[cfg_attr(not(bootstrap), target_feature(enable = "aes"))]
+#[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
+#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "aes"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(aesimc))]
 pub unsafe fn vaesimcq_u8(data: uint8x16_t) -> uint8x16_t {
@@ -93,8 +96,8 @@ pub unsafe fn vaesimcq_u8(data: uint8x16_t) -> uint8x16_t {
 
 /// SHA1 fixed rotate.
 #[inline]
-#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
-#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
+#[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
+#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1h))]
 pub unsafe fn vsha1h_u32(hash_e: u32) -> u32 {
@@ -103,8 +106,8 @@ pub unsafe fn vsha1h_u32(hash_e: u32) -> u32 {
 
 /// SHA1 hash update accelerator, choose.
 #[inline]
-#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
-#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
+#[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
+#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1c))]
 pub unsafe fn vsha1cq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) -> uint32x4_t {
@@ -113,8 +116,8 @@ pub unsafe fn vsha1cq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) ->
 
 /// SHA1 hash update accelerator, majority.
 #[inline]
-#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
-#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
+#[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
+#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1m))]
 pub unsafe fn vsha1mq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) -> uint32x4_t {
@@ -123,8 +126,8 @@ pub unsafe fn vsha1mq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) ->
 
 /// SHA1 hash update accelerator, parity.
 #[inline]
-#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
-#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
+#[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
+#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1p))]
 pub unsafe fn vsha1pq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) -> uint32x4_t {
@@ -133,8 +136,8 @@ pub unsafe fn vsha1pq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) ->
 
 /// SHA1 schedule update accelerator, first part.
 #[inline]
-#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
-#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
+#[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
+#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1su0))]
 pub unsafe fn vsha1su0q_u32(w0_3: uint32x4_t, w4_7: uint32x4_t, w8_11: uint32x4_t) -> uint32x4_t {
@@ -143,8 +146,8 @@ pub unsafe fn vsha1su0q_u32(w0_3: uint32x4_t, w4_7: uint32x4_t, w8_11: uint32x4_
 
 /// SHA1 schedule update accelerator, second part.
 #[inline]
-#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
-#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
+#[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
+#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1su1))]
 pub unsafe fn vsha1su1q_u32(tw0_3: uint32x4_t, w12_15: uint32x4_t) -> uint32x4_t {
@@ -153,8 +156,8 @@ pub unsafe fn vsha1su1q_u32(tw0_3: uint32x4_t, w12_15: uint32x4_t) -> uint32x4_t
 
 /// SHA256 hash update accelerator.
 #[inline]
-#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
-#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
+#[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
+#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha256h))]
 pub unsafe fn vsha256hq_u32(
@@ -167,8 +170,8 @@ pub unsafe fn vsha256hq_u32(
 
 /// SHA256 hash update accelerator, upper part.
 #[inline]
-#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
-#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
+#[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
+#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha256h2))]
 pub unsafe fn vsha256h2q_u32(
@@ -181,8 +184,8 @@ pub unsafe fn vsha256h2q_u32(
 
 /// SHA256 schedule update accelerator, first part.
 #[inline]
-#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
-#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
+#[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
+#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha256su0))]
 pub unsafe fn vsha256su0q_u32(w0_3: uint32x4_t, w4_7: uint32x4_t) -> uint32x4_t {
@@ -191,8 +194,8 @@ pub unsafe fn vsha256su0q_u32(w0_3: uint32x4_t, w4_7: uint32x4_t) -> uint32x4_t
 
 /// SHA256 schedule update accelerator, second part.
 #[inline]
-#[cfg_attr(bootstrap, target_feature(enable = "crypto"))]
-#[cfg_attr(not(bootstrap), target_feature(enable = "sha2"))]
+#[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
+#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha256su1))]
 pub unsafe fn vsha256su1q_u32(
@@ -210,8 +213,8 @@ mod tests {
     use std::mem;
     use stdarch_test::simd_test;
 
-    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
-    #[cfg_attr(not(bootstrap), simd_test(enable = "aes"))]
+    #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
+    #[cfg_attr(all(not(bootstrap), target_arch = "aarch64"), simd_test(enable = "aes"))]
     unsafe fn test_vaeseq_u8() {
         let data = mem::transmute(u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8));
         let key = mem::transmute(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7));
@@ -224,8 +227,8 @@ mod tests {
         );
     }
 
-    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
-    #[cfg_attr(not(bootstrap), simd_test(enable = "aes"))]
+    #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
+    #[cfg_attr(all(not(bootstrap), target_arch = "aarch64"), simd_test(enable = "aes"))]
     unsafe fn test_vaesdq_u8() {
         let data = mem::transmute(u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8));
         let key = mem::transmute(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7));
@@ -236,8 +239,8 @@ mod tests {
         );
     }
 
-    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
-    #[cfg_attr(not(bootstrap), simd_test(enable = "aes"))]
+    #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
+    #[cfg_attr(all(not(bootstrap), target_arch = "aarch64"), simd_test(enable = "aes"))]
     unsafe fn test_vaesmcq_u8() {
         let data = mem::transmute(u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8));
         let r: u8x16 = mem::transmute(vaesmcq_u8(data));
@@ -247,8 +250,8 @@ mod tests {
         );
     }
 
-    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
-    #[cfg_attr(not(bootstrap), simd_test(enable = "aes"))]
+    #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
+    #[cfg_attr(all(not(bootstrap), target_arch = "aarch64"), simd_test(enable = "aes"))]
     unsafe fn test_vaesimcq_u8() {
         let data = mem::transmute(u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8));
         let r: u8x16 = mem::transmute(vaesimcq_u8(data));
@@ -258,15 +261,15 @@ mod tests {
         );
     }
 
-    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
-    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
+    #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
+    #[cfg_attr(not(any(bootstrap, target_arch = "arm")), simd_test(enable = "sha2"))]
     unsafe fn test_vsha1h_u32() {
         assert_eq!(vsha1h_u32(0x1234), 0x048d);
         assert_eq!(vsha1h_u32(0x5678), 0x159e);
     }
 
-    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
-    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
+    #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
+    #[cfg_attr(not(any(bootstrap, target_arch = "arm")), simd_test(enable = "sha2"))]
     unsafe fn test_vsha1su0q_u32() {
         let r: u32x4 = mem::transmute(vsha1su0q_u32(
             mem::transmute(u32x4::new(0x1234_u32, 0x5678_u32, 0x9abc_u32, 0xdef0_u32)),
@@ -276,8 +279,8 @@ mod tests {
         assert_eq!(r, u32x4::new(0x9abc, 0xdef0, 0x1234, 0x5678));
     }
 
-    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
-    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
+    #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
+    #[cfg_attr(not(any(bootstrap, target_arch = "arm")), simd_test(enable = "sha2"))]
     unsafe fn test_vsha1su1q_u32() {
         let r: u32x4 = mem::transmute(vsha1su1q_u32(
             mem::transmute(u32x4::new(0x1234, 0x5678, 0x9abc, 0xdef0)),
@@ -289,8 +292,8 @@ mod tests {
         );
     }
 
-    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
-    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
+    #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
+    #[cfg_attr(not(any(bootstrap, target_arch = "arm")), simd_test(enable = "sha2"))]
     unsafe fn test_vsha1cq_u32() {
         let r: u32x4 = mem::transmute(vsha1cq_u32(
             mem::transmute(u32x4::new(0x1234, 0x5678, 0x9abc, 0xdef0)),
@@ -303,8 +306,8 @@ mod tests {
         );
     }
 
-    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
-    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
+    #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
+    #[cfg_attr(not(any(bootstrap, target_arch = "arm")), simd_test(enable = "sha2"))]
     unsafe fn test_vsha1pq_u32() {
         let r: u32x4 = mem::transmute(vsha1pq_u32(
             mem::transmute(u32x4::new(0x1234, 0x5678, 0x9abc, 0xdef0)),
@@ -317,8 +320,8 @@ mod tests {
         );
     }
 
-    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
-    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
+    #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
+    #[cfg_attr(not(any(bootstrap, target_arch = "arm")), simd_test(enable = "sha2"))]
     unsafe fn test_vsha1mq_u32() {
         let r: u32x4 = mem::transmute(vsha1mq_u32(
             mem::transmute(u32x4::new(0x1234, 0x5678, 0x9abc, 0xdef0)),
@@ -331,8 +334,8 @@ mod tests {
         );
     }
 
-    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
-    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
+    #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
+    #[cfg_attr(not(any(bootstrap, target_arch = "arm")), simd_test(enable = "sha2"))]
     unsafe fn test_vsha256hq_u32() {
         let r: u32x4 = mem::transmute(vsha256hq_u32(
             mem::transmute(u32x4::new(0x1234, 0x5678, 0x9abc, 0xdef0)),
@@ -345,8 +348,8 @@ mod tests {
         );
     }
 
-    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
-    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
+    #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
+    #[cfg_attr(not(any(bootstrap, target_arch = "arm")), simd_test(enable = "sha2"))]
     unsafe fn test_vsha256h2q_u32() {
         let r: u32x4 = mem::transmute(vsha256h2q_u32(
             mem::transmute(u32x4::new(0x1234, 0x5678, 0x9abc, 0xdef0)),
@@ -359,8 +362,8 @@ mod tests {
         );
     }
 
-    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
-    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
+    #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
+    #[cfg_attr(not(any(bootstrap, target_arch = "arm")), simd_test(enable = "sha2"))]
     unsafe fn test_vsha256su0q_u32() {
         let r: u32x4 = mem::transmute(vsha256su0q_u32(
             mem::transmute(u32x4::new(0x1234, 0x5678, 0x9abc, 0xdef0)),
@@ -372,8 +375,8 @@ mod tests {
         );
     }
 
-    #[cfg_attr(bootstrap, simd_test(enable = "crypto"))]
-    #[cfg_attr(not(bootstrap), simd_test(enable = "sha2"))]
+    #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
+    #[cfg_attr(not(any(bootstrap, target_arch = "arm")), simd_test(enable = "sha2"))]
     unsafe fn test_vsha256su1q_u32() {
         let r: u32x4 = mem::transmute(vsha256su1q_u32(
             mem::transmute(u32x4::new(0x1234, 0x5678, 0x9abc, 0xdef0)),
diff --git a/crates/std_detect/src/detect/arch/arm.rs b/crates/std_detect/src/detect/arch/arm.rs
index dea7ff75b4..d96514c844 100644
--- a/crates/std_detect/src/detect/arch/arm.rs
+++ b/crates/std_detect/src/detect/arch/arm.rs
@@ -16,6 +16,8 @@ features! {
     /// Polynomial Multiply
     @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] crc: "crc";
     /// CRC32 (Cyclic Redundancy Check)
+    @FEATURE: #[unstable(feature = "stdsimd", issue = "27731")] crypto: "crypto";
+    /// 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";
diff --git a/crates/std_detect/src/detect/os/freebsd/aarch64.rs b/crates/std_detect/src/detect/os/freebsd/aarch64.rs
index ed21252440..7d972b373f 100644
--- a/crates/std_detect/src/detect/os/freebsd/aarch64.rs
+++ b/crates/std_detect/src/detect/os/freebsd/aarch64.rs
@@ -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/crates/std_detect/src/detect/os/linux/arm.rs b/crates/std_detect/src/detect/os/linux/arm.rs
index 7601cf0a84..99ecca01bb 100644
--- a/crates/std_detect/src/detect/os/linux/arm.rs
+++ b/crates/std_detect/src/detect/os/linux/arm.rs
@@ -20,6 +20,14 @@ pub(crate) fn detect_features() -> cache::Initializer {
         enable_feature(&mut value, Feature::neon, bit::test(auxv.hwcap, 12));
         enable_feature(&mut value, Feature::pmull, bit::test(auxv.hwcap2, 1));
         enable_feature(&mut value, Feature::crc, bit::test(auxv.hwcap2, 4));
+        enable_feature(
+            &mut value,
+            Feature::crypto,
+            bit::test(auxv.hwcap2, 0)
+                && bit::test(auxv.hwcap2, 1)
+                && 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(
@@ -39,6 +47,12 @@ pub(crate) fn detect_features() -> cache::Initializer {
         );
         enable_feature(&mut value, Feature::pmull, c.field("Features").has("pmull"));
         enable_feature(&mut value, Feature::crc, c.field("Features").has("crc32"));
+        enable_feature(&mut value, Feature::crypto, 
+            c.field("Features").has("aes")
+                && c.field("Features").has("pmull")
+                && 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,
diff --git a/crates/std_detect/tests/cpu-detection.rs b/crates/std_detect/tests/cpu-detection.rs
index 6dc2e839cc..adbe4fa9a7 100644
--- a/crates/std_detect/tests/cpu-detection.rs
+++ b/crates/std_detect/tests/cpu-detection.rs
@@ -25,6 +25,7 @@ fn arm_linux() {
     println!("neon: {}", is_arm_feature_detected!("neon"));
     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"));
 }

From 693ae3c727762022af134a0fa2b661a2ba2313ce Mon Sep 17 00:00:00 2001
From: Adam Gemmell <adam.gemmell@arm.com>
Date: Thu, 27 May 2021 15:49:48 +0000
Subject: [PATCH 9/9] Style changes

---
 crates/core_arch/src/arm_shared/crypto.rs    | 90 ++++++++++++++++----
 crates/std_detect/src/detect/os/linux/arm.rs |  8 +-
 2 files changed, 77 insertions(+), 21 deletions(-)

diff --git a/crates/core_arch/src/arm_shared/crypto.rs b/crates/core_arch/src/arm_shared/crypto.rs
index 2d660fe79a..19d9190917 100644
--- a/crates/core_arch/src/arm_shared/crypto.rs
+++ b/crates/core_arch/src/arm_shared/crypto.rs
@@ -57,7 +57,10 @@ use stdarch_test::assert_instr;
 /// AES single round encryption.
 #[inline]
 #[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
-#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "aes"))]
+#[cfg_attr(
+    not(any(bootstrap, target_arch = "arm")),
+    target_feature(enable = "aes")
+)]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(aese))]
 pub unsafe fn vaeseq_u8(data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
@@ -67,7 +70,10 @@ pub unsafe fn vaeseq_u8(data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
 /// AES single round decryption.
 #[inline]
 #[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
-#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "aes"))]
+#[cfg_attr(
+    not(any(bootstrap, target_arch = "arm")),
+    target_feature(enable = "aes")
+)]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(aesd))]
 pub unsafe fn vaesdq_u8(data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
@@ -77,7 +83,10 @@ pub unsafe fn vaesdq_u8(data: uint8x16_t, key: uint8x16_t) -> uint8x16_t {
 /// AES mix columns.
 #[inline]
 #[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
-#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "aes"))]
+#[cfg_attr(
+    not(any(bootstrap, target_arch = "arm")),
+    target_feature(enable = "aes")
+)]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(aesmc))]
 pub unsafe fn vaesmcq_u8(data: uint8x16_t) -> uint8x16_t {
@@ -87,7 +96,10 @@ pub unsafe fn vaesmcq_u8(data: uint8x16_t) -> uint8x16_t {
 /// AES inverse mix columns.
 #[inline]
 #[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
-#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "aes"))]
+#[cfg_attr(
+    not(any(bootstrap, target_arch = "arm")),
+    target_feature(enable = "aes")
+)]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(aesimc))]
 pub unsafe fn vaesimcq_u8(data: uint8x16_t) -> uint8x16_t {
@@ -97,7 +109,10 @@ pub unsafe fn vaesimcq_u8(data: uint8x16_t) -> uint8x16_t {
 /// SHA1 fixed rotate.
 #[inline]
 #[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
-#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
+#[cfg_attr(
+    not(any(bootstrap, target_arch = "arm")),
+    target_feature(enable = "sha2")
+)]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1h))]
 pub unsafe fn vsha1h_u32(hash_e: u32) -> u32 {
@@ -107,7 +122,10 @@ pub unsafe fn vsha1h_u32(hash_e: u32) -> u32 {
 /// SHA1 hash update accelerator, choose.
 #[inline]
 #[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
-#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
+#[cfg_attr(
+    not(any(bootstrap, target_arch = "arm")),
+    target_feature(enable = "sha2")
+)]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1c))]
 pub unsafe fn vsha1cq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) -> uint32x4_t {
@@ -117,7 +135,10 @@ pub unsafe fn vsha1cq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) ->
 /// SHA1 hash update accelerator, majority.
 #[inline]
 #[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
-#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
+#[cfg_attr(
+    not(any(bootstrap, target_arch = "arm")),
+    target_feature(enable = "sha2")
+)]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1m))]
 pub unsafe fn vsha1mq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) -> uint32x4_t {
@@ -127,7 +148,10 @@ pub unsafe fn vsha1mq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) ->
 /// SHA1 hash update accelerator, parity.
 #[inline]
 #[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
-#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
+#[cfg_attr(
+    not(any(bootstrap, target_arch = "arm")),
+    target_feature(enable = "sha2")
+)]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1p))]
 pub unsafe fn vsha1pq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) -> uint32x4_t {
@@ -137,7 +161,10 @@ pub unsafe fn vsha1pq_u32(hash_abcd: uint32x4_t, hash_e: u32, wk: uint32x4_t) ->
 /// SHA1 schedule update accelerator, first part.
 #[inline]
 #[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
-#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
+#[cfg_attr(
+    not(any(bootstrap, target_arch = "arm")),
+    target_feature(enable = "sha2")
+)]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1su0))]
 pub unsafe fn vsha1su0q_u32(w0_3: uint32x4_t, w4_7: uint32x4_t, w8_11: uint32x4_t) -> uint32x4_t {
@@ -147,7 +174,10 @@ pub unsafe fn vsha1su0q_u32(w0_3: uint32x4_t, w4_7: uint32x4_t, w8_11: uint32x4_
 /// SHA1 schedule update accelerator, second part.
 #[inline]
 #[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
-#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
+#[cfg_attr(
+    not(any(bootstrap, target_arch = "arm")),
+    target_feature(enable = "sha2")
+)]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha1su1))]
 pub unsafe fn vsha1su1q_u32(tw0_3: uint32x4_t, w12_15: uint32x4_t) -> uint32x4_t {
@@ -157,7 +187,10 @@ pub unsafe fn vsha1su1q_u32(tw0_3: uint32x4_t, w12_15: uint32x4_t) -> uint32x4_t
 /// SHA256 hash update accelerator.
 #[inline]
 #[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
-#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
+#[cfg_attr(
+    not(any(bootstrap, target_arch = "arm")),
+    target_feature(enable = "sha2")
+)]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha256h))]
 pub unsafe fn vsha256hq_u32(
@@ -171,7 +204,10 @@ pub unsafe fn vsha256hq_u32(
 /// SHA256 hash update accelerator, upper part.
 #[inline]
 #[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
-#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
+#[cfg_attr(
+    not(any(bootstrap, target_arch = "arm")),
+    target_feature(enable = "sha2")
+)]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha256h2))]
 pub unsafe fn vsha256h2q_u32(
@@ -185,7 +221,10 @@ pub unsafe fn vsha256h2q_u32(
 /// SHA256 schedule update accelerator, first part.
 #[inline]
 #[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
-#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
+#[cfg_attr(
+    not(any(bootstrap, target_arch = "arm")),
+    target_feature(enable = "sha2")
+)]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha256su0))]
 pub unsafe fn vsha256su0q_u32(w0_3: uint32x4_t, w4_7: uint32x4_t) -> uint32x4_t {
@@ -195,7 +234,10 @@ pub unsafe fn vsha256su0q_u32(w0_3: uint32x4_t, w4_7: uint32x4_t) -> uint32x4_t
 /// SHA256 schedule update accelerator, second part.
 #[inline]
 #[cfg_attr(any(bootstrap, target_arch = "arm"), target_feature(enable = "crypto"))]
-#[cfg_attr(not(any(bootstrap, target_arch = "arm")), target_feature(enable = "sha2"))]
+#[cfg_attr(
+    not(any(bootstrap, target_arch = "arm")),
+    target_feature(enable = "sha2")
+)]
 #[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
 #[cfg_attr(test, assert_instr(sha256su1))]
 pub unsafe fn vsha256su1q_u32(
@@ -214,7 +256,10 @@ mod tests {
     use stdarch_test::simd_test;
 
     #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
-    #[cfg_attr(all(not(bootstrap), target_arch = "aarch64"), simd_test(enable = "aes"))]
+    #[cfg_attr(
+        all(not(bootstrap), target_arch = "aarch64"),
+        simd_test(enable = "aes")
+    )]
     unsafe fn test_vaeseq_u8() {
         let data = mem::transmute(u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8));
         let key = mem::transmute(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7));
@@ -228,7 +273,10 @@ mod tests {
     }
 
     #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
-    #[cfg_attr(all(not(bootstrap), target_arch = "aarch64"), simd_test(enable = "aes"))]
+    #[cfg_attr(
+        all(not(bootstrap), target_arch = "aarch64"),
+        simd_test(enable = "aes")
+    )]
     unsafe fn test_vaesdq_u8() {
         let data = mem::transmute(u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8));
         let key = mem::transmute(u8x16::new(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7));
@@ -240,7 +288,10 @@ mod tests {
     }
 
     #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
-    #[cfg_attr(all(not(bootstrap), target_arch = "aarch64"), simd_test(enable = "aes"))]
+    #[cfg_attr(
+        all(not(bootstrap), target_arch = "aarch64"),
+        simd_test(enable = "aes")
+    )]
     unsafe fn test_vaesmcq_u8() {
         let data = mem::transmute(u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8));
         let r: u8x16 = mem::transmute(vaesmcq_u8(data));
@@ -251,7 +302,10 @@ mod tests {
     }
 
     #[cfg_attr(any(bootstrap, target_arch = "arm"), simd_test(enable = "crypto"))]
-    #[cfg_attr(all(not(bootstrap), target_arch = "aarch64"), simd_test(enable = "aes"))]
+    #[cfg_attr(
+        all(not(bootstrap), target_arch = "aarch64"),
+        simd_test(enable = "aes")
+    )]
     unsafe fn test_vaesimcq_u8() {
         let data = mem::transmute(u8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8));
         let r: u8x16 = mem::transmute(vaesimcq_u8(data));
diff --git a/crates/std_detect/src/detect/os/linux/arm.rs b/crates/std_detect/src/detect/os/linux/arm.rs
index 99ecca01bb..7383e487f1 100644
--- a/crates/std_detect/src/detect/os/linux/arm.rs
+++ b/crates/std_detect/src/detect/os/linux/arm.rs
@@ -26,7 +26,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
             bit::test(auxv.hwcap2, 0)
                 && bit::test(auxv.hwcap2, 1)
                 && bit::test(auxv.hwcap2, 2)
-                && bit::test(auxv.hwcap2, 3)
+                && bit::test(auxv.hwcap2, 3),
         );
         enable_feature(&mut value, Feature::aes, bit::test(auxv.hwcap2, 0));
         // SHA2 requires SHA1 & SHA2 features
@@ -47,11 +47,13 @@ pub(crate) fn detect_features() -> cache::Initializer {
         );
         enable_feature(&mut value, Feature::pmull, c.field("Features").has("pmull"));
         enable_feature(&mut value, Feature::crc, c.field("Features").has("crc32"));
-        enable_feature(&mut value, Feature::crypto, 
+        enable_feature(
+            &mut value,
+            Feature::crypto,
             c.field("Features").has("aes")
                 && c.field("Features").has("pmull")
                 && c.field("Features").has("sha1")
-                && c.field("Features").has("sha2")
+                && c.field("Features").has("sha2"),
         );
         enable_feature(&mut value, Feature::aes, c.field("Features").has("aes"));
         enable_feature(