diff options
| author | Makoto Kato <m_kato@ga2.so-net.ne.jp> | 2023-01-11 15:58:49 +0900 |
|---|---|---|
| committer | Amanieu d'Antras <amanieu@gmail.com> | 2024-01-16 02:57:10 +0000 |
| commit | d51ea0d261392bc526004c09894155038bad131d (patch) | |
| tree | bcf7c8893f99d17d3dfb7e39bc745b1a86c4921a /library/stdarch/crates/std_detect | |
| parent | c4a00026d41404e72489f1883eec1964dc16554a (diff) | |
| download | rust-d51ea0d261392bc526004c09894155038bad131d.tar.gz rust-d51ea0d261392bc526004c09894155038bad131d.zip | |
Add CPU detection for macOS/aarch64.
Diffstat (limited to 'library/stdarch/crates/std_detect')
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")); |
