1#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
2pub enum CpuTier {
3 Scalar,
4 #[cfg(target_arch = "x86_64")]
5 Bmi2,
6 #[cfg(target_arch = "x86_64")]
7 Avx2,
8}
9
10#[cfg(feature = "std")]
11static CPU_TIER: std::sync::OnceLock<CpuTier> = std::sync::OnceLock::new();
12
13#[cfg(feature = "std")]
14pub fn cpu_tier() -> CpuTier {
15 if cfg!(miri) {
16 return CpuTier::Scalar;
17 }
18 *CPU_TIER.get_or_init(detect_cpu_tier)
19}
20
21#[cfg(not(feature = "std"))]
22pub fn cpu_tier() -> CpuTier {
23 compile_time_tier()
24}
25
26#[cfg(feature = "std")]
27fn detect_cpu_tier() -> CpuTier {
28 #[cfg(target_arch = "x86_64")]
29 {
30 if std::arch::is_x86_feature_detected!("avx2")
31 && std::arch::is_x86_feature_detected!("bmi2")
32 {
33 return CpuTier::Avx2;
34 }
35 if std::arch::is_x86_feature_detected!("bmi2") {
36 return CpuTier::Bmi2;
37 }
38 CpuTier::Scalar
39 }
40 #[cfg(not(target_arch = "x86_64"))]
41 {
42 CpuTier::Scalar
43 }
44}
45
46#[cfg(not(feature = "std"))]
47fn compile_time_tier() -> CpuTier {
48 #[cfg(target_arch = "x86_64")]
49 {
50 if cfg!(target_feature = "avx2") && cfg!(target_feature = "bmi2") {
51 CpuTier::Avx2
52 } else if cfg!(target_feature = "bmi2") {
53 CpuTier::Bmi2
54 } else {
55 CpuTier::Scalar
56 }
57 }
58 #[cfg(not(target_arch = "x86_64"))]
59 {
60 CpuTier::Scalar
61 }
62}