1pub mod scalar;
2
3#[cfg(target_arch = "x86_64")]
4pub mod x86_64;
5
6#[cfg(target_arch = "aarch64")]
7pub mod aarch64;
8
9pub mod copy;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
12pub enum CpuTier {
13 Scalar,
14 #[cfg(target_arch = "x86_64")]
15 Sse2,
16 #[cfg(target_arch = "x86_64")]
17 Bmi2,
18 #[cfg(target_arch = "x86_64")]
19 Avx2,
20 #[cfg(target_arch = "aarch64")]
21 Neon,
22}
23
24#[cfg(feature = "std")]
25static CPU_TIER: std::sync::OnceLock<CpuTier> = std::sync::OnceLock::new();
26
27#[cfg(feature = "std")]
28pub fn cpu_tier() -> CpuTier {
29 *CPU_TIER.get_or_init(detect_cpu_tier)
30}
31
32#[cfg(not(feature = "std"))]
33pub fn cpu_tier() -> CpuTier {
34 compile_time_tier()
35}
36
37#[cfg(feature = "std")]
38fn detect_cpu_tier() -> CpuTier {
39 #[cfg(target_arch = "x86_64")]
40 {
41 if std::arch::is_x86_feature_detected!("avx2")
42 && std::arch::is_x86_feature_detected!("bmi2")
43 {
44 return CpuTier::Avx2;
45 }
46 if std::arch::is_x86_feature_detected!("bmi2") {
47 return CpuTier::Bmi2;
48 }
49 if std::arch::is_x86_feature_detected!("sse2") {
50 return CpuTier::Sse2;
51 }
52 CpuTier::Scalar
53 }
54 #[cfg(target_arch = "aarch64")]
55 {
56 CpuTier::Neon
57 }
58 #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
59 {
60 CpuTier::Scalar
61 }
62}
63
64#[cfg(not(feature = "std"))]
65fn compile_time_tier() -> CpuTier {
66 #[cfg(target_arch = "x86_64")]
67 {
68 if cfg!(target_feature = "avx2") && cfg!(target_feature = "bmi2") {
69 CpuTier::Avx2
70 } else if cfg!(target_feature = "bmi2") {
71 CpuTier::Bmi2
72 } else if cfg!(target_feature = "sse2") {
73 CpuTier::Sse2
74 } else {
75 CpuTier::Scalar
76 }
77 }
78 #[cfg(target_arch = "aarch64")]
79 {
80 CpuTier::Neon
81 }
82 #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
83 {
84 CpuTier::Scalar
85 }
86}