Skip to main content

zrip_core/simd/
mod.rs

1pub mod scalar;
2
3#[cfg(all(target_arch = "x86_64", not(feature = "paranoid")))]
4pub mod x86_64;
5
6#[cfg(all(target_arch = "aarch64", not(feature = "paranoid")))]
7pub mod aarch64;
8
9#[cfg(all(target_arch = "wasm32", not(feature = "paranoid")))]
10pub mod wasm32;
11
12pub mod copy;
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
15pub enum CpuTier {
16    Scalar,
17    #[cfg(target_arch = "x86_64")]
18    Sse2,
19    #[cfg(target_arch = "x86_64")]
20    Bmi2,
21    #[cfg(target_arch = "x86_64")]
22    Avx2,
23    #[cfg(target_arch = "aarch64")]
24    Neon,
25    #[cfg(target_arch = "wasm32")]
26    Wasm32Simd128,
27}
28
29#[cfg(all(feature = "std", not(feature = "paranoid")))]
30static CPU_TIER: std::sync::OnceLock<CpuTier> = std::sync::OnceLock::new();
31
32#[cfg(feature = "paranoid")]
33pub fn cpu_tier() -> CpuTier {
34    CpuTier::Scalar
35}
36
37#[cfg(all(feature = "std", not(feature = "paranoid")))]
38pub fn cpu_tier() -> CpuTier {
39    if cfg!(miri) {
40        return CpuTier::Scalar;
41    }
42    *CPU_TIER.get_or_init(detect_cpu_tier)
43}
44
45#[cfg(all(not(feature = "std"), not(feature = "paranoid")))]
46pub fn cpu_tier() -> CpuTier {
47    compile_time_tier()
48}
49
50#[cfg(all(feature = "std", not(feature = "paranoid")))]
51fn detect_cpu_tier() -> CpuTier {
52    #[cfg(target_arch = "x86_64")]
53    {
54        if std::arch::is_x86_feature_detected!("avx2")
55            && std::arch::is_x86_feature_detected!("bmi2")
56        {
57            return CpuTier::Avx2;
58        }
59        if std::arch::is_x86_feature_detected!("bmi2") {
60            return CpuTier::Bmi2;
61        }
62        if std::arch::is_x86_feature_detected!("sse2") {
63            return CpuTier::Sse2;
64        }
65        CpuTier::Scalar
66    }
67    #[cfg(target_arch = "aarch64")]
68    {
69        CpuTier::Neon
70    }
71    #[cfg(target_arch = "wasm32")]
72    {
73        if cfg!(target_feature = "simd128") {
74            CpuTier::Wasm32Simd128
75        } else {
76            CpuTier::Scalar
77        }
78    }
79    #[cfg(not(any(
80        target_arch = "x86_64",
81        target_arch = "aarch64",
82        target_arch = "wasm32"
83    )))]
84    {
85        CpuTier::Scalar
86    }
87}
88
89#[cfg(all(not(feature = "std"), not(feature = "paranoid")))]
90fn compile_time_tier() -> CpuTier {
91    #[cfg(target_arch = "x86_64")]
92    {
93        if cfg!(target_feature = "avx2") && cfg!(target_feature = "bmi2") {
94            CpuTier::Avx2
95        } else if cfg!(target_feature = "bmi2") {
96            CpuTier::Bmi2
97        } else if cfg!(target_feature = "sse2") {
98            CpuTier::Sse2
99        } else {
100            CpuTier::Scalar
101        }
102    }
103    #[cfg(target_arch = "aarch64")]
104    {
105        CpuTier::Neon
106    }
107    #[cfg(target_arch = "wasm32")]
108    {
109        if cfg!(target_feature = "simd128") {
110            CpuTier::Wasm32Simd128
111        } else {
112            CpuTier::Scalar
113        }
114    }
115    #[cfg(not(any(
116        target_arch = "x86_64",
117        target_arch = "aarch64",
118        target_arch = "wasm32"
119    )))]
120    {
121        CpuTier::Scalar
122    }
123}