Skip to main content

core/stdarch/crates/core_arch/src/x86/
mod.rs

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