1//! This module implements minimal run-time feature detection for x86.
2//!
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 a `usize` where each bit position represents
6//! whether a feature is available (bit is set) or unavailable (bit is cleared).
7//!
8//! The enum `Feature` is used to map bit positions to feature names, and the
9//! the `__crate::detect::check_for!` macro is used to map string literals (e.g.,
10//! "avx") to these bit positions (e.g., `Feature::avx`).
11//!
12//! The run-time feature detection is performed by the
13//! `__crate::detect::check_for(Feature) -> bool` function. On its first call,
14//! this functions queries the CPU for the available features and stores them
15//! in a global `AtomicUsize` variable. The query is performed by just checking
16//! whether the feature bit in this global variable is set or cleared.
17
18features! {
19 @TARGET: x86;
20 @CFG: any(target_arch = "x86", target_arch = "x86_64");
21 @MACRO_NAME: is_x86_feature_detected;
22 @MACRO_ATTRS:
23 /// A macro to test at *runtime* whether a CPU feature is available on
24 /// x86/x86-64 platforms.
25 ///
26 /// This macro is provided in the standard library and will detect at runtime
27 /// whether the specified CPU feature is detected. This does **not** resolve at
28 /// compile time unless the specified feature is already enabled for the entire
29 /// crate. Runtime detection currently relies mostly on the `cpuid` instruction.
30 ///
31 /// This macro only takes one argument which is a string literal of the feature
32 /// being tested for. The feature names supported are the lowercase versions of
33 /// the ones defined by Intel in [their documentation][docs].
34 ///
35 /// ## Supported arguments
36 ///
37 /// This macro supports the same names that `#[target_feature]` supports. Unlike
38 /// `#[target_feature]`, however, this macro does not support names separated
39 /// with a comma. Instead testing for multiple features must be done through
40 /// separate macro invocations for now.
41 ///
42 /// Supported arguments are:
43 ///
44 /// * `"aes"`
45 /// * `"pclmulqdq"`
46 /// * `"rdrand"`
47 /// * `"rdseed"`
48 /// * `"tsc"`
49 /// * `"mmx"`
50 /// * `"sse"`
51 /// * `"sse2"`
52 /// * `"sse3"`
53 /// * `"ssse3"`
54 /// * `"sse4.1"`
55 /// * `"sse4.2"`
56 /// * `"sse4a"`
57 /// * `"sha"`
58 /// * `"avx"`
59 /// * `"avx2"`
60 /// * `"sha512"`
61 /// * `"sm3"`
62 /// * `"sm4"`
63 /// * `"avx512f"`
64 /// * `"avx512cd"`
65 /// * `"avx512er"`
66 /// * `"avx512pf"`
67 /// * `"avx512bw"`
68 /// * `"avx512dq"`
69 /// * `"avx512vl"`
70 /// * `"avx512ifma"`
71 /// * `"avx512vbmi"`
72 /// * `"avx512vpopcntdq"`
73 /// * `"avx512vbmi2"`
74 /// * `"gfni"`
75 /// * `"vaes"`
76 /// * `"vpclmulqdq"`
77 /// * `"avx512vnni"`
78 /// * `"avx512bitalg"`
79 /// * `"avx512bf16"`
80 /// * `"avx512vp2intersect"`
81 /// * `"avx512fp16"`
82 /// * `"avxvnni"`
83 /// * `"avxifma"`
84 /// * `"avxneconvert"`
85 /// * `"avxvnniint8"`
86 /// * `"avxvnniint16"`
87 /// * `"amx-tile"`
88 /// * `"amx-int8"`
89 /// * `"amx-bf16"`
90 /// * `"amx-fp16"`
91 /// * `"amx-complex"`
92 /// * `"f16c"`
93 /// * `"fma"`
94 /// * `"bmi1"`
95 /// * `"bmi2"`
96 /// * `"abm"`
97 /// * `"lzcnt"`
98 /// * `"tbm"`
99 /// * `"popcnt"`
100 /// * `"fxsr"`
101 /// * `"xsave"`
102 /// * `"xsaveopt"`
103 /// * `"xsaves"`
104 /// * `"xsavec"`
105 /// * `"cmpxchg16b"`
106 /// * `"kl"`
107 /// * `"widekl"`
108 /// * `"adx"`
109 /// * `"rtm"`
110 /// * `"movbe"`
111 /// * `"ermsb"`
112 ///
113 /// [docs]: https://software.intel.com/sites/landingpage/IntrinsicsGuide
114 #[stable(feature = "simd_x86", since = "1.27.0")]
115 @BIND_FEATURE_NAME: "abm"; "lzcnt"; // abm is a synonym for lzcnt
116 @BIND_FEATURE_NAME: "avx512gfni"; "gfni"; #[deprecated(since = "1.67.0", note = "the `avx512gfni` feature has been renamed to `gfni`")];
117 @BIND_FEATURE_NAME: "avx512vaes"; "vaes"; #[deprecated(since = "1.67.0", note = "the `avx512vaes` feature has been renamed to `vaes`")];
118 @BIND_FEATURE_NAME: "avx512vpclmulqdq"; "vpclmulqdq"; #[deprecated(since = "1.67.0", note = "the `avx512vpclmulqdq` feature has been renamed to `vpclmulqdq`")];
119 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] aes: "aes";
120 /// AES (Advanced Encryption Standard New Instructions AES-NI)
121 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] pclmulqdq: "pclmulqdq";
122 /// CLMUL (Carry-less Multiplication)
123 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] rdrand: "rdrand";
124 /// RDRAND
125 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] rdseed: "rdseed";
126 /// RDSEED
127 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] tsc: "tsc";
128 without cfg check: true;
129 /// TSC (Time Stamp Counter)
130 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] mmx: "mmx";
131 without cfg check: true;
132 /// MMX (MultiMedia eXtensions)
133 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] sse: "sse";
134 /// SSE (Streaming SIMD Extensions)
135 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] sse2: "sse2";
136 /// SSE2 (Streaming SIMD Extensions 2)
137 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] sse3: "sse3";
138 /// SSE3 (Streaming SIMD Extensions 3)
139 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] ssse3: "ssse3";
140 /// SSSE3 (Supplemental Streaming SIMD Extensions 3)
141 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] sse4_1: "sse4.1";
142 /// SSE4.1 (Streaming SIMD Extensions 4.1)
143 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] sse4_2: "sse4.2";
144 /// SSE4.2 (Streaming SIMD Extensions 4.2)
145 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] sse4a: "sse4a";
146 /// SSE4a (Streaming SIMD Extensions 4a)
147 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] sha: "sha";
148 /// SHA
149 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx: "avx";
150 /// AVX (Advanced Vector Extensions)
151 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx2: "avx2";
152 /// AVX2 (Advanced Vector Extensions 2)
153 @FEATURE: #[unstable(feature = "sha512_sm_x86", issue = "126624")] sha512: "sha512";
154 /// SHA512
155 @FEATURE: #[unstable(feature = "sha512_sm_x86", issue = "126624")] sm3: "sm3";
156 /// SM3
157 @FEATURE: #[unstable(feature = "sha512_sm_x86", issue = "126624")] sm4: "sm4";
158 /// SM4
159 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512f: "avx512f" ;
160 /// AVX-512 F (Foundation)
161 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512cd: "avx512cd" ;
162 /// AVX-512 CD (Conflict Detection Instructions)
163 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512er: "avx512er";
164 without cfg check: true;
165 /// AVX-512 ER (Expo nential and Reciprocal Instructions)
166 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512pf: "avx512pf";
167 without cfg check: true;
168 /// AVX-512 PF (Prefetch Instructions)
169 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512bw: "avx512bw";
170 /// AVX-512 BW (Byte and Word Instructions)
171 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512dq: "avx512dq";
172 /// AVX-512 DQ (Doubleword and Quadword)
173 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512vl: "avx512vl";
174 /// AVX-512 VL (Vector Length Extensions)
175 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512ifma: "avx512ifma";
176 /// AVX-512 IFMA (Integer Fused Multiply Add)
177 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512vbmi: "avx512vbmi";
178 /// AVX-512 VBMI (Vector Byte Manipulation Instructions)
179 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512vpopcntdq: "avx512vpopcntdq";
180 /// AVX-512 VPOPCNTDQ (Vector Population Count Doubleword and
181 /// Quadword)
182 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512vbmi2: "avx512vbmi2";
183 /// AVX-512 VBMI2 (Additional byte, word, dword and qword capabilities)
184 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] gfni: "gfni";
185 /// AVX-512 GFNI (Galois Field New Instruction)
186 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] vaes: "vaes";
187 /// AVX-512 VAES (Vector AES instruction)
188 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] vpclmulqdq: "vpclmulqdq";
189 /// AVX-512 VPCLMULQDQ (Vector PCLMULQDQ instructions)
190 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512vnni: "avx512vnni";
191 /// AVX-512 VNNI (Vector Neural Network Instructions)
192 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512bitalg: "avx512bitalg";
193 /// AVX-512 BITALG (Support for VPOPCNT\[B,W\] and VPSHUFBITQMB)
194 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512bf16: "avx512bf16";
195 /// AVX-512 BF16 (BFLOAT16 instructions)
196 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512vp2intersect: "avx512vp2intersect";
197 /// AVX-512 P2INTERSECT
198 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] avx512fp16: "avx512fp16";
199 /// AVX-512 FP16 (FLOAT16 instructions)
200 @FEATURE: #[unstable(feature = "avx512_target_feature", issue = "44839")] avxifma: "avxifma";
201 /// AVX-IFMA (Integer Fused Multiply Add)
202 @FEATURE: #[unstable(feature = "avx512_target_feature", issue = "44839")] avxneconvert: "avxneconvert";
203 /// AVX-NE-CONVERT (Exceptionless Convert)
204 @FEATURE: #[unstable(feature = "avx512_target_feature", issue = "44839")] avxvnni: "avxvnni";
205 /// AVX-VNNI (Vector Neural Network Instructions)
206 @FEATURE: #[unstable(feature = "avx512_target_feature", issue = "44839")] avxvnniint16: "avxvnniint16";
207 /// AVX-VNNI_INT8 (VNNI with 16-bit Integers)
208 @FEATURE: #[unstable(feature = "avx512_target_feature", issue = "44839")] avxvnniint8: "avxvnniint8";
209 /// AVX-VNNI_INT16 (VNNI with 8-bit integers)
210 @FEATURE: #[unstable(feature = "x86_amx_intrinsics", issue = "126622")] amx_tile: "amx-tile";
211 /// AMX (Advanced Matrix Extensions) - Tile load/store
212 @FEATURE: #[unstable(feature = "x86_amx_intrinsics", issue = "126622")] amx_int8: "amx-int8";
213 /// AMX-INT8 (Operations on 8-bit integers)
214 @FEATURE: #[unstable(feature = "x86_amx_intrinsics", issue = "126622")] amx_bf16: "amx-bf16";
215 /// AMX-BF16 (BFloat16 Operations)
216 @FEATURE: #[unstable(feature = "x86_amx_intrinsics", issue = "126622")] amx_fp16: "amx-fp16";
217 /// AMX-FP16 (Float16 Operations)
218 @FEATURE: #[unstable(feature = "x86_amx_intrinsics", issue = "126622")] amx_complex: "amx-complex";
219 /// AMX-COMPLEX (Complex number Operations)
220 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] f16c: "f16c";
221 /// F16C (Conversions between IEEE-754 `binary16` and `binary32` formats)
222 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] fma: "fma";
223 /// FMA (Fused Multiply Add)
224 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] bmi1: "bmi1" ;
225 /// BMI1 (Bit Manipulation Instructions 1)
226 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] bmi2: "bmi2" ;
227 /// BMI2 (Bit Manipulation Instructions 2)
228 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] lzcnt: "lzcnt";
229 /// ABM (Advanced Bit Manipulation) / LZCNT (Leading Zero Count)
230 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] tbm: "tbm";
231 /// TBM (Trailing Bit Manipulation)
232 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] popcnt: "popcnt";
233 /// POPCNT (Population Count)
234 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] fxsr: "fxsr";
235 /// FXSR (Floating-point context fast save and restore)
236 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] xsave: "xsave";
237 /// XSAVE (Save Processor Extended States)
238 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] xsaveopt: "xsaveopt";
239 /// XSAVEOPT (Save Processor Extended States Optimized)
240 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] xsaves: "xsaves";
241 /// XSAVES (Save Processor Extended States Supervisor)
242 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] xsavec: "xsavec";
243 /// XSAVEC (Save Processor Extended States Compacted)
244 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] cmpxchg16b: "cmpxchg16b";
245 /// CMPXCH16B (16-byte compare-and-swap instruction)
246 @FEATURE: #[unstable(feature = "keylocker_x86", issue = "134813")] kl: "kl";
247 /// Intel Key Locker
248 @FEATURE: #[unstable(feature = "keylocker_x86", issue = "134813")] widekl: "widekl";
249 /// Intel Key Locker Wide
250 @FEATURE: #[stable(feature = "simd_x86_adx", since = "1.33.0")] adx: "adx";
251 /// ADX, Intel ADX (Multi-Precision Add-Carry Instruction Extensions)
252 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] rtm: "rtm";
253 /// RTM, Intel (Restricted Transactional Memory)
254 @FEATURE: #[stable(feature = "movbe_target_feature", since = "1.67.0")] movbe: "movbe";
255 /// MOVBE (Move Data After Swapping Bytes)
256 @FEATURE: #[stable(feature = "simd_x86", since = "1.27.0")] ermsb: "ermsb";
257 /// ERMSB, Enhanced REP MOVSB and STOSB
258 @FEATURE: #[unstable(feature = "xop_target_feature", issue = "127208")] xop: "xop";
259 /// XOP: eXtended Operations (AMD)
260}
261

Provided by KDAB

Privacy Policy