about summary refs log tree commit diff
path: root/library/stdarch/crates/std_detect
diff options
context:
space:
mode:
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>2023-01-11 15:58:49 +0900
committerAmanieu d'Antras <amanieu@gmail.com>2024-01-16 02:57:10 +0000
commitd51ea0d261392bc526004c09894155038bad131d (patch)
treebcf7c8893f99d17d3dfb7e39bc745b1a86c4921a /library/stdarch/crates/std_detect
parentc4a00026d41404e72489f1883eec1964dc16554a (diff)
downloadrust-d51ea0d261392bc526004c09894155038bad131d.tar.gz
rust-d51ea0d261392bc526004c09894155038bad131d.zip
Add CPU detection for macOS/aarch64.
Diffstat (limited to 'library/stdarch/crates/std_detect')
-rw-r--r--library/stdarch/crates/std_detect/src/detect/mod.rs3
-rw-r--r--library/stdarch/crates/std_detect/src/detect/os/macos/aarch64.rs98
-rw-r--r--library/stdarch/crates/std_detect/tests/cpu-detection.rs32
3 files changed, 133 insertions, 0 deletions
diff --git a/library/stdarch/crates/std_detect/src/detect/mod.rs b/library/stdarch/crates/std_detect/src/detect/mod.rs
index 5ce4e54e23b..c938abf17da 100644
--- a/library/stdarch/crates/std_detect/src/detect/mod.rs
+++ b/library/stdarch/crates/std_detect/src/detect/mod.rs
@@ -66,6 +66,9 @@ cfg_if! {
     } else if #[cfg(all(target_os = "windows", target_arch = "aarch64"))] {
         #[path = "os/windows/aarch64.rs"]
         mod os;
+    } else if #[cfg(all(target_os = "macos", target_arch = "aarch64", feature = "libc"))] {
+        #[path = "os/macos/aarch64.rs"]
+        mod os;
     } else {
         #[path = "os/other.rs"]
         mod os;
diff --git a/library/stdarch/crates/std_detect/src/detect/os/macos/aarch64.rs b/library/stdarch/crates/std_detect/src/detect/os/macos/aarch64.rs
new file mode 100644
index 00000000000..d7ebd956d69
--- /dev/null
+++ b/library/stdarch/crates/std_detect/src/detect/os/macos/aarch64.rs
@@ -0,0 +1,98 @@
+//! Run-time feature detection for aarch64 on macOS.
+
+use crate::detect::{cache, Feature};
+
+#[inline]
+fn _sysctlbyname(name: &str) -> bool {
+    use libc;
+
+    let mut enabled: i32 = 0;
+    let mut enabled_len: usize = 4;
+    let enabled_ptr = &mut enabled as *mut i32 as *mut libc::c_void;
+
+    let ret = unsafe {
+        libc::sysctlbyname(
+            name.as_ptr() as *const i8,
+            enabled_ptr,
+            &mut enabled_len,
+            core::ptr::null_mut(),
+            0,
+        )
+    };
+
+    match ret {
+        0 => enabled != 0,
+        _ => false,
+    }
+}
+
+/// Try to read the features using sysctlbyname.
+pub(crate) fn detect_features() -> cache::Initializer {
+    let mut value = cache::Initializer::default();
+
+    let mut enable_feature = |f, enable| {
+        if enable {
+            value.set(f as u32);
+        }
+    };
+
+    let asimd = _sysctlbyname("hw.optional.AdvSIMD\0");
+    let pmull = _sysctlbyname("hw.optional.arm.FEAT_PMULL\0");
+    let fp = _sysctlbyname("hw.optional.floatingpoint\0");
+    let fp16 = _sysctlbyname("hw.optional.arm.FEAT_FP16\0");
+    let crc = _sysctlbyname("hw.optional.armv8_crc32\0");
+    let lse = _sysctlbyname("hw.optional.arm.FEAT_LSE\0");
+    let lse2 = _sysctlbyname("hw.optional.arm.FEAT_LSE2\0");
+    let rdm = _sysctlbyname("hw.optional.arm.FEAT_RDM\0");
+    let rcpc = _sysctlbyname("hw.optional.arm.FEAT_LRCPC\0");
+    let rcpc2 = _sysctlbyname("hw.optional.arm.FEAT_LRCPC2\0");
+    let dotprod = _sysctlbyname("hw.optional.arm.FEAT_DotProd\0");
+    let fhm = _sysctlbyname("hw.optional.arm.FEAT_FHM\0");
+    let flagm = _sysctlbyname("hw.optional.arm.FEAT_FlagM\0");
+    let ssbs = _sysctlbyname("hw.optional.arm.FEAT_SSBS\0");
+    let sb = _sysctlbyname("hw.optional.arm.FEAT_SB\0");
+    let paca = _sysctlbyname("hw.optional.arm.FEAT_PAuth\0");
+    let dpb = _sysctlbyname("hw.optional.arm.FEAT_DPB\0");
+    let dpb2 = _sysctlbyname("hw.optional.arm.FEAT_DPB2\0");
+    let frintts = _sysctlbyname("hw.optional.arm.FEAT_FRINTTS\0");
+    let i8mm = _sysctlbyname("hw.optional.arm.FEAT_I8MM\0");
+    let bf16 = _sysctlbyname("hw.optional.arm.FEAT_BF16\0");
+    let bti = _sysctlbyname("hw.optional.arm.FEAT_BTI\0");
+    let fcma = _sysctlbyname("hw.optional.arm.FEAT_FCMA\0");
+    let aes = _sysctlbyname("hw.optional.arm.FEAT_AES\0");
+    let sha1 = _sysctlbyname("hw.optional.arm.FEAT_SHA1\0");
+    let sha2 = _sysctlbyname("hw.optional.arm.FEAT_SHA256\0");
+    let sha3 = _sysctlbyname("hw.optional.arm.FEAT_SHA3\0");
+    let sha512 = _sysctlbyname("hw.optional.arm.FEAT_SHA512\0");
+    let jsconv = _sysctlbyname("hw.optional.arm.FEAT_JSCVT\0");
+
+    enable_feature(Feature::asimd, asimd);
+    enable_feature(Feature::pmull, pmull);
+    enable_feature(Feature::fp, fp);
+    enable_feature(Feature::fp16, fp16);
+    enable_feature(Feature::crc, crc);
+    enable_feature(Feature::lse, lse);
+    enable_feature(Feature::lse2, lse2);
+    enable_feature(Feature::rdm, rdm);
+    enable_feature(Feature::rcpc, rcpc);
+    enable_feature(Feature::rcpc2, rcpc2);
+    enable_feature(Feature::dotprod, dotprod);
+    enable_feature(Feature::fhm, fhm);
+    enable_feature(Feature::flagm, flagm);
+    enable_feature(Feature::ssbs, ssbs);
+    enable_feature(Feature::sb, sb);
+    enable_feature(Feature::paca, paca);
+    enable_feature(Feature::dpb, dpb);
+    enable_feature(Feature::dpb2, dpb2);
+    enable_feature(Feature::frintts, frintts);
+    enable_feature(Feature::i8mm, i8mm);
+    enable_feature(Feature::bf16, bf16);
+    enable_feature(Feature::bti, bti);
+    enable_feature(Feature::fcma, fcma);
+    enable_feature(Feature::aes, aes);
+    enable_feature(Feature::jsconv, jsconv);
+    enable_feature(Feature::sha2, sha1 && sha2 && asimd);
+    enable_feature(Feature::sha3, sha512 && sha3 && asimd);
+
+    value
+}
diff --git a/library/stdarch/crates/std_detect/tests/cpu-detection.rs b/library/stdarch/crates/std_detect/tests/cpu-detection.rs
index cb57b849d69..1ad897a2e21 100644
--- a/library/stdarch/crates/std_detect/tests/cpu-detection.rs
+++ b/library/stdarch/crates/std_detect/tests/cpu-detection.rs
@@ -140,6 +140,38 @@ fn aarch64_bsd() {
 }
 
 #[test]
+#[cfg(all(target_arch = "aarch64", target_os = "macos"))]
+fn aarch64_macos() {
+    println!("asimd: {:?}", is_aarch64_feature_detected!("asimd"));
+    println!("fp: {:?}", is_aarch64_feature_detected!("fp"));
+    println!("fp16: {:?}", is_aarch64_feature_detected!("fp16"));
+    println!("pmull: {:?}", is_aarch64_feature_detected!("pmull"));
+    println!("crc: {:?}", is_aarch64_feature_detected!("crc"));
+    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!("fhm: {:?}", is_aarch64_feature_detected!("fhm"));
+    println!("flagm: {:?}", is_aarch64_feature_detected!("flagm"));
+    println!("ssbs: {:?}", is_aarch64_feature_detected!("ssbs"));
+    println!("sb: {:?}", is_aarch64_feature_detected!("sb"));
+    println!("paca: {:?}", is_aarch64_feature_detected!("paca"));
+    println!("dpb: {:?}", is_aarch64_feature_detected!("dpb"));
+    println!("dpb2: {:?}", is_aarch64_feature_detected!("dpb2"));
+    println!("frintts: {:?}", is_aarch64_feature_detected!("frintts"));
+    println!("i8mm: {:?}", is_aarch64_feature_detected!("i8mm"));
+    println!("bf16: {:?}", is_aarch64_feature_detected!("bf16"));
+    println!("bti: {:?}", is_aarch64_feature_detected!("bti"));
+    println!("fcma: {:?}", is_aarch64_feature_detected!("fcma"));
+    println!("jsconv: {:?}", is_aarch64_feature_detected!("jsconv"));
+    println!("aes: {:?}", is_aarch64_feature_detected!("aes"));
+    println!("sha2: {:?}", is_aarch64_feature_detected!("sha2"));
+    println!("sha3: {:?}", is_aarch64_feature_detected!("sha3"));
+}
+
+#[test]
 #[cfg(all(target_arch = "powerpc", target_os = "linux"))]
 fn powerpc_linux() {
     println!("altivec: {}", is_powerpc_feature_detected!("altivec"));