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::*;