]>
Commit | Line | Data |
---|---|---|
0531ce1d XL |
1 | //! `x86` and `x86_64` intrinsics. |
2 | ||
532ac7d7 | 3 | use crate::{intrinsics, marker::Sized, mem::transmute}; |
0531ce1d XL |
4 | |
5 | #[macro_use] | |
6 | mod macros; | |
7 | ||
0531ce1d XL |
8 | types! { |
9 | /// 64-bit wide integer vector type, x86-specific | |
10 | /// | |
11 | /// This type is the same as the `__m64` type defined by Intel, | |
12 | /// representing a 64-bit SIMD register. Usage of this type typically | |
13 | /// corresponds to the `mmx` target feature. | |
14 | /// | |
15 | /// Internally this type may be viewed as: | |
16 | /// | |
17 | /// * `i8x8` - eight `i8` variables packed together | |
18 | /// * `i16x4` - four `i16` variables packed together | |
19 | /// * `i32x2` - two `i32` variables packed together | |
20 | /// | |
21 | /// (as well as unsigned versions). Each intrinsic may interpret the | |
22 | /// internal bits differently, check the documentation of the intrinsic | |
23 | /// to see how it's being used. | |
24 | /// | |
25 | /// Note that this means that an instance of `__m64` typically just means | |
26 | /// a "bag of bits" which is left up to interpretation at the point of use. | |
27 | /// | |
28 | /// Most intrinsics using `__m64` are prefixed with `_mm_` and the | |
29 | /// integer types tend to correspond to suffixes like "pi8" or "pi32" (not | |
30 | /// to be confused with "epiXX", used for `__m128i`). | |
31 | /// | |
32 | /// # Examples | |
33 | /// | |
34 | /// ``` | |
83c7162d | 35 | /// # #![feature(stdsimd, mmx_target_feature)] |
0531ce1d XL |
36 | /// #[cfg(target_arch = "x86")] |
37 | /// use std::arch::x86::*; | |
38 | /// #[cfg(target_arch = "x86_64")] | |
39 | /// use std::arch::x86_64::*; | |
40 | /// | |
41 | /// # fn main() { | |
42 | /// # #[target_feature(enable = "mmx")] | |
43 | /// # unsafe fn foo() { | |
44 | /// let all_bytes_zero = _mm_setzero_si64(); | |
45 | /// let all_bytes_one = _mm_set1_pi8(1); | |
46 | /// let two_i32 = _mm_set_pi32(1, 2); | |
47 | /// # } | |
48 | /// # if is_x86_feature_detected!("mmx") { unsafe { foo() } } | |
49 | /// # } | |
50 | /// ``` | |
51 | pub struct __m64(i64); | |
52 | ||
53 | /// 128-bit wide integer vector type, x86-specific | |
54 | /// | |
55 | /// This type is the same as the `__m128i` type defined by Intel, | |
56 | /// representing a 128-bit SIMD register. Usage of this type typically | |
57 | /// corresponds to the `sse` and up target features for x86/x86_64. | |
58 | /// | |
59 | /// Internally this type may be viewed as: | |
60 | /// | |
61 | /// * `i8x16` - sixteen `i8` variables packed together | |
62 | /// * `i16x8` - eight `i16` variables packed together | |
63 | /// * `i32x4` - four `i32` variables packed together | |
64 | /// * `i64x2` - two `i64` variables packed together | |
65 | /// | |
66 | /// (as well as unsigned versions). Each intrinsic may interpret the | |
67 | /// internal bits differently, check the documentation of the intrinsic | |
68 | /// to see how it's being used. | |
69 | /// | |
70 | /// Note that this means that an instance of `__m128i` typically just means | |
71 | /// a "bag of bits" which is left up to interpretation at the point of use. | |
72 | /// | |
73 | /// Most intrinsics using `__m128i` are prefixed with `_mm_` and the | |
74 | /// integer types tend to correspond to suffixes like "epi8" or "epi32". | |
75 | /// | |
76 | /// # Examples | |
77 | /// | |
78 | /// ``` | |
0531ce1d XL |
79 | /// #[cfg(target_arch = "x86")] |
80 | /// use std::arch::x86::*; | |
81 | /// #[cfg(target_arch = "x86_64")] | |
82 | /// use std::arch::x86_64::*; | |
83 | /// | |
84 | /// # fn main() { | |
85 | /// # #[target_feature(enable = "sse2")] | |
86 | /// # unsafe fn foo() { | |
87 | /// let all_bytes_zero = _mm_setzero_si128(); | |
88 | /// let all_bytes_one = _mm_set1_epi8(1); | |
89 | /// let four_i32 = _mm_set_epi32(1, 2, 3, 4); | |
90 | /// # } | |
91 | /// # if is_x86_feature_detected!("sse2") { unsafe { foo() } } | |
92 | /// # } | |
93 | /// ``` | |
83c7162d | 94 | #[stable(feature = "simd_x86", since = "1.27.0")] |
0531ce1d XL |
95 | pub struct __m128i(i64, i64); |
96 | ||
97 | /// 128-bit wide set of four `f32` types, x86-specific | |
98 | /// | |
99 | /// This type is the same as the `__m128` type defined by Intel, | |
100 | /// representing a 128-bit SIMD register which internally is consisted of | |
101 | /// four packed `f32` instances. Usage of this type typically corresponds | |
102 | /// to the `sse` and up target features for x86/x86_64. | |
103 | /// | |
104 | /// Note that unlike `__m128i`, the integer version of the 128-bit | |
105 | /// registers, this `__m128` type has *one* interpretation. Each instance | |
106 | /// of `__m128` always corresponds to `f32x4`, or four `f32` types packed | |
107 | /// together. | |
108 | /// | |
109 | /// Most intrinsics using `__m128` are prefixed with `_mm_` and are | |
110 | /// suffixed with "ps" (or otherwise contain "ps"). Not to be confused with | |
111 | /// "pd" which is used for `__m128d`. | |
112 | /// | |
113 | /// # Examples | |
114 | /// | |
115 | /// ``` | |
0531ce1d XL |
116 | /// #[cfg(target_arch = "x86")] |
117 | /// use std::arch::x86::*; | |
118 | /// #[cfg(target_arch = "x86_64")] | |
119 | /// use std::arch::x86_64::*; | |
120 | /// | |
121 | /// # fn main() { | |
122 | /// # #[target_feature(enable = "sse")] | |
123 | /// # unsafe fn foo() { | |
124 | /// let four_zeros = _mm_setzero_ps(); | |
125 | /// let four_ones = _mm_set1_ps(1.0); | |
126 | /// let four_floats = _mm_set_ps(1.0, 2.0, 3.0, 4.0); | |
127 | /// # } | |
128 | /// # if is_x86_feature_detected!("sse") { unsafe { foo() } } | |
129 | /// # } | |
130 | /// ``` | |
83c7162d | 131 | #[stable(feature = "simd_x86", since = "1.27.0")] |
0531ce1d XL |
132 | pub struct __m128(f32, f32, f32, f32); |
133 | ||
134 | /// 128-bit wide set of two `f64` types, x86-specific | |
135 | /// | |
136 | /// This type is the same as the `__m128d` type defined by Intel, | |
137 | /// representing a 128-bit SIMD register which internally is consisted of | |
138 | /// two packed `f64` instances. Usage of this type typically corresponds | |
139 | /// to the `sse` and up target features for x86/x86_64. | |
140 | /// | |
141 | /// Note that unlike `__m128i`, the integer version of the 128-bit | |
142 | /// registers, this `__m128d` type has *one* interpretation. Each instance | |
143 | /// of `__m128d` always corresponds to `f64x2`, or two `f64` types packed | |
144 | /// together. | |
145 | /// | |
146 | /// Most intrinsics using `__m128d` are prefixed with `_mm_` and are | |
147 | /// suffixed with "pd" (or otherwise contain "pd"). Not to be confused with | |
148 | /// "ps" which is used for `__m128`. | |
149 | /// | |
150 | /// # Examples | |
151 | /// | |
152 | /// ``` | |
0531ce1d XL |
153 | /// #[cfg(target_arch = "x86")] |
154 | /// use std::arch::x86::*; | |
155 | /// #[cfg(target_arch = "x86_64")] | |
156 | /// use std::arch::x86_64::*; | |
157 | /// | |
158 | /// # fn main() { | |
159 | /// # #[target_feature(enable = "sse")] | |
160 | /// # unsafe fn foo() { | |
161 | /// let two_zeros = _mm_setzero_pd(); | |
162 | /// let two_ones = _mm_set1_pd(1.0); | |
163 | /// let two_floats = _mm_set_pd(1.0, 2.0); | |
164 | /// # } | |
165 | /// # if is_x86_feature_detected!("sse") { unsafe { foo() } } | |
166 | /// # } | |
167 | /// ``` | |
83c7162d | 168 | #[stable(feature = "simd_x86", since = "1.27.0")] |
0531ce1d XL |
169 | pub struct __m128d(f64, f64); |
170 | ||
171 | /// 256-bit wide integer vector type, x86-specific | |
172 | /// | |
173 | /// This type is the same as the `__m256i` type defined by Intel, | |
174 | /// representing a 256-bit SIMD register. Usage of this type typically | |
175 | /// corresponds to the `avx` and up target features for x86/x86_64. | |
176 | /// | |
177 | /// Internally this type may be viewed as: | |
178 | /// | |
179 | /// * `i8x32` - thirty two `i8` variables packed together | |
180 | /// * `i16x16` - sixteen `i16` variables packed together | |
181 | /// * `i32x8` - eight `i32` variables packed together | |
182 | /// * `i64x4` - four `i64` variables packed together | |
183 | /// | |
184 | /// (as well as unsigned versions). Each intrinsic may interpret the | |
185 | /// internal bits differently, check the documentation of the intrinsic | |
186 | /// to see how it's being used. | |
187 | /// | |
188 | /// Note that this means that an instance of `__m256i` typically just means | |
189 | /// a "bag of bits" which is left up to interpretation at the point of use. | |
190 | /// | |
191 | /// # Examples | |
192 | /// | |
193 | /// ``` | |
0531ce1d XL |
194 | /// #[cfg(target_arch = "x86")] |
195 | /// use std::arch::x86::*; | |
196 | /// #[cfg(target_arch = "x86_64")] | |
197 | /// use std::arch::x86_64::*; | |
198 | /// | |
199 | /// # fn main() { | |
200 | /// # #[target_feature(enable = "avx")] | |
201 | /// # unsafe fn foo() { | |
202 | /// let all_bytes_zero = _mm256_setzero_si256(); | |
203 | /// let all_bytes_one = _mm256_set1_epi8(1); | |
204 | /// let eight_i32 = _mm256_set_epi32(1, 2, 3, 4, 5, 6, 7, 8); | |
205 | /// # } | |
206 | /// # if is_x86_feature_detected!("avx") { unsafe { foo() } } | |
207 | /// # } | |
208 | /// ``` | |
83c7162d | 209 | #[stable(feature = "simd_x86", since = "1.27.0")] |
0531ce1d XL |
210 | pub struct __m256i(i64, i64, i64, i64); |
211 | ||
212 | /// 256-bit wide set of eight `f32` types, x86-specific | |
213 | /// | |
214 | /// This type is the same as the `__m256` type defined by Intel, | |
215 | /// representing a 256-bit SIMD register which internally is consisted of | |
216 | /// eight packed `f32` instances. Usage of this type typically corresponds | |
217 | /// to the `avx` and up target features for x86/x86_64. | |
218 | /// | |
219 | /// Note that unlike `__m256i`, the integer version of the 256-bit | |
220 | /// registers, this `__m256` type has *one* interpretation. Each instance | |
221 | /// of `__m256` always corresponds to `f32x8`, or eight `f32` types packed | |
222 | /// together. | |
223 | /// | |
224 | /// Most intrinsics using `__m256` are prefixed with `_mm256_` and are | |
225 | /// suffixed with "ps" (or otherwise contain "ps"). Not to be confused with | |
226 | /// "pd" which is used for `__m256d`. | |
227 | /// | |
228 | /// # Examples | |
229 | /// | |
230 | /// ``` | |
0531ce1d XL |
231 | /// #[cfg(target_arch = "x86")] |
232 | /// use std::arch::x86::*; | |
233 | /// #[cfg(target_arch = "x86_64")] | |
234 | /// use std::arch::x86_64::*; | |
235 | /// | |
236 | /// # fn main() { | |
8faf50e0 | 237 | /// # #[target_feature(enable = "avx")] |
0531ce1d XL |
238 | /// # unsafe fn foo() { |
239 | /// let eight_zeros = _mm256_setzero_ps(); | |
240 | /// let eight_ones = _mm256_set1_ps(1.0); | |
241 | /// let eight_floats = _mm256_set_ps(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0); | |
242 | /// # } | |
8faf50e0 | 243 | /// # if is_x86_feature_detected!("avx") { unsafe { foo() } } |
0531ce1d XL |
244 | /// # } |
245 | /// ``` | |
83c7162d | 246 | #[stable(feature = "simd_x86", since = "1.27.0")] |
0531ce1d XL |
247 | pub struct __m256(f32, f32, f32, f32, f32, f32, f32, f32); |
248 | ||
249 | /// 256-bit wide set of four `f64` types, x86-specific | |
250 | /// | |
251 | /// This type is the same as the `__m256d` type defined by Intel, | |
252 | /// representing a 256-bit SIMD register which internally is consisted of | |
253 | /// four packed `f64` instances. Usage of this type typically corresponds | |
254 | /// to the `avx` and up target features for x86/x86_64. | |
255 | /// | |
256 | /// Note that unlike `__m256i`, the integer version of the 256-bit | |
257 | /// registers, this `__m256d` type has *one* interpretation. Each instance | |
258 | /// of `__m256d` always corresponds to `f64x4`, or four `f64` types packed | |
259 | /// together. | |
260 | /// | |
261 | /// Most intrinsics using `__m256d` are prefixed with `_mm256_` and are | |
262 | /// suffixed with "pd" (or otherwise contain "pd"). Not to be confused with | |
263 | /// "ps" which is used for `__m256`. | |
264 | /// | |
265 | /// # Examples | |
266 | /// | |
267 | /// ``` | |
0531ce1d XL |
268 | /// #[cfg(target_arch = "x86")] |
269 | /// use std::arch::x86::*; | |
270 | /// #[cfg(target_arch = "x86_64")] | |
271 | /// use std::arch::x86_64::*; | |
272 | /// | |
273 | /// # fn main() { | |
274 | /// # #[target_feature(enable = "avx")] | |
275 | /// # unsafe fn foo() { | |
276 | /// let four_zeros = _mm256_setzero_pd(); | |
277 | /// let four_ones = _mm256_set1_pd(1.0); | |
278 | /// let four_floats = _mm256_set_pd(1.0, 2.0, 3.0, 4.0); | |
279 | /// # } | |
280 | /// # if is_x86_feature_detected!("avx") { unsafe { foo() } } | |
281 | /// # } | |
282 | /// ``` | |
83c7162d | 283 | #[stable(feature = "simd_x86", since = "1.27.0")] |
0531ce1d | 284 | pub struct __m256d(f64, f64, f64, f64); |
0731742a XL |
285 | |
286 | /// 512-bit wide integer vector type, x86-specific | |
287 | /// | |
288 | /// This type is the same as the `__m512i` type defined by Intel, | |
289 | /// representing a 512-bit SIMD register. Usage of this type typically | |
290 | /// corresponds to the `avx512*` and up target features for x86/x86_64. | |
291 | /// | |
292 | /// Internally this type may be viewed as: | |
293 | /// | |
294 | /// * `i8x64` - sixty-four `i8` variables packed together | |
295 | /// * `i16x32` - thirty-two `i16` variables packed together | |
296 | /// * `i32x16` - sixteen `i32` variables packed together | |
297 | /// * `i64x8` - eight `i64` variables packed together | |
298 | /// | |
299 | /// (as well as unsigned versions). Each intrinsic may interpret the | |
300 | /// internal bits differently, check the documentation of the intrinsic | |
301 | /// to see how it's being used. | |
302 | /// | |
303 | /// Note that this means that an instance of `__m512i` typically just means | |
304 | /// a "bag of bits" which is left up to interpretation at the point of use. | |
305 | pub struct __m512i(i64, i64, i64, i64, i64, i64, i64, i64); | |
306 | ||
307 | /// 512-bit wide set of sixteen `f32` types, x86-specific | |
308 | /// | |
309 | /// This type is the same as the `__m512` type defined by Intel, | |
310 | /// representing a 512-bit SIMD register which internally is consisted of | |
311 | /// eight packed `f32` instances. Usage of this type typically corresponds | |
312 | /// to the `avx512*` and up target features for x86/x86_64. | |
313 | /// | |
314 | /// Note that unlike `__m512i`, the integer version of the 512-bit | |
315 | /// registers, this `__m512` type has *one* interpretation. Each instance | |
316 | /// of `__m512` always corresponds to `f32x16`, or sixteen `f32` types | |
317 | /// packed together. | |
318 | /// | |
319 | /// Most intrinsics using `__m512` are prefixed with `_mm512_` and are | |
320 | /// suffixed with "ps" (or otherwise contain "ps"). Not to be confused with | |
321 | /// "pd" which is used for `__m512d`. | |
322 | pub struct __m512( | |
323 | f32, f32, f32, f32, f32, f32, f32, f32, | |
324 | f32, f32, f32, f32, f32, f32, f32, f32, | |
325 | ); | |
326 | ||
327 | /// 512-bit wide set of eight `f64` types, x86-specific | |
328 | /// | |
329 | /// This type is the same as the `__m512d` type defined by Intel, | |
330 | /// representing a 512-bit SIMD register which internally is consisted of | |
331 | /// eight packed `f64` instances. Usage of this type typically corresponds | |
332 | /// to the `avx` and up target features for x86/x86_64. | |
333 | /// | |
334 | /// Note that unlike `__m512i`, the integer version of the 512-bit | |
335 | /// registers, this `__m512d` type has *one* interpretation. Each instance | |
336 | /// of `__m512d` always corresponds to `f64x4`, or eight `f64` types packed | |
337 | /// together. | |
338 | /// | |
339 | /// Most intrinsics using `__m512d` are prefixed with `_mm512_` and are | |
340 | /// suffixed with "pd" (or otherwise contain "pd"). Not to be confused with | |
341 | /// "ps" which is used for `__m512`. | |
342 | pub struct __m512d(f64, f64, f64, f64, f64, f64, f64, f64); | |
0531ce1d XL |
343 | } |
344 | ||
0731742a XL |
345 | /// The `__mmask16` type used in AVX-512 intrinsics, a 16-bit integer |
346 | #[allow(non_camel_case_types)] | |
347 | pub type __mmask16 = i16; | |
348 | ||
0531ce1d XL |
349 | #[cfg(test)] |
350 | mod test; | |
351 | #[cfg(test)] | |
352 | pub use self::test::*; | |
353 | ||
0531ce1d | 354 | #[allow(non_camel_case_types)] |
74b04a01 XL |
355 | #[unstable(feature = "stdimd_internal", issue = "none")] |
356 | pub(crate) trait m64Ext: Sized { | |
357 | fn as_m64(self) -> __m64; | |
358 | ||
359 | #[inline] | |
360 | fn as_u8x8(self) -> crate::core_arch::simd::u8x8 { | |
361 | unsafe { transmute(self.as_m64()) } | |
362 | } | |
363 | ||
364 | #[inline] | |
365 | fn as_u16x4(self) -> crate::core_arch::simd::u16x4 { | |
366 | unsafe { transmute(self.as_m64()) } | |
367 | } | |
368 | ||
369 | #[inline] | |
370 | fn as_u32x2(self) -> crate::core_arch::simd::u32x2 { | |
371 | unsafe { transmute(self.as_m64()) } | |
372 | } | |
373 | ||
374 | #[inline] | |
375 | fn as_i8x8(self) -> crate::core_arch::simd::i8x8 { | |
376 | unsafe { transmute(self.as_m64()) } | |
377 | } | |
378 | ||
379 | #[inline] | |
380 | fn as_i16x4(self) -> crate::core_arch::simd::i16x4 { | |
381 | unsafe { transmute(self.as_m64()) } | |
382 | } | |
383 | ||
384 | #[inline] | |
385 | fn as_i32x2(self) -> crate::core_arch::simd::i32x2 { | |
386 | unsafe { transmute(self.as_m64()) } | |
387 | } | |
388 | } | |
389 | ||
390 | impl m64Ext for __m64 { | |
391 | #[inline] | |
392 | fn as_m64(self) -> Self { | |
393 | self | |
394 | } | |
395 | } | |
396 | ||
397 | #[allow(non_camel_case_types)] | |
398 | #[unstable(feature = "stdimd_internal", issue = "none")] | |
0531ce1d XL |
399 | pub(crate) trait m128iExt: Sized { |
400 | fn as_m128i(self) -> __m128i; | |
401 | ||
402 | #[inline] | |
532ac7d7 XL |
403 | fn as_u8x16(self) -> crate::core_arch::simd::u8x16 { |
404 | unsafe { transmute(self.as_m128i()) } | |
0531ce1d XL |
405 | } |
406 | ||
407 | #[inline] | |
532ac7d7 XL |
408 | fn as_u16x8(self) -> crate::core_arch::simd::u16x8 { |
409 | unsafe { transmute(self.as_m128i()) } | |
0531ce1d XL |
410 | } |
411 | ||
412 | #[inline] | |
532ac7d7 XL |
413 | fn as_u32x4(self) -> crate::core_arch::simd::u32x4 { |
414 | unsafe { transmute(self.as_m128i()) } | |
0531ce1d XL |
415 | } |
416 | ||
417 | #[inline] | |
532ac7d7 XL |
418 | fn as_u64x2(self) -> crate::core_arch::simd::u64x2 { |
419 | unsafe { transmute(self.as_m128i()) } | |
0531ce1d XL |
420 | } |
421 | ||
422 | #[inline] | |
532ac7d7 XL |
423 | fn as_i8x16(self) -> crate::core_arch::simd::i8x16 { |
424 | unsafe { transmute(self.as_m128i()) } | |
0531ce1d XL |
425 | } |
426 | ||
427 | #[inline] | |
532ac7d7 XL |
428 | fn as_i16x8(self) -> crate::core_arch::simd::i16x8 { |
429 | unsafe { transmute(self.as_m128i()) } | |
0531ce1d XL |
430 | } |
431 | ||
432 | #[inline] | |
532ac7d7 XL |
433 | fn as_i32x4(self) -> crate::core_arch::simd::i32x4 { |
434 | unsafe { transmute(self.as_m128i()) } | |
0531ce1d XL |
435 | } |
436 | ||
437 | #[inline] | |
532ac7d7 XL |
438 | fn as_i64x2(self) -> crate::core_arch::simd::i64x2 { |
439 | unsafe { transmute(self.as_m128i()) } | |
0531ce1d XL |
440 | } |
441 | } | |
442 | ||
443 | impl m128iExt for __m128i { | |
444 | #[inline] | |
445 | fn as_m128i(self) -> Self { | |
446 | self | |
447 | } | |
448 | } | |
449 | ||
0531ce1d | 450 | #[allow(non_camel_case_types)] |
74b04a01 | 451 | #[unstable(feature = "stdimd_internal", issue = "none")] |
0531ce1d XL |
452 | pub(crate) trait m256iExt: Sized { |
453 | fn as_m256i(self) -> __m256i; | |
454 | ||
455 | #[inline] | |
532ac7d7 XL |
456 | fn as_u8x32(self) -> crate::core_arch::simd::u8x32 { |
457 | unsafe { transmute(self.as_m256i()) } | |
0531ce1d XL |
458 | } |
459 | ||
460 | #[inline] | |
532ac7d7 XL |
461 | fn as_u16x16(self) -> crate::core_arch::simd::u16x16 { |
462 | unsafe { transmute(self.as_m256i()) } | |
0531ce1d XL |
463 | } |
464 | ||
465 | #[inline] | |
532ac7d7 XL |
466 | fn as_u32x8(self) -> crate::core_arch::simd::u32x8 { |
467 | unsafe { transmute(self.as_m256i()) } | |
0531ce1d XL |
468 | } |
469 | ||
470 | #[inline] | |
532ac7d7 XL |
471 | fn as_u64x4(self) -> crate::core_arch::simd::u64x4 { |
472 | unsafe { transmute(self.as_m256i()) } | |
0531ce1d XL |
473 | } |
474 | ||
475 | #[inline] | |
532ac7d7 XL |
476 | fn as_i8x32(self) -> crate::core_arch::simd::i8x32 { |
477 | unsafe { transmute(self.as_m256i()) } | |
0531ce1d XL |
478 | } |
479 | ||
480 | #[inline] | |
532ac7d7 XL |
481 | fn as_i16x16(self) -> crate::core_arch::simd::i16x16 { |
482 | unsafe { transmute(self.as_m256i()) } | |
0531ce1d XL |
483 | } |
484 | ||
485 | #[inline] | |
532ac7d7 XL |
486 | fn as_i32x8(self) -> crate::core_arch::simd::i32x8 { |
487 | unsafe { transmute(self.as_m256i()) } | |
0531ce1d XL |
488 | } |
489 | ||
490 | #[inline] | |
532ac7d7 XL |
491 | fn as_i64x4(self) -> crate::core_arch::simd::i64x4 { |
492 | unsafe { transmute(self.as_m256i()) } | |
0531ce1d XL |
493 | } |
494 | } | |
495 | ||
496 | impl m256iExt for __m256i { | |
497 | #[inline] | |
498 | fn as_m256i(self) -> Self { | |
499 | self | |
500 | } | |
501 | } | |
502 | ||
0731742a | 503 | #[allow(non_camel_case_types)] |
74b04a01 | 504 | #[unstable(feature = "stdimd_internal", issue = "none")] |
0731742a XL |
505 | pub(crate) trait m512iExt: Sized { |
506 | fn as_m512i(self) -> __m512i; | |
507 | ||
508 | #[inline] | |
532ac7d7 XL |
509 | fn as_i32x16(self) -> crate::core_arch::simd::i32x16 { |
510 | unsafe { transmute(self.as_m512i()) } | |
0731742a XL |
511 | } |
512 | } | |
513 | ||
514 | impl m512iExt for __m512i { | |
515 | #[inline] | |
516 | fn as_m512i(self) -> Self { | |
517 | self | |
518 | } | |
519 | } | |
520 | ||
0531ce1d XL |
521 | mod eflags; |
522 | pub use self::eflags::*; | |
523 | ||
0531ce1d | 524 | mod fxsr; |
0531ce1d XL |
525 | pub use self::fxsr::*; |
526 | ||
527 | mod bswap; | |
528 | pub use self::bswap::*; | |
529 | ||
530 | mod rdtsc; | |
531 | pub use self::rdtsc::*; | |
532 | ||
533 | mod cpuid; | |
534 | pub use self::cpuid::*; | |
535 | mod xsave; | |
536 | pub use self::xsave::*; | |
537 | ||
538 | mod sse; | |
539 | pub use self::sse::*; | |
540 | mod sse2; | |
541 | pub use self::sse2::*; | |
542 | mod sse3; | |
543 | pub use self::sse3::*; | |
544 | mod ssse3; | |
545 | pub use self::ssse3::*; | |
546 | mod sse41; | |
547 | pub use self::sse41::*; | |
548 | mod sse42; | |
549 | pub use self::sse42::*; | |
550 | mod avx; | |
551 | pub use self::avx::*; | |
552 | mod avx2; | |
553 | pub use self::avx2::*; | |
83c7162d XL |
554 | mod fma; |
555 | pub use self::fma::*; | |
0531ce1d XL |
556 | |
557 | mod abm; | |
558 | pub use self::abm::*; | |
83c7162d XL |
559 | mod bmi1; |
560 | pub use self::bmi1::*; | |
0531ce1d XL |
561 | |
562 | mod bmi2; | |
563 | pub use self::bmi2::*; | |
564 | ||
416331ca | 565 | #[cfg(not(stdarch_intel_sde))] |
0531ce1d | 566 | mod sse4a; |
416331ca | 567 | #[cfg(not(stdarch_intel_sde))] |
0531ce1d XL |
568 | pub use self::sse4a::*; |
569 | ||
416331ca | 570 | #[cfg(not(stdarch_intel_sde))] |
0531ce1d | 571 | mod tbm; |
416331ca | 572 | #[cfg(not(stdarch_intel_sde))] |
0531ce1d XL |
573 | pub use self::tbm::*; |
574 | ||
575 | mod mmx; | |
576 | pub use self::mmx::*; | |
577 | ||
578 | mod pclmulqdq; | |
579 | pub use self::pclmulqdq::*; | |
580 | ||
581 | mod aes; | |
582 | pub use self::aes::*; | |
583 | ||
584 | mod rdrand; | |
585 | pub use self::rdrand::*; | |
83c7162d XL |
586 | |
587 | mod sha; | |
588 | pub use self::sha::*; | |
0731742a XL |
589 | |
590 | mod adx; | |
591 | pub use self::adx::*; | |
592 | ||
593 | #[cfg(test)] | |
416331ca | 594 | use stdarch_test::assert_instr; |
0731742a XL |
595 | |
596 | /// Generates the trap instruction `UD2` | |
597 | #[cfg_attr(test, assert_instr(ud2))] | |
598 | #[inline] | |
599 | pub unsafe fn ud2() -> ! { | |
532ac7d7 | 600 | intrinsics::abort() |
0731742a XL |
601 | } |
602 | ||
603 | mod avx512f; | |
604 | pub use self::avx512f::*; | |
9fa01778 XL |
605 | |
606 | mod avx512ifma; | |
607 | pub use self::avx512ifma::*; | |
532ac7d7 XL |
608 | |
609 | mod bt; | |
610 | pub use self::bt::*; | |
416331ca XL |
611 | |
612 | mod rtm; | |
613 | pub use self::rtm::*; | |
614 | ||
615 | mod f16c; | |
616 | pub use self::f16c::*; |