Skip to content

Commit 2659a32

Browse files
makotokatoAmanieu
authored andcommitted
Add CPU detection for macOS/aarch64.
1 parent 0fd054c commit 2659a32

File tree

3 files changed

+133
-0
lines changed

3 files changed

+133
-0
lines changed

crates/std_detect/src/detect/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ cfg_if! {
6666
} else if #[cfg(all(target_os = "windows", target_arch = "aarch64"))] {
6767
#[path = "os/windows/aarch64.rs"]
6868
mod os;
69+
} else if #[cfg(all(target_os = "macos", target_arch = "aarch64", feature = "libc"))] {
70+
#[path = "os/macos/aarch64.rs"]
71+
mod os;
6972
} else {
7073
#[path = "os/other.rs"]
7174
mod os;
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//! Run-time feature detection for aarch64 on macOS.
2+
3+
use crate::detect::{cache, Feature};
4+
5+
#[inline]
6+
fn _sysctlbyname(name: &str) -> bool {
7+
use libc;
8+
9+
let mut enabled: i32 = 0;
10+
let mut enabled_len: usize = 4;
11+
let enabled_ptr = &mut enabled as *mut i32 as *mut libc::c_void;
12+
13+
let ret = unsafe {
14+
libc::sysctlbyname(
15+
name.as_ptr() as *const i8,
16+
enabled_ptr,
17+
&mut enabled_len,
18+
core::ptr::null_mut(),
19+
0,
20+
)
21+
};
22+
23+
match ret {
24+
0 => enabled != 0,
25+
_ => false,
26+
}
27+
}
28+
29+
/// Try to read the features using sysctlbyname.
30+
pub(crate) fn detect_features() -> cache::Initializer {
31+
let mut value = cache::Initializer::default();
32+
33+
let mut enable_feature = |f, enable| {
34+
if enable {
35+
value.set(f as u32);
36+
}
37+
};
38+
39+
let asimd = _sysctlbyname("hw.optional.AdvSIMD\0");
40+
let pmull = _sysctlbyname("hw.optional.arm.FEAT_PMULL\0");
41+
let fp = _sysctlbyname("hw.optional.floatingpoint\0");
42+
let fp16 = _sysctlbyname("hw.optional.arm.FEAT_FP16\0");
43+
let crc = _sysctlbyname("hw.optional.armv8_crc32\0");
44+
let lse = _sysctlbyname("hw.optional.arm.FEAT_LSE\0");
45+
let lse2 = _sysctlbyname("hw.optional.arm.FEAT_LSE2\0");
46+
let rdm = _sysctlbyname("hw.optional.arm.FEAT_RDM\0");
47+
let rcpc = _sysctlbyname("hw.optional.arm.FEAT_LRCPC\0");
48+
let rcpc2 = _sysctlbyname("hw.optional.arm.FEAT_LRCPC2\0");
49+
let dotprod = _sysctlbyname("hw.optional.arm.FEAT_DotProd\0");
50+
let fhm = _sysctlbyname("hw.optional.arm.FEAT_FHM\0");
51+
let flagm = _sysctlbyname("hw.optional.arm.FEAT_FlagM\0");
52+
let ssbs = _sysctlbyname("hw.optional.arm.FEAT_SSBS\0");
53+
let sb = _sysctlbyname("hw.optional.arm.FEAT_SB\0");
54+
let paca = _sysctlbyname("hw.optional.arm.FEAT_PAuth\0");
55+
let dpb = _sysctlbyname("hw.optional.arm.FEAT_DPB\0");
56+
let dpb2 = _sysctlbyname("hw.optional.arm.FEAT_DPB2\0");
57+
let frintts = _sysctlbyname("hw.optional.arm.FEAT_FRINTTS\0");
58+
let i8mm = _sysctlbyname("hw.optional.arm.FEAT_I8MM\0");
59+
let bf16 = _sysctlbyname("hw.optional.arm.FEAT_BF16\0");
60+
let bti = _sysctlbyname("hw.optional.arm.FEAT_BTI\0");
61+
let fcma = _sysctlbyname("hw.optional.arm.FEAT_FCMA\0");
62+
let aes = _sysctlbyname("hw.optional.arm.FEAT_AES\0");
63+
let sha1 = _sysctlbyname("hw.optional.arm.FEAT_SHA1\0");
64+
let sha2 = _sysctlbyname("hw.optional.arm.FEAT_SHA256\0");
65+
let sha3 = _sysctlbyname("hw.optional.arm.FEAT_SHA3\0");
66+
let sha512 = _sysctlbyname("hw.optional.arm.FEAT_SHA512\0");
67+
let jsconv = _sysctlbyname("hw.optional.arm.FEAT_JSCVT\0");
68+
69+
enable_feature(Feature::asimd, asimd);
70+
enable_feature(Feature::pmull, pmull);
71+
enable_feature(Feature::fp, fp);
72+
enable_feature(Feature::fp16, fp16);
73+
enable_feature(Feature::crc, crc);
74+
enable_feature(Feature::lse, lse);
75+
enable_feature(Feature::lse2, lse2);
76+
enable_feature(Feature::rdm, rdm);
77+
enable_feature(Feature::rcpc, rcpc);
78+
enable_feature(Feature::rcpc2, rcpc2);
79+
enable_feature(Feature::dotprod, dotprod);
80+
enable_feature(Feature::fhm, fhm);
81+
enable_feature(Feature::flagm, flagm);
82+
enable_feature(Feature::ssbs, ssbs);
83+
enable_feature(Feature::sb, sb);
84+
enable_feature(Feature::paca, paca);
85+
enable_feature(Feature::dpb, dpb);
86+
enable_feature(Feature::dpb2, dpb2);
87+
enable_feature(Feature::frintts, frintts);
88+
enable_feature(Feature::i8mm, i8mm);
89+
enable_feature(Feature::bf16, bf16);
90+
enable_feature(Feature::bti, bti);
91+
enable_feature(Feature::fcma, fcma);
92+
enable_feature(Feature::aes, aes);
93+
enable_feature(Feature::jsconv, jsconv);
94+
enable_feature(Feature::sha2, sha1 && sha2 && asimd);
95+
enable_feature(Feature::sha3, sha512 && sha3 && asimd);
96+
97+
value
98+
}

crates/std_detect/tests/cpu-detection.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,38 @@ fn aarch64_bsd() {
139139
println!("sha2: {:?}", is_aarch64_feature_detected!("sha2"));
140140
}
141141

142+
#[test]
143+
#[cfg(all(target_arch = "aarch64", target_os = "macos"))]
144+
fn aarch64_macos() {
145+
println!("asimd: {:?}", is_aarch64_feature_detected!("asimd"));
146+
println!("fp: {:?}", is_aarch64_feature_detected!("fp"));
147+
println!("fp16: {:?}", is_aarch64_feature_detected!("fp16"));
148+
println!("pmull: {:?}", is_aarch64_feature_detected!("pmull"));
149+
println!("crc: {:?}", is_aarch64_feature_detected!("crc"));
150+
println!("lse: {:?}", is_aarch64_feature_detected!("lse"));
151+
println!("lse2: {:?}", is_aarch64_feature_detected!("lse2"));
152+
println!("rdm: {:?}", is_aarch64_feature_detected!("rdm"));
153+
println!("rcpc: {:?}", is_aarch64_feature_detected!("rcpc"));
154+
println!("rcpc2: {:?}", is_aarch64_feature_detected!("rcpc2"));
155+
println!("dotprod: {:?}", is_aarch64_feature_detected!("dotprod"));
156+
println!("fhm: {:?}", is_aarch64_feature_detected!("fhm"));
157+
println!("flagm: {:?}", is_aarch64_feature_detected!("flagm"));
158+
println!("ssbs: {:?}", is_aarch64_feature_detected!("ssbs"));
159+
println!("sb: {:?}", is_aarch64_feature_detected!("sb"));
160+
println!("paca: {:?}", is_aarch64_feature_detected!("paca"));
161+
println!("dpb: {:?}", is_aarch64_feature_detected!("dpb"));
162+
println!("dpb2: {:?}", is_aarch64_feature_detected!("dpb2"));
163+
println!("frintts: {:?}", is_aarch64_feature_detected!("frintts"));
164+
println!("i8mm: {:?}", is_aarch64_feature_detected!("i8mm"));
165+
println!("bf16: {:?}", is_aarch64_feature_detected!("bf16"));
166+
println!("bti: {:?}", is_aarch64_feature_detected!("bti"));
167+
println!("fcma: {:?}", is_aarch64_feature_detected!("fcma"));
168+
println!("jsconv: {:?}", is_aarch64_feature_detected!("jsconv"));
169+
println!("aes: {:?}", is_aarch64_feature_detected!("aes"));
170+
println!("sha2: {:?}", is_aarch64_feature_detected!("sha2"));
171+
println!("sha3: {:?}", is_aarch64_feature_detected!("sha3"));
172+
}
173+
142174
#[test]
143175
#[cfg(all(target_arch = "powerpc", target_os = "linux"))]
144176
fn powerpc_linux() {

0 commit comments

Comments
 (0)