use crate::detect::{Feature, cache};
use core::ffi::CStr;
#[inline]
fn _sysctlbyname(name: &CStr) -> 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(),
enabled_ptr,
&mut enabled_len,
core::ptr::null_mut(),
0,
)
};
match ret {
0 => enabled != 0,
_ => false,
}
}
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 fp = _sysctlbyname(c"hw.optional.floatingpoint");
let asimd = _sysctlbyname(c"hw.optional.AdvSIMD");
let crc = _sysctlbyname(c"hw.optional.armv8_crc32");
let aes = _sysctlbyname(c"hw.optional.arm.FEAT_AES");
let bf16 = _sysctlbyname(c"hw.optional.arm.FEAT_BF16");
let bti = _sysctlbyname(c"hw.optional.arm.FEAT_BTI");
let cssc = _sysctlbyname(c"hw.optional.arm.FEAT_CSSC");
let dit = _sysctlbyname(c"hw.optional.arm.FEAT_DIT");
let dpb = _sysctlbyname(c"hw.optional.arm.FEAT_DPB");
let dpb2 = _sysctlbyname(c"hw.optional.arm.FEAT_DPB2");
let dotprod = _sysctlbyname(c"hw.optional.arm.FEAT_DotProd");
let ecv = _sysctlbyname(c"hw.optional.arm.FEAT_ECV");
let fcma = _sysctlbyname(c"hw.optional.arm.FEAT_FCMA");
let fhm = _sysctlbyname(c"hw.optional.arm.FEAT_FHM");
let fp16 = _sysctlbyname(c"hw.optional.arm.FEAT_FP16");
let frintts = _sysctlbyname(c"hw.optional.arm.FEAT_FRINTTS");
let flagm = _sysctlbyname(c"hw.optional.arm.FEAT_FlagM");
let flagm2 = _sysctlbyname(c"hw.optional.arm.FEAT_FlagM2");
let hbc = _sysctlbyname(c"hw.optional.arm.FEAT_HBC");
let i8mm = _sysctlbyname(c"hw.optional.arm.FEAT_I8MM");
let jsconv = _sysctlbyname(c"hw.optional.arm.FEAT_JSCVT");
let rcpc = _sysctlbyname(c"hw.optional.arm.FEAT_LRCPC");
let rcpc2 = _sysctlbyname(c"hw.optional.arm.FEAT_LRCPC2");
let lse = _sysctlbyname(c"hw.optional.arm.FEAT_LSE");
let lse2 = _sysctlbyname(c"hw.optional.arm.FEAT_LSE2");
let pauth = _sysctlbyname(c"hw.optional.arm.FEAT_PAuth");
let pmull = _sysctlbyname(c"hw.optional.arm.FEAT_PMULL");
let rdm = _sysctlbyname(c"hw.optional.arm.FEAT_RDM");
let sb = _sysctlbyname(c"hw.optional.arm.FEAT_SB");
let sha1 = _sysctlbyname(c"hw.optional.arm.FEAT_SHA1");
let sha256 = _sysctlbyname(c"hw.optional.arm.FEAT_SHA256");
let sha3 = _sysctlbyname(c"hw.optional.arm.FEAT_SHA3");
let sha512 = _sysctlbyname(c"hw.optional.arm.FEAT_SHA512");
let sme = _sysctlbyname(c"hw.optional.arm.FEAT_SME");
let sme2 = _sysctlbyname(c"hw.optional.arm.FEAT_SME2");
let sme_f64f64 = _sysctlbyname(c"hw.optional.arm.FEAT_SME_F64F64");
let sme_i16i64 = _sysctlbyname(c"hw.optional.arm.FEAT_SME_I16I64");
let ssbs = _sysctlbyname(c"hw.optional.arm.FEAT_SSBS");
let wfxt = _sysctlbyname(c"hw.optional.arm.FEAT_WFxT");
enable_feature(Feature::aes, aes && pmull);
enable_feature(Feature::asimd, asimd);
enable_feature(Feature::bf16, bf16);
enable_feature(Feature::bti, bti);
enable_feature(Feature::crc, crc);
enable_feature(Feature::cssc, cssc);
enable_feature(Feature::dit, dit);
enable_feature(Feature::dotprod, dotprod);
enable_feature(Feature::dpb, dpb);
enable_feature(Feature::dpb2, dpb2);
enable_feature(Feature::ecv, ecv);
enable_feature(Feature::fcma, fcma);
enable_feature(Feature::fhm, fhm);
enable_feature(Feature::flagm, flagm);
enable_feature(Feature::flagm2, flagm2);
enable_feature(Feature::fp, fp);
enable_feature(Feature::fp16, fp16);
enable_feature(Feature::frintts, frintts);
enable_feature(Feature::hbc, hbc);
enable_feature(Feature::i8mm, i8mm);
enable_feature(Feature::jsconv, jsconv);
enable_feature(Feature::lse, lse);
enable_feature(Feature::lse2, lse2);
enable_feature(Feature::paca, pauth);
enable_feature(Feature::pacg, pauth);
enable_feature(Feature::pmull, aes && pmull);
enable_feature(Feature::rcpc, rcpc);
enable_feature(Feature::rcpc2, rcpc2);
enable_feature(Feature::rdm, rdm);
enable_feature(Feature::sb, sb);
enable_feature(Feature::sha2, sha1 && sha256 && asimd);
enable_feature(Feature::sha3, sha512 && sha3 && asimd);
enable_feature(Feature::sme, sme);
enable_feature(Feature::sme2, sme2);
enable_feature(Feature::sme_f64f64, sme_f64f64);
enable_feature(Feature::sme_i16i64, sme_i16i64);
enable_feature(Feature::ssbs, ssbs);
enable_feature(Feature::wfxt, wfxt);
value
}