libcrux_platform/
lib.rs

1//! High-level functions to detect available CPU features
2//! at runtime on supported processor architectures and
3//! operation systems
4
5#![no_std]
6
7// Use std for tests
8#[cfg(test)]
9#[macro_use]
10extern crate std;
11
12#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), not(hax)))]
13mod x86;
14
15#[cfg(all(target_arch = "aarch64", target_os = "linux", not(hax)))]
16mod linux_arm;
17#[cfg(all(target_arch = "aarch64", target_os = "macos", not(hax)))]
18mod macos_arm;
19
20#[cfg(test)]
21mod test;
22
23pub use platform::*;
24
25#[cfg(hax)]
26mod platform {
27    pub fn simd128_support() -> bool {
28        false
29    }
30    pub fn simd256_support() -> bool {
31        false
32    }
33    pub fn x25519_support() -> bool {
34        false
35    }
36    pub fn bmi2_adx_support() -> bool {
37        false
38    }
39    pub fn pmull_support() -> bool {
40        false
41    }
42    pub fn adv_simd_support() -> bool {
43        false
44    }
45    pub fn aes_ni_support() -> bool {
46        false
47    }
48    pub fn sha256_support() -> bool {
49        false
50    }
51}
52
53#[cfg(not(hax))]
54mod platform {
55    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
56    use super::x86::{self as cpu_id, Feature};
57
58    // TODO: Check for z14 or z15
59    pub fn simd128_support() -> bool {
60        #[cfg(target_arch = "aarch64")]
61        {
62            // All AArch64 supports NEON / AdvSIMD
63            true
64        }
65
66        #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
67        {
68            cpu_id::supported(Feature::sse2)
69                && cpu_id::supported(Feature::sse3)
70                && cpu_id::supported(Feature::sse4_1)
71                && cpu_id::supported(Feature::avx)
72        }
73
74        #[cfg(not(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64")))]
75        {
76            false
77        }
78    }
79
80    pub fn simd256_support() -> bool {
81        #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
82        return cpu_id::supported(Feature::avx2);
83
84        #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
85        false
86    }
87
88    pub fn x25519_support() -> bool {
89        #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
90        return cpu_id::supported(Feature::bmi2) && cpu_id::supported(Feature::adx);
91
92        #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
93        false
94    }
95
96    pub fn bmi2_adx_support() -> bool {
97        #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
98        return cpu_id::supported(Feature::bmi2) && cpu_id::supported(Feature::adx);
99
100        #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
101        false
102    }
103
104    /// Check whether p(cl)mull is supported
105    pub fn pmull_support() -> bool {
106        #[cfg(all(target_arch = "aarch64", target_os = "macos"))]
107        {
108            use crate::macos_arm::*;
109            pmull()
110        }
111
112        #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
113        {
114            cpu_id::supported(Feature::pclmulqdq)
115        }
116
117        #[cfg(all(target_arch = "aarch64", target_os = "linux"))]
118        {
119            use crate::linux_arm::*;
120            pmull()
121        }
122
123        #[cfg(not(any(
124            all(target_arch = "aarch64", any(target_os = "linux", target_os = "macos")),
125            target_arch = "x86",
126            target_arch = "x86_64"
127        )))]
128        {
129            false
130        }
131    }
132
133    /// Check whether advanced SIMD features are supported
134    pub fn adv_simd_support() -> bool {
135        #[cfg(target_arch = "aarch64")]
136        {
137            // All AArch64 supports NEON / AdvSIMD
138            true
139        }
140
141        #[cfg(not(target_arch = "aarch64"))]
142        {
143            false
144        }
145    }
146
147    /// Check whether AES is supported
148    pub fn aes_ni_support() -> bool {
149        #[cfg(all(target_arch = "aarch64", target_os = "macos"))]
150        {
151            use crate::macos_arm::*;
152            aes()
153        }
154
155        #[cfg(all(target_arch = "aarch64", target_os = "linux"))]
156        {
157            use crate::linux_arm::*;
158            aes()
159        }
160
161        #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
162        {
163            cpu_id::supported(Feature::avx)
164                && cpu_id::supported(Feature::sse)
165                && cpu_id::supported(Feature::aes)
166                && cpu_id::supported(Feature::pclmulqdq)
167                && cpu_id::supported(Feature::movbe)
168        }
169
170        #[cfg(not(any(
171            all(target_arch = "aarch64", any(target_os = "linux", target_os = "macos")),
172            target_arch = "x86",
173            target_arch = "x86_64"
174        )))]
175        {
176            false
177        }
178    }
179
180    /// Check whether SHA256 is supported
181    pub fn sha256_support() -> bool {
182        #[cfg(all(target_arch = "aarch64", target_os = "macos"))]
183        {
184            use crate::macos_arm::*;
185            sha256()
186        }
187
188        #[cfg(all(target_arch = "aarch64", target_os = "linux"))]
189        {
190            use crate::linux_arm::*;
191            sha256()
192        }
193
194        #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
195        {
196            cpu_id::supported(Feature::sha)
197        }
198
199        #[cfg(not(any(
200            all(target_arch = "aarch64", any(target_os = "linux", target_os = "macos")),
201            target_arch = "x86",
202            target_arch = "x86_64"
203        )))]
204        {
205            false
206        }
207    }
208}