#[cfg(target_env = "sgx")]
compile_error!("internal error: this module is not supported on this environment");
include!("common.rs");
use core::arch::x86_64::{__cpuid, _xgetbv, CpuidResult};
#[cold]
fn _detect(info: &mut CpuInfo) {
#[allow(unused_unsafe)] let CpuidResult { ecx: proc_info_ecx, .. } = unsafe { __cpuid(1) };
let cpu_xsave = test(proc_info_ecx, 26);
if cpu_xsave {
let cpu_osxsave = test(proc_info_ecx, 27);
if cpu_osxsave {
let xcr0 = unsafe { _xgetbv(0) };
let os_avx_support = xcr0 & 6 == 6;
if os_avx_support && test(proc_info_ecx, 28) {
info.set(CpuInfoFlag::avx);
}
}
}
}
#[allow(
clippy::alloc_instead_of_core,
clippy::std_instead_of_alloc,
clippy::std_instead_of_core,
clippy::undocumented_unsafe_blocks,
clippy::wildcard_imports
)]
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[cfg_attr(atomic_maybe_uninit_test_detect_false, ignore = "detection disabled")]
fn test_cpuid() {
#[cfg(target_vendor = "apple")]
assert_eq!(
std::is_x86_feature_detected!("avx"),
detect().avx() || cfg!(target_feature = "avx")
);
#[cfg(not(target_vendor = "apple"))]
assert_eq!(std::is_x86_feature_detected!("avx"), detect().avx());
}
}