#[macro_export]
#[doc(hidden)]
macro_rules! __unless_target_features {
($($tf:tt),+ => $body:expr ) => {
{
#[cfg(not(all($(target_feature=$tf,)*)))]
$body
#[cfg(all($(target_feature=$tf,)*))]
true
}
};
}
#[cfg(target_os = "linux")]
#[macro_export]
#[doc(hidden)]
macro_rules! __detect_target_features {
($($tf:tt),+) => {{
let hwcaps = $crate::aarch64::getauxval_hwcap();
$($crate::check!(hwcaps, $tf) & )+ true
}};
}
#[cfg(target_os = "linux")]
pub fn getauxval_hwcap() -> u64 {
unsafe { libc::getauxval(libc::AT_HWCAP) }
}
#[cfg(target_os = "macos")]
#[macro_export]
#[doc(hidden)]
macro_rules! __detect_target_features {
($($tf:tt),+) => {{
$($crate::check!($tf) & )+ true
}};
}
#[cfg(target_os = "linux")]
macro_rules! __expand_check_macro {
($(($name:tt, $hwcap:ident)),* $(,)?) => {
#[macro_export]
#[doc(hidden)]
macro_rules! check {
$(
($hwcaps:expr, $name) => {
(($hwcaps & $crate::aarch64::hwcaps::$hwcap) != 0)
};
)*
}
};
}
#[cfg(target_os = "linux")]
__expand_check_macro! {
("aes", HWCAP_AES), ("sha2", HWCAP_SHA2), ("sha3", HWCAP_SHA3), }
#[cfg(target_os = "linux")]
pub mod hwcaps {
pub const HWCAP_AES: libc::c_ulong = 1 << 3;
pub const HWCAP_NEON: libc::c_ulong = 1 << 12;
pub const HWCAP_SHA2: libc::c_ulong = 1 << 6;
pub const HWCAP_SHA3: libc::c_ulong = 1 << 17;
}
#[cfg(target_os = "macos")]
#[macro_export]
#[doc(hidden)]
macro_rules! check {
("aes") => {
true
};
("sha2") => {
true
};
("sha3") => {
unsafe { $crate::aarch64::sysctlbyname(b"hw.optional.armv8_2_sha3\0") }
};
}
#[cfg(target_os = "macos")]
pub unsafe fn sysctlbyname(name: &[u8]) -> bool {
assert_eq!(
name.last().cloned(),
Some(0),
"name is not NUL terminated: {:?}",
name
);
let mut value: u32 = 0;
let mut size = core::mem::size_of::<u32>();
let rc = libc::sysctlbyname(
name.as_ptr() as *const i8,
&mut value as *mut _ as *mut libc::c_void,
&mut size,
core::ptr::null_mut(),
0,
);
assert_eq!(size, 4, "unexpected sysctlbyname(3) result size");
assert_eq!(rc, 0, "sysctlbyname returned error code: {}", rc);
value != 0
}