1 | //! `x86` and `x86_64` intrinsics. |
2 | |
3 | use crate::mem::transmute; |
4 | |
5 | #[macro_use ] |
6 | mod macros; |
7 | |
8 | types! { |
9 | #![stable (feature = "simd_x86" , since = "1.27.0" )] |
10 | |
11 | /// 128-bit wide integer vector type, x86-specific |
12 | /// |
13 | /// This type is the same as the `__m128i` type defined by Intel, |
14 | /// representing a 128-bit SIMD register. Usage of this type typically |
15 | /// corresponds to the `sse` and up target features for x86/x86_64. |
16 | /// |
17 | /// Internally this type may be viewed as: |
18 | /// |
19 | /// * `i8x16` - sixteen `i8` variables packed together |
20 | /// * `i16x8` - eight `i16` variables packed together |
21 | /// * `i32x4` - four `i32` variables packed together |
22 | /// * `i64x2` - two `i64` variables packed together |
23 | /// |
24 | /// (as well as unsigned versions). Each intrinsic may interpret the |
25 | /// internal bits differently, check the documentation of the intrinsic |
26 | /// to see how it's being used. |
27 | /// |
28 | /// The in-memory representation of this type is the same as the one of an |
29 | /// equivalent array (i.e. the in-memory order of elements is the same, and |
30 | /// there is no padding); however, the alignment is different and equal to |
31 | /// the size of the type. Note that the ABI for function calls may *not* be |
32 | /// the same. |
33 | /// |
34 | /// Note that this means that an instance of `__m128i` typically just means |
35 | /// a "bag of bits" which is left up to interpretation at the point of use. |
36 | /// |
37 | /// Most intrinsics using `__m128i` are prefixed with `_mm_` and the |
38 | /// integer types tend to correspond to suffixes like "epi8" or "epi32". |
39 | /// |
40 | /// # Examples |
41 | /// |
42 | /// ``` |
43 | /// #[cfg(target_arch = "x86")] |
44 | /// use std::arch::x86::*; |
45 | /// #[cfg(target_arch = "x86_64")] |
46 | /// use std::arch::x86_64::*; |
47 | /// |
48 | /// # fn main() { |
49 | /// # #[target_feature(enable = "sse2")] |
50 | /// # #[allow(unused_unsafe)] // temporary, to unstick CI |
51 | /// # unsafe fn foo() { unsafe { |
52 | /// let all_bytes_zero = _mm_setzero_si128(); |
53 | /// let all_bytes_one = _mm_set1_epi8(1); |
54 | /// let four_i32 = _mm_set_epi32(1, 2, 3, 4); |
55 | /// # }} |
56 | /// # if is_x86_feature_detected!("sse2") { unsafe { foo() } } |
57 | /// # } |
58 | /// ``` |
59 | pub struct __m128i(2 x i64); |
60 | |
61 | /// 128-bit wide set of four `f32` types, x86-specific |
62 | /// |
63 | /// This type is the same as the `__m128` type defined by Intel, |
64 | /// representing a 128-bit SIMD register which internally is consisted of |
65 | /// four packed `f32` instances. Usage of this type typically corresponds |
66 | /// to the `sse` and up target features for x86/x86_64. |
67 | /// |
68 | /// Note that unlike `__m128i`, the integer version of the 128-bit |
69 | /// registers, this `__m128` type has *one* interpretation. Each instance |
70 | /// of `__m128` always corresponds to `f32x4`, or four `f32` types packed |
71 | /// together. |
72 | /// |
73 | /// The in-memory representation of this type is the same as the one of an |
74 | /// equivalent array (i.e. the in-memory order of elements is the same, and |
75 | /// there is no padding); however, the alignment is different and equal to |
76 | /// the size of the type. Note that the ABI for function calls may *not* be |
77 | /// the same. |
78 | /// |
79 | /// Most intrinsics using `__m128` are prefixed with `_mm_` and are |
80 | /// suffixed with "ps" (or otherwise contain "ps"). Not to be confused with |
81 | /// "pd" which is used for `__m128d`. |
82 | /// |
83 | /// # Examples |
84 | /// |
85 | /// ``` |
86 | /// #[cfg(target_arch = "x86")] |
87 | /// use std::arch::x86::*; |
88 | /// #[cfg(target_arch = "x86_64")] |
89 | /// use std::arch::x86_64::*; |
90 | /// |
91 | /// # fn main() { |
92 | /// # #[target_feature(enable = "sse")] |
93 | /// # #[allow(unused_unsafe)] // temporary, to unstick CI |
94 | /// # unsafe fn foo() { unsafe { |
95 | /// let four_zeros = _mm_setzero_ps(); |
96 | /// let four_ones = _mm_set1_ps(1.0); |
97 | /// let four_floats = _mm_set_ps(1.0, 2.0, 3.0, 4.0); |
98 | /// # }} |
99 | /// # if is_x86_feature_detected!("sse") { unsafe { foo() } } |
100 | /// # } |
101 | /// ``` |
102 | pub struct __m128(4 x f32); |
103 | |
104 | /// 128-bit wide set of two `f64` types, x86-specific |
105 | /// |
106 | /// This type is the same as the `__m128d` type defined by Intel, |
107 | /// representing a 128-bit SIMD register which internally is consisted of |
108 | /// two packed `f64` instances. Usage of this type typically corresponds |
109 | /// to the `sse` and up target features for x86/x86_64. |
110 | /// |
111 | /// Note that unlike `__m128i`, the integer version of the 128-bit |
112 | /// registers, this `__m128d` type has *one* interpretation. Each instance |
113 | /// of `__m128d` always corresponds to `f64x2`, or two `f64` types packed |
114 | /// together. |
115 | /// |
116 | /// The in-memory representation of this type is the same as the one of an |
117 | /// equivalent array (i.e. the in-memory order of elements is the same, and |
118 | /// there is no padding); however, the alignment is different and equal to |
119 | /// the size of the type. Note that the ABI for function calls may *not* be |
120 | /// the same. |
121 | /// |
122 | /// Most intrinsics using `__m128d` are prefixed with `_mm_` and are |
123 | /// suffixed with "pd" (or otherwise contain "pd"). Not to be confused with |
124 | /// "ps" which is used for `__m128`. |
125 | /// |
126 | /// # Examples |
127 | /// |
128 | /// ``` |
129 | /// #[cfg(target_arch = "x86")] |
130 | /// use std::arch::x86::*; |
131 | /// #[cfg(target_arch = "x86_64")] |
132 | /// use std::arch::x86_64::*; |
133 | /// |
134 | /// # fn main() { |
135 | /// # #[target_feature(enable = "sse2")] |
136 | /// # #[allow(unused_unsafe)] // temporary, to unstick CI |
137 | /// # unsafe fn foo() { unsafe { |
138 | /// let two_zeros = _mm_setzero_pd(); |
139 | /// let two_ones = _mm_set1_pd(1.0); |
140 | /// let two_floats = _mm_set_pd(1.0, 2.0); |
141 | /// # }} |
142 | /// # if is_x86_feature_detected!("sse2") { unsafe { foo() } } |
143 | /// # } |
144 | /// ``` |
145 | pub struct __m128d(2 x f64); |
146 | |
147 | /// 256-bit wide integer vector type, x86-specific |
148 | /// |
149 | /// This type is the same as the `__m256i` type defined by Intel, |
150 | /// representing a 256-bit SIMD register. Usage of this type typically |
151 | /// corresponds to the `avx` and up target features for x86/x86_64. |
152 | /// |
153 | /// Internally this type may be viewed as: |
154 | /// |
155 | /// * `i8x32` - thirty two `i8` variables packed together |
156 | /// * `i16x16` - sixteen `i16` variables packed together |
157 | /// * `i32x8` - eight `i32` variables packed together |
158 | /// * `i64x4` - four `i64` variables packed together |
159 | /// |
160 | /// (as well as unsigned versions). Each intrinsic may interpret the |
161 | /// internal bits differently, check the documentation of the intrinsic |
162 | /// to see how it's being used. |
163 | /// |
164 | /// The in-memory representation of this type is the same as the one of an |
165 | /// equivalent array (i.e. the in-memory order of elements is the same, and |
166 | /// there is no padding); however, the alignment is different and equal to |
167 | /// the size of the type. Note that the ABI for function calls may *not* be |
168 | /// the same. |
169 | /// |
170 | /// Note that this means that an instance of `__m256i` typically just means |
171 | /// a "bag of bits" which is left up to interpretation at the point of use. |
172 | /// |
173 | /// # Examples |
174 | /// |
175 | /// ``` |
176 | /// #[cfg(target_arch = "x86")] |
177 | /// use std::arch::x86::*; |
178 | /// #[cfg(target_arch = "x86_64")] |
179 | /// use std::arch::x86_64::*; |
180 | /// |
181 | /// # fn main() { |
182 | /// # #[target_feature(enable = "avx")] |
183 | /// # #[allow(unused_unsafe)] // temporary, to unstick CI |
184 | /// # unsafe fn foo() { unsafe { |
185 | /// let all_bytes_zero = _mm256_setzero_si256(); |
186 | /// let all_bytes_one = _mm256_set1_epi8(1); |
187 | /// let eight_i32 = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); |
188 | /// # }} |
189 | /// # if is_x86_feature_detected!("avx") { unsafe { foo() } } |
190 | /// # } |
191 | /// ``` |
192 | pub struct __m256i(4 x i64); |
193 | |
194 | /// 256-bit wide set of eight `f32` types, x86-specific |
195 | /// |
196 | /// This type is the same as the `__m256` type defined by Intel, |
197 | /// representing a 256-bit SIMD register which internally is consisted of |
198 | /// eight packed `f32` instances. Usage of this type typically corresponds |
199 | /// to the `avx` and up target features for x86/x86_64. |
200 | /// |
201 | /// Note that unlike `__m256i`, the integer version of the 256-bit |
202 | /// registers, this `__m256` type has *one* interpretation. Each instance |
203 | /// of `__m256` always corresponds to `f32x8`, or eight `f32` types packed |
204 | /// together. |
205 | /// |
206 | /// The in-memory representation of this type is the same as the one of an |
207 | /// equivalent array (i.e. the in-memory order of elements is the same, and |
208 | /// there is no padding between two consecutive elements); however, the |
209 | /// alignment is different and equal to the size of the type. Note that the |
210 | /// ABI for function calls may *not* be the same. |
211 | /// |
212 | /// Most intrinsics using `__m256` are prefixed with `_mm256_` and are |
213 | /// suffixed with "ps" (or otherwise contain "ps"). Not to be confused with |
214 | /// "pd" which is used for `__m256d`. |
215 | /// |
216 | /// # Examples |
217 | /// |
218 | /// ``` |
219 | /// #[cfg(target_arch = "x86")] |
220 | /// use std::arch::x86::*; |
221 | /// #[cfg(target_arch = "x86_64")] |
222 | /// use std::arch::x86_64::*; |
223 | /// |
224 | /// # fn main() { |
225 | /// # #[target_feature(enable = "avx")] |
226 | /// # #[allow(unused_unsafe)] // temporary, to unstick CI |
227 | /// # unsafe fn foo() { unsafe { |
228 | /// let eight_zeros = _mm256_setzero_ps(); |
229 | /// let eight_ones = _mm256_set1_ps(1.0); |
230 | /// let eight_floats = _mm256_set_ps(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); |
231 | /// # }} |
232 | /// # if is_x86_feature_detected!("avx") { unsafe { foo() } } |
233 | /// # } |
234 | /// ``` |
235 | pub struct __m256(8 x f32); |
236 | |
237 | /// 256-bit wide set of four `f64` types, x86-specific |
238 | /// |
239 | /// This type is the same as the `__m256d` type defined by Intel, |
240 | /// representing a 256-bit SIMD register which internally is consisted of |
241 | /// four packed `f64` instances. Usage of this type typically corresponds |
242 | /// to the `avx` and up target features for x86/x86_64. |
243 | /// |
244 | /// Note that unlike `__m256i`, the integer version of the 256-bit |
245 | /// registers, this `__m256d` type has *one* interpretation. Each instance |
246 | /// of `__m256d` always corresponds to `f64x4`, or four `f64` types packed |
247 | /// together. |
248 | /// |
249 | /// The in-memory representation of this type is the same as the one of an |
250 | /// equivalent array (i.e. the in-memory order of elements is the same, and |
251 | /// there is no padding); however, the alignment is different and equal to |
252 | /// the size of the type. Note that the ABI for function calls may *not* be |
253 | /// the same. |
254 | /// |
255 | /// Most intrinsics using `__m256d` are prefixed with `_mm256_` and are |
256 | /// suffixed with "pd" (or otherwise contain "pd"). Not to be confused with |
257 | /// "ps" which is used for `__m256`. |
258 | /// |
259 | /// # Examples |
260 | /// |
261 | /// ``` |
262 | /// #[cfg(target_arch = "x86")] |
263 | /// use std::arch::x86::*; |
264 | /// #[cfg(target_arch = "x86_64")] |
265 | /// use std::arch::x86_64::*; |
266 | /// |
267 | /// # fn main() { |
268 | /// # #[target_feature(enable = "avx")] |
269 | /// # #[allow(unused_unsafe)] // temporary, to unstick CI |
270 | /// # unsafe fn foo() { unsafe { |
271 | /// let four_zeros = _mm256_setzero_pd(); |
272 | /// let four_ones = _mm256_set1_pd(1.0); |
273 | /// let four_floats = _mm256_set_pd(1.0, 2.0, 3.0, 4.0); |
274 | /// # }} |
275 | /// # if is_x86_feature_detected!("avx") { unsafe { foo() } } |
276 | /// # } |
277 | /// ``` |
278 | pub struct __m256d(4 x f64); |
279 | } |
280 | |
281 | types! { |
282 | #![stable (feature = "simd_avx512_types" , since = "1.72.0" )] |
283 | |
284 | /// 512-bit wide integer vector type, x86-specific |
285 | /// |
286 | /// This type is the same as the `__m512i` type defined by Intel, |
287 | /// representing a 512-bit SIMD register. Usage of this type typically |
288 | /// corresponds to the `avx512*` and up target features for x86/x86_64. |
289 | /// |
290 | /// Internally this type may be viewed as: |
291 | /// |
292 | /// * `i8x64` - sixty-four `i8` variables packed together |
293 | /// * `i16x32` - thirty-two `i16` variables packed together |
294 | /// * `i32x16` - sixteen `i32` variables packed together |
295 | /// * `i64x8` - eight `i64` variables packed together |
296 | /// |
297 | /// (as well as unsigned versions). Each intrinsic may interpret the |
298 | /// internal bits differently, check the documentation of the intrinsic |
299 | /// to see how it's being used. |
300 | /// |
301 | /// The in-memory representation of this type is the same as the one of an |
302 | /// equivalent array (i.e. the in-memory order of elements is the same, and |
303 | /// there is no padding); however, the alignment is different and equal to |
304 | /// the size of the type. Note that the ABI for function calls may *not* be |
305 | /// the same. |
306 | /// |
307 | /// Note that this means that an instance of `__m512i` typically just means |
308 | /// a "bag of bits" which is left up to interpretation at the point of use. |
309 | pub struct __m512i(8 x i64); |
310 | |
311 | /// 512-bit wide set of sixteen `f32` types, x86-specific |
312 | /// |
313 | /// This type is the same as the `__m512` type defined by Intel, |
314 | /// representing a 512-bit SIMD register which internally is consisted of |
315 | /// eight packed `f32` instances. Usage of this type typically corresponds |
316 | /// to the `avx512*` and up target features for x86/x86_64. |
317 | /// |
318 | /// Note that unlike `__m512i`, the integer version of the 512-bit |
319 | /// registers, this `__m512` type has *one* interpretation. Each instance |
320 | /// of `__m512` always corresponds to `f32x16`, or sixteen `f32` types |
321 | /// packed together. |
322 | /// |
323 | /// The in-memory representation of this type is the same as the one of an |
324 | /// equivalent array (i.e. the in-memory order of elements is the same, and |
325 | /// there is no padding between two consecutive elements); however, the |
326 | /// alignment is different and equal to the size of the type. Note that the |
327 | /// ABI for function calls may *not* be the same. |
328 | /// |
329 | /// Most intrinsics using `__m512` are prefixed with `_mm512_` and are |
330 | /// suffixed with "ps" (or otherwise contain "ps"). Not to be confused with |
331 | /// "pd" which is used for `__m512d`. |
332 | pub struct __m512(16 x f32); |
333 | |
334 | /// 512-bit wide set of eight `f64` types, x86-specific |
335 | /// |
336 | /// This type is the same as the `__m512d` type defined by Intel, |
337 | /// representing a 512-bit SIMD register which internally is consisted of |
338 | /// eight packed `f64` instances. Usage of this type typically corresponds |
339 | /// to the `avx` and up target features for x86/x86_64. |
340 | /// |
341 | /// Note that unlike `__m512i`, the integer version of the 512-bit |
342 | /// registers, this `__m512d` type has *one* interpretation. Each instance |
343 | /// of `__m512d` always corresponds to `f64x4`, or eight `f64` types packed |
344 | /// together. |
345 | /// |
346 | /// The in-memory representation of this type is the same as the one of an |
347 | /// equivalent array (i.e. the in-memory order of elements is the same, and |
348 | /// there is no padding between two consecutive elements); however, the |
349 | /// alignment is different and equal to the size of the type. Note that the |
350 | /// ABI for function calls may *not* be the same. |
351 | /// |
352 | /// Most intrinsics using `__m512d` are prefixed with `_mm512_` and are |
353 | /// suffixed with "pd" (or otherwise contain "pd"). Not to be confused with |
354 | /// "ps" which is used for `__m512`. |
355 | pub struct __m512d(8 x f64); |
356 | } |
357 | |
358 | types! { |
359 | #![unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
360 | |
361 | /// 128-bit wide set of eight `u16` types, x86-specific |
362 | /// |
363 | /// This type is representing a 128-bit SIMD register which internally is consisted of |
364 | /// eight packed `u16` instances. Its purpose is for bf16 related intrinsic |
365 | /// implementations. |
366 | /// |
367 | /// The in-memory representation of this type is the same as the one of an |
368 | /// equivalent array (i.e. the in-memory order of elements is the same, and |
369 | /// there is no padding); however, the alignment is different and equal to |
370 | /// the size of the type. Note that the ABI for function calls may *not* be |
371 | /// the same. |
372 | pub struct __m128bh(8 x u16); |
373 | |
374 | /// 256-bit wide set of 16 `u16` types, x86-specific |
375 | /// |
376 | /// This type is the same as the `__m256bh` type defined by Intel, |
377 | /// representing a 256-bit SIMD register which internally is consisted of |
378 | /// 16 packed `u16` instances. Its purpose is for bf16 related intrinsic |
379 | /// implementations. |
380 | /// |
381 | /// The in-memory representation of this type is the same as the one of an |
382 | /// equivalent array (i.e. the in-memory order of elements is the same, and |
383 | /// there is no padding); however, the alignment is different and equal to |
384 | /// the size of the type. Note that the ABI for function calls may *not* be |
385 | /// the same. |
386 | pub struct __m256bh(16 x u16); |
387 | |
388 | /// 512-bit wide set of 32 `u16` types, x86-specific |
389 | /// |
390 | /// This type is the same as the `__m512bh` type defined by Intel, |
391 | /// representing a 512-bit SIMD register which internally is consisted of |
392 | /// 32 packed `u16` instances. Its purpose is for bf16 related intrinsic |
393 | /// implementations. |
394 | /// |
395 | /// The in-memory representation of this type is the same as the one of an |
396 | /// equivalent array (i.e. the in-memory order of elements is the same, and |
397 | /// there is no padding); however, the alignment is different and equal to |
398 | /// the size of the type. Note that the ABI for function calls may *not* be |
399 | /// the same. |
400 | pub struct __m512bh(32 x u16); |
401 | } |
402 | |
403 | types! { |
404 | #![unstable (feature = "stdarch_x86_avx512_f16" , issue = "127213" )] |
405 | |
406 | /// 128-bit wide set of 8 `f16` types, x86-specific |
407 | /// |
408 | /// This type is the same as the `__m128h` type defined by Intel, |
409 | /// representing a 128-bit SIMD register which internally is consisted of |
410 | /// 8 packed `f16` instances. its purpose is for f16 related intrinsic |
411 | /// implementations. |
412 | /// |
413 | /// The in-memory representation of this type is the same as the one of an |
414 | /// equivalent array (i.e. the in-memory order of elements is the same, and |
415 | /// there is no padding); however, the alignment is different and equal to |
416 | /// the size of the type. Note that the ABI for function calls may *not* be |
417 | /// the same. |
418 | pub struct __m128h(8 x f16); |
419 | |
420 | /// 256-bit wide set of 16 `f16` types, x86-specific |
421 | /// |
422 | /// This type is the same as the `__m256h` type defined by Intel, |
423 | /// representing a 256-bit SIMD register which internally is consisted of |
424 | /// 16 packed `f16` instances. its purpose is for f16 related intrinsic |
425 | /// implementations. |
426 | /// |
427 | /// The in-memory representation of this type is the same as the one of an |
428 | /// equivalent array (i.e. the in-memory order of elements is the same, and |
429 | /// there is no padding); however, the alignment is different and equal to |
430 | /// the size of the type. Note that the ABI for function calls may *not* be |
431 | /// the same. |
432 | pub struct __m256h(16 x f16); |
433 | |
434 | /// 512-bit wide set of 32 `f16` types, x86-specific |
435 | /// |
436 | /// This type is the same as the `__m512h` type defined by Intel, |
437 | /// representing a 512-bit SIMD register which internally is consisted of |
438 | /// 32 packed `f16` instances. its purpose is for f16 related intrinsic |
439 | /// implementations. |
440 | /// |
441 | /// The in-memory representation of this type is the same as the one of an |
442 | /// equivalent array (i.e. the in-memory order of elements is the same, and |
443 | /// there is no padding); however, the alignment is different and equal to |
444 | /// the size of the type. Note that the ABI for function calls may *not* be |
445 | /// the same. |
446 | pub struct __m512h(32 x f16); |
447 | } |
448 | |
449 | /// The BFloat16 type used in AVX-512 intrinsics. |
450 | #[repr (transparent)] |
451 | #[derive (Copy, Clone, Debug)] |
452 | #[allow (non_camel_case_types)] |
453 | #[unstable (feature = "stdarch_x86_avx512_bf16" , issue = "127356" )] |
454 | pub struct bf16(u16); |
455 | |
456 | impl bf16 { |
457 | /// Raw transmutation from `u16` |
458 | #[inline ] |
459 | #[must_use ] |
460 | #[unstable (feature = "stdarch_x86_avx512_bf16" , issue = "127356" )] |
461 | pub const fn from_bits(bits: u16) -> bf16 { |
462 | bf16(bits) |
463 | } |
464 | |
465 | /// Raw transmutation to `u16` |
466 | #[inline ] |
467 | #[must_use = "this returns the result of the operation, without modifying the original" ] |
468 | #[unstable (feature = "stdarch_x86_avx512_bf16" , issue = "127356" )] |
469 | pub const fn to_bits(self) -> u16 { |
470 | self.0 |
471 | } |
472 | } |
473 | |
474 | /// The `__mmask64` type used in AVX-512 intrinsics, a 64-bit integer |
475 | #[allow (non_camel_case_types)] |
476 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
477 | pub type __mmask64 = u64; |
478 | |
479 | /// The `__mmask32` type used in AVX-512 intrinsics, a 32-bit integer |
480 | #[allow (non_camel_case_types)] |
481 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
482 | pub type __mmask32 = u32; |
483 | |
484 | /// The `__mmask16` type used in AVX-512 intrinsics, a 16-bit integer |
485 | #[allow (non_camel_case_types)] |
486 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
487 | pub type __mmask16 = u16; |
488 | |
489 | /// The `__mmask8` type used in AVX-512 intrinsics, a 8-bit integer |
490 | #[allow (non_camel_case_types)] |
491 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
492 | pub type __mmask8 = u8; |
493 | |
494 | /// The `_MM_CMPINT_ENUM` type used to specify comparison operations in AVX-512 intrinsics. |
495 | #[allow (non_camel_case_types)] |
496 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
497 | pub type _MM_CMPINT_ENUM = i32; |
498 | |
499 | /// The `MM_MANTISSA_NORM_ENUM` type used to specify mantissa normalized operations in AVX-512 intrinsics. |
500 | #[allow (non_camel_case_types)] |
501 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
502 | pub type _MM_MANTISSA_NORM_ENUM = i32; |
503 | |
504 | /// The `MM_MANTISSA_SIGN_ENUM` type used to specify mantissa signed operations in AVX-512 intrinsics. |
505 | #[allow (non_camel_case_types)] |
506 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
507 | pub type _MM_MANTISSA_SIGN_ENUM = i32; |
508 | |
509 | /// The `MM_PERM_ENUM` type used to specify shuffle operations in AVX-512 intrinsics. |
510 | #[allow (non_camel_case_types)] |
511 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
512 | pub type _MM_PERM_ENUM = i32; |
513 | |
514 | #[cfg (test)] |
515 | mod test; |
516 | #[cfg (test)] |
517 | pub use self::test::*; |
518 | |
519 | macro_rules! as_transmute { |
520 | ($from:ty => $($name:ident -> $to:ident),* $(,)?) => { |
521 | impl $from {$( |
522 | #[inline] |
523 | pub(crate) fn $name(self) -> crate::core_arch::simd::$to { |
524 | unsafe { transmute(self) } |
525 | } |
526 | )*} |
527 | }; |
528 | } |
529 | |
530 | as_transmute!(__m128i => |
531 | as_u8x16 -> u8x16, |
532 | as_u16x8 -> u16x8, |
533 | as_u32x4 -> u32x4, |
534 | as_u64x2 -> u64x2, |
535 | as_i8x16 -> i8x16, |
536 | as_i16x8 -> i16x8, |
537 | as_i32x4 -> i32x4, |
538 | as_i64x2 -> i64x2, |
539 | ); |
540 | as_transmute!(__m256i => |
541 | as_u8x32 -> u8x32, |
542 | as_u16x16 -> u16x16, |
543 | as_u32x8 -> u32x8, |
544 | as_u64x4 -> u64x4, |
545 | as_i8x32 -> i8x32, |
546 | as_i16x16 -> i16x16, |
547 | as_i32x8 -> i32x8, |
548 | as_i64x4 -> i64x4, |
549 | ); |
550 | as_transmute!(__m512i => |
551 | as_u8x64 -> u8x64, |
552 | as_u16x32 -> u16x32, |
553 | as_u32x16 -> u32x16, |
554 | as_u64x8 -> u64x8, |
555 | as_i8x64 -> i8x64, |
556 | as_i16x32 -> i16x32, |
557 | as_i32x16 -> i32x16, |
558 | as_i64x8 -> i64x8, |
559 | ); |
560 | |
561 | as_transmute!(__m128 => as_f32x4 -> f32x4); |
562 | as_transmute!(__m128d => as_f64x2 -> f64x2); |
563 | as_transmute!(__m256 => as_f32x8 -> f32x8); |
564 | as_transmute!(__m256d => as_f64x4 -> f64x4); |
565 | as_transmute!(__m512 => as_f32x16 -> f32x16); |
566 | as_transmute!(__m512d => as_f64x8 -> f64x8); |
567 | |
568 | as_transmute!(__m128bh => |
569 | as_u16x8 -> u16x8, |
570 | as_u32x4 -> u32x4, |
571 | as_i16x8 -> i16x8, |
572 | as_i32x4 -> i32x4, |
573 | ); |
574 | as_transmute!(__m256bh => |
575 | as_u16x16 -> u16x16, |
576 | as_u32x8 -> u32x8, |
577 | as_i16x16 -> i16x16, |
578 | as_i32x8 -> i32x8, |
579 | ); |
580 | as_transmute!(__m512bh => |
581 | as_u16x32 -> u16x32, |
582 | as_u32x16 -> u32x16, |
583 | as_i16x32 -> i16x32, |
584 | as_i32x16 -> i32x16, |
585 | ); |
586 | |
587 | as_transmute!(__m128h => as_f16x8 -> f16x8); |
588 | as_transmute!(__m256h => as_f16x16 -> f16x16); |
589 | as_transmute!(__m512h => as_f16x32 -> f16x32); |
590 | |
591 | mod eflags; |
592 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
593 | pub use self::eflags::*; |
594 | |
595 | mod fxsr; |
596 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
597 | pub use self::fxsr::*; |
598 | |
599 | mod bswap; |
600 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
601 | pub use self::bswap::*; |
602 | |
603 | mod rdtsc; |
604 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
605 | pub use self::rdtsc::*; |
606 | |
607 | mod cpuid; |
608 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
609 | pub use self::cpuid::*; |
610 | mod xsave; |
611 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
612 | pub use self::xsave::*; |
613 | |
614 | mod sse; |
615 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
616 | pub use self::sse::*; |
617 | mod sse2; |
618 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
619 | pub use self::sse2::*; |
620 | mod sse3; |
621 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
622 | pub use self::sse3::*; |
623 | mod ssse3; |
624 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
625 | pub use self::ssse3::*; |
626 | mod sse41; |
627 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
628 | pub use self::sse41::*; |
629 | mod sse42; |
630 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
631 | pub use self::sse42::*; |
632 | mod avx; |
633 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
634 | pub use self::avx::*; |
635 | mod avx2; |
636 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
637 | pub use self::avx2::*; |
638 | mod fma; |
639 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
640 | pub use self::fma::*; |
641 | |
642 | mod abm; |
643 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
644 | pub use self::abm::*; |
645 | mod bmi1; |
646 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
647 | pub use self::bmi1::*; |
648 | |
649 | mod bmi2; |
650 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
651 | pub use self::bmi2::*; |
652 | |
653 | mod sse4a; |
654 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
655 | pub use self::sse4a::*; |
656 | |
657 | mod tbm; |
658 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
659 | pub use self::tbm::*; |
660 | |
661 | mod pclmulqdq; |
662 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
663 | pub use self::pclmulqdq::*; |
664 | |
665 | mod aes; |
666 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
667 | pub use self::aes::*; |
668 | |
669 | mod rdrand; |
670 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
671 | pub use self::rdrand::*; |
672 | |
673 | mod sha; |
674 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
675 | pub use self::sha::*; |
676 | |
677 | mod adx; |
678 | #[stable (feature = "simd_x86_adx" , since = "1.33.0" )] |
679 | pub use self::adx::*; |
680 | |
681 | #[cfg (test)] |
682 | use stdarch_test::assert_instr; |
683 | |
684 | mod avx512f; |
685 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
686 | pub use self::avx512f::*; |
687 | |
688 | mod avx512bw; |
689 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
690 | pub use self::avx512bw::*; |
691 | |
692 | mod avx512cd; |
693 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
694 | pub use self::avx512cd::*; |
695 | |
696 | mod avx512dq; |
697 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
698 | pub use self::avx512dq::*; |
699 | |
700 | mod avx512ifma; |
701 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
702 | pub use self::avx512ifma::*; |
703 | |
704 | mod avx512vbmi; |
705 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
706 | pub use self::avx512vbmi::*; |
707 | |
708 | mod avx512vbmi2; |
709 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
710 | pub use self::avx512vbmi2::*; |
711 | |
712 | mod avx512vnni; |
713 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
714 | pub use self::avx512vnni::*; |
715 | |
716 | mod avx512bitalg; |
717 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
718 | pub use self::avx512bitalg::*; |
719 | |
720 | mod gfni; |
721 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
722 | pub use self::gfni::*; |
723 | |
724 | mod avx512vpopcntdq; |
725 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
726 | pub use self::avx512vpopcntdq::*; |
727 | |
728 | mod vaes; |
729 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
730 | pub use self::vaes::*; |
731 | |
732 | mod vpclmulqdq; |
733 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
734 | pub use self::vpclmulqdq::*; |
735 | |
736 | mod bt; |
737 | #[stable (feature = "simd_x86_bittest" , since = "1.55.0" )] |
738 | pub use self::bt::*; |
739 | |
740 | mod rtm; |
741 | #[unstable (feature = "stdarch_x86_rtm" , issue = "111138" )] |
742 | pub use self::rtm::*; |
743 | |
744 | mod f16c; |
745 | #[stable (feature = "x86_f16c_intrinsics" , since = "1.68.0" )] |
746 | pub use self::f16c::*; |
747 | |
748 | mod avx512bf16; |
749 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
750 | pub use self::avx512bf16::*; |
751 | |
752 | mod avxneconvert; |
753 | #[unstable (feature = "stdarch_x86_avx512" , issue = "111137" )] |
754 | pub use self::avxneconvert::*; |
755 | |
756 | mod avx512fp16; |
757 | #[unstable (feature = "stdarch_x86_avx512_f16" , issue = "127213" )] |
758 | pub use self::avx512fp16::*; |
759 | |
760 | mod kl; |
761 | #[unstable (feature = "keylocker_x86" , issue = "134813" )] |
762 | pub use self::kl::*; |
763 | |