about summary refs log tree commit diff
path: root/library/stdarch/crates/std_detect/src
diff options
context:
space:
mode:
authorTaiki Endo <te316e89@gmail.com>2023-01-26 00:50:42 +0900
committerAmanieu d'Antras <amanieu@gmail.com>2023-01-26 23:33:52 +0000
commitd3bb923c82da9df128a6faad659bdee9e2008821 (patch)
tree0c5406f6a1a86deb8ad8cf99a2b4aa1939308689 /library/stdarch/crates/std_detect/src
parent674fd58f608a0bf4f551c82fad4a28e8297c5feb (diff)
downloadrust-d3bb923c82da9df128a6faad659bdee9e2008821.tar.gz
rust-d3bb923c82da9df128a6faad659bdee9e2008821.zip
std_detect: Split os/aarch64.rs' detect_features into reading and parsing
Diffstat (limited to 'library/stdarch/crates/std_detect/src')
-rw-r--r--library/stdarch/crates/std_detect/src/detect/os/aarch64.rs135
1 files changed, 72 insertions, 63 deletions
diff --git a/library/stdarch/crates/std_detect/src/detect/os/aarch64.rs b/library/stdarch/crates/std_detect/src/detect/os/aarch64.rs
index e0e62ee3393..bda5f1bf2de 100644
--- a/library/stdarch/crates/std_detect/src/detect/os/aarch64.rs
+++ b/library/stdarch/crates/std_detect/src/detect/os/aarch64.rs
@@ -23,77 +23,86 @@ use core::arch::asm;
 ///
 /// This will cause SIGILL if the current OS is not trapping the mrs instruction.
 pub(crate) fn detect_features() -> cache::Initializer {
-    let mut value = cache::Initializer::default();
+    // ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0
+    let aa64isar0: u64;
+    unsafe {
+        asm!(
+            "mrs {}, ID_AA64ISAR0_EL1",
+            out(reg) aa64isar0,
+            options(pure, nomem, preserves_flags, nostack)
+        );
+    }
 
-    {
-        let mut enable_feature = |f, enable| {
-            if enable {
-                value.set(f as u32);
-            }
-        };
+    // ID_AA64ISAR1_EL1 - Instruction Set Attribute Register 1
+    let aa64isar1: u64;
+    unsafe {
+        asm!(
+            "mrs {}, ID_AA64ISAR1_EL1",
+            out(reg) aa64isar1,
+            options(pure, nomem, preserves_flags, nostack)
+        );
+    }
 
-        // ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0
-        let aa64isar0: u64;
-        unsafe {
-            asm!(
-                "mrs {}, ID_AA64ISAR0_EL1",
-                out(reg) aa64isar0,
-                options(pure, nomem, preserves_flags, nostack)
-            );
-        }
+    // ID_AA64PFR0_EL1 - Processor Feature Register 0
+    let aa64pfr0: u64;
+    unsafe {
+        asm!(
+            "mrs {}, ID_AA64PFR0_EL1",
+            out(reg) aa64pfr0,
+            options(pure, nomem, preserves_flags, nostack)
+        );
+    }
+
+    parse_system_registers(aa64isar0, aa64isar1, aa64pfr0)
+}
 
-        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);
+pub(crate) fn parse_system_registers(
+    aa64isar0: u64,
+    aa64isar1: u64,
+    aa64pfr0: u64,
+) -> cache::Initializer {
+    let mut value = cache::Initializer::default();
 
-        // ID_AA64PFR0_EL1 - Processor Feature Register 0
-        let aa64pfr0: u64;
-        unsafe {
-            asm!(
-                "mrs {}, ID_AA64PFR0_EL1",
-                out(reg) aa64pfr0,
-                options(pure, nomem, preserves_flags, nostack)
-            );
+    let mut enable_feature = |f, enable| {
+        if enable {
+            value.set(f as u32);
         }
+    };
 
-        let fp = bits_shift(aa64pfr0, 19, 16) < 0xF;
-        let fphp = bits_shift(aa64pfr0, 19, 16) >= 1;
-        let asimd = bits_shift(aa64pfr0, 23, 20) < 0xF;
-        let asimdhp = bits_shift(aa64pfr0, 23, 20) >= 1;
-        enable_feature(Feature::fp, fp);
-        enable_feature(Feature::fp16, fphp);
-        // SIMD support requires float support - if half-floats are
-        // 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,
-            asimd && bits_shift(aa64isar0, 47, 44) >= 1,
-        );
-        enable_feature(Feature::sve, asimd && bits_shift(aa64pfr0, 35, 32) >= 1);
+    // ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0
+    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);
 
-        // ID_AA64ISAR1_EL1 - Instruction Set Attribute Register 1
-        let aa64isar1: u64;
-        unsafe {
-            asm!(
-                "mrs {}, ID_AA64ISAR1_EL1",
-                out(reg) aa64isar1,
-                options(pure, nomem, preserves_flags, nostack)
-            );
-        }
+    // ID_AA64PFR0_EL1 - Processor Feature Register 0
+    let fp = bits_shift(aa64pfr0, 19, 16) < 0xF;
+    let fphp = bits_shift(aa64pfr0, 19, 16) >= 1;
+    let asimd = bits_shift(aa64pfr0, 23, 20) < 0xF;
+    let asimdhp = bits_shift(aa64pfr0, 23, 20) >= 1;
+    enable_feature(Feature::fp, fp);
+    enable_feature(Feature::fp16, fphp);
+    // SIMD support requires float support - if half-floats are
+    // 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,
+        asimd && bits_shift(aa64isar0, 47, 44) >= 1,
+    );
+    enable_feature(Feature::sve, asimd && bits_shift(aa64pfr0, 35, 32) >= 1);
 
-        // Check for either APA or API field
-        enable_feature(Feature::paca, bits_shift(aa64isar1, 11, 4) >= 1);
-        enable_feature(Feature::rcpc, bits_shift(aa64isar1, 23, 20) >= 1);
-        // Check for either GPA or GPI field
-        enable_feature(Feature::pacg, bits_shift(aa64isar1, 31, 24) >= 1);
-    }
+    // ID_AA64PFR0_EL1 - Processor Feature Register 0
+    // Check for either APA or API field
+    enable_feature(Feature::paca, bits_shift(aa64isar1, 11, 4) >= 1);
+    enable_feature(Feature::rcpc, bits_shift(aa64isar1, 23, 20) >= 1);
+    // Check for either GPA or GPI field
+    enable_feature(Feature::pacg, bits_shift(aa64isar1, 31, 24) >= 1);
 
     value
 }