]>
git.proxmox.com Git - rustc.git/blob - src/stdsimd/stdsimd/arch/detect/arch/x86.rs
1 //! This module implements minimal run-time feature detection for x86.
3 //! The features are detected using the `detect_features` function below.
4 //! This function uses the CPUID instruction to read the feature flags from the
5 //! CPU and encodes them in an `usize` where each bit position represents
6 //! whether a feature is available (bit is set) or unavaiable (bit is cleared).
8 //! The enum `Feature` is used to map bit positions to feature names, and the
9 //! the `__crate::arch::detect::check_for!` macro is used to map string literals (e.g.
10 //! "avx") to these bit positions (e.g. `Feature::avx`).
13 //! The run-time feature detection is performed by the
14 //! `__crate::arch::detect::check_for(Feature) -> bool` function. On its first call,
15 //! this functions queries the CPU for the available features and stores them
16 //! in a global `AtomicUsize` variable. The query is performed by just checking
17 //! whether the feature bit in this global variable is set or cleared.
19 /// A macro to test at *runtime* whether a CPU feature is available on
20 /// x86/x86-64 platforms.
22 /// This macro is provided in the standard library and will detect at runtime
23 /// whether the specified CPU feature is detected. This does *not* resolve at
24 /// compile time unless the specified feature is already enabled for the entire
25 /// crate. Runtime detection currently relies mostly on the `cpuid` instruction.
27 /// This macro only takes one argument which is a string literal of the feature
28 /// being tested for. The feature names supported are the lowercase versions of
29 /// the ones defined by Intel in [their documentation][docs].
31 /// ## Supported arguments
33 /// This macro supports the same names that `#[target_feature]` supports. Unlike
34 /// `#[target_feature]`, however, this macro does not support names separated
35 /// with a comma. Instead testing for multiple features must be done through
36 /// separate macro invocations for now.
38 /// Supported arguments are:
65 /// * `"avx512vpopcntdq"`
79 /// [docs]: https://software.intel.com/sites/landingpage/IntrinsicsGuide
81 #[stable(feature = "simd_x86", since = "1.27.0")]
82 #[allow_internal_unstable]
83 macro_rules
! is_x86_feature_detected
{
85 cfg
!(target_feature
= "aes") || $
crate::arch
::detect
::check_for(
86 $
crate::arch
::detect
::Feature
::aes
) };
88 cfg
!(target_feature
= "pclmulqdq") || $
crate::arch
::detect
::check_for(
89 $
crate::arch
::detect
::Feature
::pclmulqdq
) };
91 cfg
!(target_feature
= "rdrand") || $
crate::arch
::detect
::check_for(
92 $
crate::arch
::detect
::Feature
::rdrand
) };
94 cfg
!(target_feature
= "rdseed") || $
crate::arch
::detect
::check_for(
95 $
crate::arch
::detect
::Feature
::rdseed
) };
97 cfg
!(target_feature
= "tsc") || $
crate::arch
::detect
::check_for(
98 $
crate::arch
::detect
::Feature
::tsc
) };
100 cfg
!(target_feature
= "mmx") || $
crate::arch
::detect
::check_for(
101 $
crate::arch
::detect
::Feature
::mmx
) };
103 cfg
!(target_feature
= "sse") || $
crate::arch
::detect
::check_for(
104 $
crate::arch
::detect
::Feature
::sse
) };
106 cfg
!(target_feature
= "sse2") || $
crate::arch
::detect
::check_for(
107 $
crate::arch
::detect
::Feature
::sse2
)
110 cfg
!(target_feature
= "sse3") || $
crate::arch
::detect
::check_for(
111 $
crate::arch
::detect
::Feature
::sse3
)
114 cfg
!(target_feature
= "ssse3") || $
crate::arch
::detect
::check_for(
115 $
crate::arch
::detect
::Feature
::ssse3
)
118 cfg
!(target_feature
= "sse4.1") || $
crate::arch
::detect
::check_for(
119 $
crate::arch
::detect
::Feature
::sse4_1
)
122 cfg
!(target_feature
= "sse4.2") || $
crate::arch
::detect
::check_for(
123 $
crate::arch
::detect
::Feature
::sse4_2
)
126 cfg
!(target_feature
= "sse4a") || $
crate::arch
::detect
::check_for(
127 $
crate::arch
::detect
::Feature
::sse4a
)
130 cfg
!(target_feature
= "sha") || $
crate::arch
::detect
::check_for(
131 $
crate::arch
::detect
::Feature
::sha
)
134 cfg
!(target_feature
= "avx") || $
crate::arch
::detect
::check_for(
135 $
crate::arch
::detect
::Feature
::avx
)
138 cfg
!(target_feature
= "avx2") || $
crate::arch
::detect
::check_for(
139 $
crate::arch
::detect
::Feature
::avx2
)
142 cfg
!(target_feature
= "avx512f") || $
crate::arch
::detect
::check_for(
143 $
crate::arch
::detect
::Feature
::avx512f
)
146 cfg
!(target_feature
= "avx512cd") || $
crate::arch
::detect
::check_for(
147 $
crate::arch
::detect
::Feature
::avx512cd
)
150 cfg
!(target_feature
= "avx512er") || $
crate::arch
::detect
::check_for(
151 $
crate::arch
::detect
::Feature
::avx512er
)
154 cfg
!(target_feature
= "avx512pf") || $
crate::arch
::detect
::check_for(
155 $
crate::arch
::detect
::Feature
::avx512pf
)
158 cfg
!(target_feature
= "avx512bw") || $
crate::arch
::detect
::check_for(
159 $
crate::arch
::detect
::Feature
::avx512bw
)
162 cfg
!(target_feature
= "avx512dq") || $
crate::arch
::detect
::check_for(
163 $
crate::arch
::detect
::Feature
::avx512dq
)
166 cfg
!(target_Feature
= "avx512vl") || $
crate::arch
::detect
::check_for(
167 $
crate::arch
::detect
::Feature
::avx512vl
)
170 cfg
!(target_feature
= "avx512ifma") || $
crate::arch
::detect
::check_for(
171 $
crate::arch
::detect
::Feature
::avx512_ifma
)
174 cfg
!(target_feature
= "avx512vbmi") || $
crate::arch
::detect
::check_for(
175 $
crate::arch
::detect
::Feature
::avx512_vbmi
)
177 ("avx512vpopcntdq") => {
178 cfg
!(target_feature
= "avx512vpopcntdq") || $
crate::arch
::detect
::check_for(
179 $
crate::arch
::detect
::Feature
::avx512_vpopcntdq
)
182 cfg
!(target_feature
= "fma") || $
crate::arch
::detect
::check_for(
183 $
crate::arch
::detect
::Feature
::fma
)
186 cfg
!(target_feature
= "bmi1") || $
crate::arch
::detect
::check_for(
187 $
crate::arch
::detect
::Feature
::bmi
)
190 cfg
!(target_feature
= "bmi2") || $
crate::arch
::detect
::check_for(
191 $
crate::arch
::detect
::Feature
::bmi2
)
194 cfg
!(target_feature
= "abm") || $
crate::arch
::detect
::check_for(
195 $
crate::arch
::detect
::Feature
::abm
)
198 cfg
!(target_feature
= "lzcnt") || $
crate::arch
::detect
::check_for(
199 $
crate::arch
::detect
::Feature
::abm
)
202 cfg
!(target_feature
= "tbm") || $
crate::arch
::detect
::check_for(
203 $
crate::arch
::detect
::Feature
::tbm
)
206 cfg
!(target_feature
= "popcnt") || $
crate::arch
::detect
::check_for(
207 $
crate::arch
::detect
::Feature
::popcnt
)
210 cfg
!(target_feature
= "fxsr") || $
crate::arch
::detect
::check_for(
211 $
crate::arch
::detect
::Feature
::fxsr
)
214 cfg
!(target_feature
= "xsave") || $
crate::arch
::detect
::check_for(
215 $
crate::arch
::detect
::Feature
::xsave
)
218 cfg
!(target_feature
= "xsaveopt") || $
crate::arch
::detect
::check_for(
219 $
crate::arch
::detect
::Feature
::xsaveopt
)
222 cfg
!(target_feature
= "xsaves") || $
crate::arch
::detect
::check_for(
223 $
crate::arch
::detect
::Feature
::xsaves
)
226 cfg
!(target_feature
= "xsavec") || $
crate::arch
::detect
::check_for(
227 $
crate::arch
::detect
::Feature
::xsavec
)
230 cfg
!(target_feature
= "cmpxchg16b") || $
crate::arch
::detect
::check_for(
231 $
crate::arch
::detect
::Feature
::cmpxchg16b
)
234 cfg
!(target_feature
= "adx") || $
crate::arch
::detect
::check_for(
235 $
crate::arch
::detect
::Feature
::adx
)
238 compile_error
!(concat
!("unknown target feature: ", $t
))
242 /// X86 CPU Feature enum. Each variant denotes a position in a bitset for a
243 /// particular feature.
245 /// This is an unstable implementation detail subject to change.
246 #[allow(non_camel_case_types)]
249 #[unstable(feature = "stdsimd_internal", issue = "0")]
251 /// AES (Advanced Encryption Standard New Instructions AES-NI)
253 /// CLMUL (Carry-less Multiplication)
259 /// TSC (Time Stamp Counter)
263 /// SSE (Streaming SIMD Extensions)
265 /// SSE2 (Streaming SIMD Extensions 2)
267 /// SSE3 (Streaming SIMD Extensions 3)
269 /// SSSE3 (Supplemental Streaming SIMD Extensions 3)
271 /// SSE4.1 (Streaming SIMD Extensions 4.1)
273 /// SSE4.2 (Streaming SIMD Extensions 4.2)
275 /// SSE4a (Streaming SIMD Extensions 4a)
279 /// AVX (Advanced Vector Extensions)
281 /// AVX2 (Advanced Vector Extensions 2)
283 /// AVX-512 F (Foundation)
285 /// AVX-512 CD (Conflict Detection Instructions)
287 /// AVX-512 ER (Exponential and Reciprocal Instructions)
289 /// AVX-512 PF (Prefetch Instructions)
291 /// AVX-512 BW (Byte and Word Instructions)
293 /// AVX-512 DQ (Doubleword and Quadword)
295 /// AVX-512 VL (Vector Length Extensions)
297 /// AVX-512 IFMA (Integer Fused Multiply Add)
299 /// AVX-512 VBMI (Vector Byte Manipulation Instructions)
301 /// AVX-512 VPOPCNTDQ (Vector Population Count Doubleword and
304 /// FMA (Fused Multiply Add)
306 /// BMI1 (Bit Manipulation Instructions 1)
308 /// BMI1 (Bit Manipulation Instructions 2)
310 /// ABM (Advanced Bit Manipulation) on AMD / LZCNT (Leading Zero
313 /// TBM (Trailing Bit Manipulation)
315 /// POPCNT (Population Count)
317 /// FXSR (Floating-point context fast save and restor)
319 /// XSAVE (Save Processor Extended States)
321 /// XSAVEOPT (Save Processor Extended States Optimized)
323 /// XSAVES (Save Processor Extended States Supervisor)
325 /// XSAVEC (Save Processor Extended States Compacted)
327 /// CMPXCH16B, a 16-byte compare-and-swap instruction
329 /// ADX, Intel ADX (Multi-Precision Add-Carry Instruction Extensions)