Skip to main content

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

1//! Streaming SIMD Extensions 2 (SSE2)
2
3#[cfg(test)]
4use stdarch_test::assert_instr;
5
6use crate::{
7    core_arch::{simd::*, x86::*},
8    intrinsics::simd::*,
9    intrinsics::sqrtf64,
10    mem, ptr,
11};
12
13/// Provides a hint to the processor that the code sequence is a spin-wait loop.
14///
15/// This can help improve the performance and power consumption of spin-wait
16/// loops.
17///
18/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_pause)
19#[inline]
20#[cfg_attr(all(test, target_feature = "sse2"), assert_instr(pause))]
21#[stable(feature = "simd_x86", since = "1.27.0")]
22pub fn _mm_pause() {
23    // note: `pause` is guaranteed to be interpreted as a `nop` by CPUs without
24    // the SSE2 target-feature - therefore it does not require any target features
25    unsafe { pause() }
26}
27
28/// Invalidates and flushes the cache line that contains `p` from all levels of
29/// the cache hierarchy.
30///
31/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_clflush)
32///
33/// # Safety
34///
35/// Unlike the prefetch intrinsics, `CLFLUSH` is subject to all the permission
36/// checking and faults associated with a byte load, so `p` must point to a
37/// byte that is valid for reads.
38#[inline]
39#[target_feature(enable = "sse2")]
40#[cfg_attr(test, assert_instr(clflush))]
41#[stable(feature = "simd_x86", since = "1.27.0")]
42pub unsafe fn _mm_clflush(p: *const u8) {
43    clflush(p)
44}
45
46/// Performs a serializing operation on all load-from-memory instructions
47/// that were issued prior to this instruction.
48///
49/// Guarantees that every load instruction that precedes, in program order, is
50/// globally visible before any load instruction which follows the fence in
51/// program order.
52///
53/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_lfence)
54#[inline]
55#[target_feature(enable = "sse2")]
56#[cfg_attr(test, assert_instr(lfence))]
57#[stable(feature = "simd_x86", since = "1.27.0")]
58pub fn _mm_lfence() {
59    unsafe { lfence() }
60}
61
62/// Performs a serializing operation on all load-from-memory and store-to-memory
63/// instructions that were issued prior to this instruction.
64///
65/// Guarantees that every memory access that precedes, in program order, the
66/// memory fence instruction is globally visible before any memory instruction
67/// which follows the fence in program order.
68///
69/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mfence)
70#[inline]
71#[target_feature(enable = "sse2")]
72#[cfg_attr(test, assert_instr(mfence))]
73#[stable(feature = "simd_x86", since = "1.27.0")]
74pub fn _mm_mfence() {
75    unsafe { mfence() }
76}
77
78/// Adds packed 8-bit integers in `a` and `b`.
79///
80/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_add_epi8)
81#[inline]
82#[target_feature(enable = "sse2")]
83#[cfg_attr(test, assert_instr(paddb))]
84#[stable(feature = "simd_x86", since = "1.27.0")]
85#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
86pub const fn _mm_add_epi8(a: __m128i, b: __m128i) -> __m128i {
87    unsafe { transmute(simd_add(a.as_i8x16(), b.as_i8x16())) }
88}
89
90/// Adds packed 16-bit integers in `a` and `b`.
91///
92/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_add_epi16)
93#[inline]
94#[target_feature(enable = "sse2")]
95#[cfg_attr(test, assert_instr(paddw))]
96#[stable(feature = "simd_x86", since = "1.27.0")]
97#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
98pub const fn _mm_add_epi16(a: __m128i, b: __m128i) -> __m128i {
99    unsafe { transmute(simd_add(a.as_i16x8(), b.as_i16x8())) }
100}
101
102/// Adds packed 32-bit integers in `a` and `b`.
103///
104/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_add_epi32)
105#[inline]
106#[target_feature(enable = "sse2")]
107#[cfg_attr(test, assert_instr(paddd))]
108#[stable(feature = "simd_x86", since = "1.27.0")]
109#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
110pub const fn _mm_add_epi32(a: __m128i, b: __m128i) -> __m128i {
111    unsafe { transmute(simd_add(a.as_i32x4(), b.as_i32x4())) }
112}
113
114/// Adds packed 64-bit integers in `a` and `b`.
115///
116/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_add_epi64)
117#[inline]
118#[target_feature(enable = "sse2")]
119#[cfg_attr(test, assert_instr(paddq))]
120#[stable(feature = "simd_x86", since = "1.27.0")]
121#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
122pub const fn _mm_add_epi64(a: __m128i, b: __m128i) -> __m128i {
123    unsafe { transmute(simd_add(a.as_i64x2(), b.as_i64x2())) }
124}
125
126/// Adds packed 8-bit integers in `a` and `b` using saturation.
127///
128/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_adds_epi8)
129#[inline]
130#[target_feature(enable = "sse2")]
131#[cfg_attr(test, assert_instr(paddsb))]
132#[stable(feature = "simd_x86", since = "1.27.0")]
133#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
134pub const fn _mm_adds_epi8(a: __m128i, b: __m128i) -> __m128i {
135    unsafe { transmute(simd_saturating_add(a.as_i8x16(), b.as_i8x16())) }
136}
137
138/// Adds packed 16-bit integers in `a` and `b` using saturation.
139///
140/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_adds_epi16)
141#[inline]
142#[target_feature(enable = "sse2")]
143#[cfg_attr(test, assert_instr(paddsw))]
144#[stable(feature = "simd_x86", since = "1.27.0")]
145#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
146pub const fn _mm_adds_epi16(a: __m128i, b: __m128i) -> __m128i {
147    unsafe { transmute(simd_saturating_add(a.as_i16x8(), b.as_i16x8())) }
148}
149
150/// Adds packed unsigned 8-bit integers in `a` and `b` using saturation.
151///
152/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_adds_epu8)
153#[inline]
154#[target_feature(enable = "sse2")]
155#[cfg_attr(test, assert_instr(paddusb))]
156#[stable(feature = "simd_x86", since = "1.27.0")]
157#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
158pub const fn _mm_adds_epu8(a: __m128i, b: __m128i) -> __m128i {
159    unsafe { transmute(simd_saturating_add(a.as_u8x16(), b.as_u8x16())) }
160}
161
162/// Adds packed unsigned 16-bit integers in `a` and `b` using saturation.
163///
164/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_adds_epu16)
165#[inline]
166#[target_feature(enable = "sse2")]
167#[cfg_attr(test, assert_instr(paddusw))]
168#[stable(feature = "simd_x86", since = "1.27.0")]
169#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
170pub const fn _mm_adds_epu16(a: __m128i, b: __m128i) -> __m128i {
171    unsafe { transmute(simd_saturating_add(a.as_u16x8(), b.as_u16x8())) }
172}
173
174/// Averages packed unsigned 8-bit integers in `a` and `b`.
175///
176/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_avg_epu8)
177#[inline]
178#[target_feature(enable = "sse2")]
179#[cfg_attr(test, assert_instr(pavgb))]
180#[stable(feature = "simd_x86", since = "1.27.0")]
181#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
182pub const fn _mm_avg_epu8(a: __m128i, b: __m128i) -> __m128i {
183    unsafe {
184        let a = simd_cast::<_, u16x16>(a.as_u8x16());
185        let b = simd_cast::<_, u16x16>(b.as_u8x16());
186        let r = simd_shr(simd_add(simd_add(a, b), u16x16::splat(1)), u16x16::splat(1));
187        transmute(simd_cast::<_, u8x16>(r))
188    }
189}
190
191/// Averages packed unsigned 16-bit integers in `a` and `b`.
192///
193/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_avg_epu16)
194#[inline]
195#[target_feature(enable = "sse2")]
196#[cfg_attr(test, assert_instr(pavgw))]
197#[stable(feature = "simd_x86", since = "1.27.0")]
198#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
199pub const fn _mm_avg_epu16(a: __m128i, b: __m128i) -> __m128i {
200    unsafe {
201        let a = simd_cast::<_, u32x8>(a.as_u16x8());
202        let b = simd_cast::<_, u32x8>(b.as_u16x8());
203        let r = simd_shr(simd_add(simd_add(a, b), u32x8::splat(1)), u32x8::splat(1));
204        transmute(simd_cast::<_, u16x8>(r))
205    }
206}
207
208/// Multiplies and then horizontally add signed 16 bit integers in `a` and `b`.
209///
210/// Multiplies packed signed 16-bit integers in `a` and `b`, producing
211/// intermediate signed 32-bit integers. Horizontally add adjacent pairs of
212/// intermediate 32-bit integers.
213///
214/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_madd_epi16)
215#[inline]
216#[target_feature(enable = "sse2")]
217#[cfg_attr(test, assert_instr(pmaddwd))]
218#[stable(feature = "simd_x86", since = "1.27.0")]
219pub fn _mm_madd_epi16(a: __m128i, b: __m128i) -> __m128i {
220    // It's a trick used in the Adler-32 algorithm to perform a widening addition.
221    //
222    // ```rust
223    // #[target_feature(enable = "sse2")]
224    // unsafe fn widening_add(mad: __m128i) -> __m128i {
225    //     _mm_madd_epi16(mad, _mm_set1_epi16(1))
226    // }
227    // ```
228    //
229    // If we implement this using generic vector intrinsics, the optimizer
230    // will eliminate this pattern, and `pmaddwd` will no longer be emitted.
231    // For this reason, we use x86 intrinsics.
232    unsafe { transmute(pmaddwd(a.as_i16x8(), b.as_i16x8())) }
233}
234
235/// Compares packed 16-bit integers in `a` and `b`, and returns the packed
236/// maximum values.
237///
238/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_max_epi16)
239#[inline]
240#[target_feature(enable = "sse2")]
241#[cfg_attr(test, assert_instr(pmaxsw))]
242#[stable(feature = "simd_x86", since = "1.27.0")]
243#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
244pub const fn _mm_max_epi16(a: __m128i, b: __m128i) -> __m128i {
245    unsafe { simd_imax(a.as_i16x8(), b.as_i16x8()).as_m128i() }
246}
247
248/// Compares packed unsigned 8-bit integers in `a` and `b`, and returns the
249/// packed maximum values.
250///
251/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_max_epu8)
252#[inline]
253#[target_feature(enable = "sse2")]
254#[cfg_attr(test, assert_instr(pmaxub))]
255#[stable(feature = "simd_x86", since = "1.27.0")]
256#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
257pub const fn _mm_max_epu8(a: __m128i, b: __m128i) -> __m128i {
258    unsafe { simd_imax(a.as_u8x16(), b.as_u8x16()).as_m128i() }
259}
260
261/// Compares packed 16-bit integers in `a` and `b`, and returns the packed
262/// minimum values.
263///
264/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_min_epi16)
265#[inline]
266#[target_feature(enable = "sse2")]
267#[cfg_attr(test, assert_instr(pminsw))]
268#[stable(feature = "simd_x86", since = "1.27.0")]
269#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
270pub const fn _mm_min_epi16(a: __m128i, b: __m128i) -> __m128i {
271    unsafe { simd_imin(a.as_i16x8(), b.as_i16x8()).as_m128i() }
272}
273
274/// Compares packed unsigned 8-bit integers in `a` and `b`, and returns the
275/// packed minimum values.
276///
277/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_min_epu8)
278#[inline]
279#[target_feature(enable = "sse2")]
280#[cfg_attr(test, assert_instr(pminub))]
281#[stable(feature = "simd_x86", since = "1.27.0")]
282#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
283pub const fn _mm_min_epu8(a: __m128i, b: __m128i) -> __m128i {
284    unsafe { simd_imin(a.as_u8x16(), b.as_u8x16()).as_m128i() }
285}
286
287/// Multiplies the packed 16-bit integers in `a` and `b`.
288///
289/// The multiplication produces intermediate 32-bit integers, and returns the
290/// high 16 bits of the intermediate integers.
291///
292/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mulhi_epi16)
293#[inline]
294#[target_feature(enable = "sse2")]
295#[cfg_attr(test, assert_instr(pmulhw))]
296#[stable(feature = "simd_x86", since = "1.27.0")]
297#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
298pub const fn _mm_mulhi_epi16(a: __m128i, b: __m128i) -> __m128i {
299    unsafe {
300        let a = simd_cast::<_, i32x8>(a.as_i16x8());
301        let b = simd_cast::<_, i32x8>(b.as_i16x8());
302        let r = simd_shr(simd_mul(a, b), i32x8::splat(16));
303        transmute(simd_cast::<i32x8, i16x8>(r))
304    }
305}
306
307/// Multiplies the packed unsigned 16-bit integers in `a` and `b`.
308///
309/// The multiplication produces intermediate 32-bit integers, and returns the
310/// high 16 bits of the intermediate integers.
311///
312/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mulhi_epu16)
313#[inline]
314#[target_feature(enable = "sse2")]
315#[cfg_attr(test, assert_instr(pmulhuw))]
316#[stable(feature = "simd_x86", since = "1.27.0")]
317#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
318pub const fn _mm_mulhi_epu16(a: __m128i, b: __m128i) -> __m128i {
319    unsafe {
320        let a = simd_cast::<_, u32x8>(a.as_u16x8());
321        let b = simd_cast::<_, u32x8>(b.as_u16x8());
322        let r = simd_shr(simd_mul(a, b), u32x8::splat(16));
323        transmute(simd_cast::<u32x8, u16x8>(r))
324    }
325}
326
327/// Multiplies the packed 16-bit integers in `a` and `b`.
328///
329/// The multiplication produces intermediate 32-bit integers, and returns the
330/// low 16 bits of the intermediate integers.
331///
332/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mullo_epi16)
333#[inline]
334#[target_feature(enable = "sse2")]
335#[cfg_attr(test, assert_instr(pmullw))]
336#[stable(feature = "simd_x86", since = "1.27.0")]
337#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
338pub const fn _mm_mullo_epi16(a: __m128i, b: __m128i) -> __m128i {
339    unsafe { transmute(simd_mul(a.as_i16x8(), b.as_i16x8())) }
340}
341
342/// Multiplies the low unsigned 32-bit integers from each packed 64-bit element
343/// in `a` and `b`.
344///
345/// Returns the unsigned 64-bit results.
346///
347/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mul_epu32)
348#[inline]
349#[target_feature(enable = "sse2")]
350#[cfg_attr(test, assert_instr(pmuludq))]
351#[stable(feature = "simd_x86", since = "1.27.0")]
352#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
353pub const fn _mm_mul_epu32(a: __m128i, b: __m128i) -> __m128i {
354    unsafe {
355        let a = a.as_u64x2();
356        let b = b.as_u64x2();
357        let mask = u64x2::splat(u32::MAX as u64);
358        transmute(simd_mul(simd_and(a, mask), simd_and(b, mask)))
359    }
360}
361
362/// Sum the absolute differences of packed unsigned 8-bit integers.
363///
364/// Computes the absolute differences of packed unsigned 8-bit integers in `a`
365/// and `b`, then horizontally sum each consecutive 8 differences to produce
366/// two unsigned 16-bit integers, and pack these unsigned 16-bit integers in
367/// the low 16 bits of 64-bit elements returned.
368///
369/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sad_epu8)
370#[inline]
371#[target_feature(enable = "sse2")]
372#[cfg_attr(test, assert_instr(psadbw))]
373#[stable(feature = "simd_x86", since = "1.27.0")]
374pub fn _mm_sad_epu8(a: __m128i, b: __m128i) -> __m128i {
375    unsafe { transmute(psadbw(a.as_u8x16(), b.as_u8x16())) }
376}
377
378/// Subtracts packed 8-bit integers in `b` from packed 8-bit integers in `a`.
379///
380/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sub_epi8)
381#[inline]
382#[target_feature(enable = "sse2")]
383#[cfg_attr(test, assert_instr(psubb))]
384#[stable(feature = "simd_x86", since = "1.27.0")]
385#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
386pub const fn _mm_sub_epi8(a: __m128i, b: __m128i) -> __m128i {
387    unsafe { transmute(simd_sub(a.as_i8x16(), b.as_i8x16())) }
388}
389
390/// Subtracts packed 16-bit integers in `b` from packed 16-bit integers in `a`.
391///
392/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sub_epi16)
393#[inline]
394#[target_feature(enable = "sse2")]
395#[cfg_attr(test, assert_instr(psubw))]
396#[stable(feature = "simd_x86", since = "1.27.0")]
397#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
398pub const fn _mm_sub_epi16(a: __m128i, b: __m128i) -> __m128i {
399    unsafe { transmute(simd_sub(a.as_i16x8(), b.as_i16x8())) }
400}
401
402/// Subtract packed 32-bit integers in `b` from packed 32-bit integers in `a`.
403///
404/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sub_epi32)
405#[inline]
406#[target_feature(enable = "sse2")]
407#[cfg_attr(test, assert_instr(psubd))]
408#[stable(feature = "simd_x86", since = "1.27.0")]
409#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
410pub const fn _mm_sub_epi32(a: __m128i, b: __m128i) -> __m128i {
411    unsafe { transmute(simd_sub(a.as_i32x4(), b.as_i32x4())) }
412}
413
414/// Subtract packed 64-bit integers in `b` from packed 64-bit integers in `a`.
415///
416/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sub_epi64)
417#[inline]
418#[target_feature(enable = "sse2")]
419#[cfg_attr(test, assert_instr(psubq))]
420#[stable(feature = "simd_x86", since = "1.27.0")]
421#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
422pub const fn _mm_sub_epi64(a: __m128i, b: __m128i) -> __m128i {
423    unsafe { transmute(simd_sub(a.as_i64x2(), b.as_i64x2())) }
424}
425
426/// Subtract packed 8-bit integers in `b` from packed 8-bit integers in `a`
427/// using saturation.
428///
429/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_subs_epi8)
430#[inline]
431#[target_feature(enable = "sse2")]
432#[cfg_attr(test, assert_instr(psubsb))]
433#[stable(feature = "simd_x86", since = "1.27.0")]
434#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
435pub const fn _mm_subs_epi8(a: __m128i, b: __m128i) -> __m128i {
436    unsafe { transmute(simd_saturating_sub(a.as_i8x16(), b.as_i8x16())) }
437}
438
439/// Subtract packed 16-bit integers in `b` from packed 16-bit integers in `a`
440/// using saturation.
441///
442/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_subs_epi16)
443#[inline]
444#[target_feature(enable = "sse2")]
445#[cfg_attr(test, assert_instr(psubsw))]
446#[stable(feature = "simd_x86", since = "1.27.0")]
447#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
448pub const fn _mm_subs_epi16(a: __m128i, b: __m128i) -> __m128i {
449    unsafe { transmute(simd_saturating_sub(a.as_i16x8(), b.as_i16x8())) }
450}
451
452/// Subtract packed unsigned 8-bit integers in `b` from packed unsigned 8-bit
453/// integers in `a` using saturation.
454///
455/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_subs_epu8)
456#[inline]
457#[target_feature(enable = "sse2")]
458#[cfg_attr(test, assert_instr(psubusb))]
459#[stable(feature = "simd_x86", since = "1.27.0")]
460#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
461pub const fn _mm_subs_epu8(a: __m128i, b: __m128i) -> __m128i {
462    unsafe { transmute(simd_saturating_sub(a.as_u8x16(), b.as_u8x16())) }
463}
464
465/// Subtract packed unsigned 16-bit integers in `b` from packed unsigned 16-bit
466/// integers in `a` using saturation.
467///
468/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_subs_epu16)
469#[inline]
470#[target_feature(enable = "sse2")]
471#[cfg_attr(test, assert_instr(psubusw))]
472#[stable(feature = "simd_x86", since = "1.27.0")]
473#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
474pub const fn _mm_subs_epu16(a: __m128i, b: __m128i) -> __m128i {
475    unsafe { transmute(simd_saturating_sub(a.as_u16x8(), b.as_u16x8())) }
476}
477
478/// Shifts `a` left by `IMM8` bytes while shifting in zeros.
479///
480/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_slli_si128)
481#[inline]
482#[target_feature(enable = "sse2")]
483#[cfg_attr(test, assert_instr(pslldq, IMM8 = 1))]
484#[rustc_legacy_const_generics(1)]
485#[stable(feature = "simd_x86", since = "1.27.0")]
486#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
487pub const fn _mm_slli_si128<const IMM8: i32>(a: __m128i) -> __m128i {
488    static_assert_uimm_bits!(IMM8, 8);
489    unsafe { _mm_slli_si128_impl::<IMM8>(a) }
490}
491
492/// Implementation detail: converts the immediate argument of the
493/// `_mm_slli_si128` intrinsic into a compile-time constant.
494#[inline]
495#[target_feature(enable = "sse2")]
496#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
497const unsafe fn _mm_slli_si128_impl<const IMM8: i32>(a: __m128i) -> __m128i {
498    const fn mask(shift: i32, i: u32) -> u32 {
499        let shift = shift as u32 & 0xff;
500        if shift > 15 { i } else { 16 - shift + i }
501    }
502    transmute::<i8x16, _>(simd_shuffle!(
503        i8x16::ZERO,
504        a.as_i8x16(),
505        [
506            mask(IMM8, 0),
507            mask(IMM8, 1),
508            mask(IMM8, 2),
509            mask(IMM8, 3),
510            mask(IMM8, 4),
511            mask(IMM8, 5),
512            mask(IMM8, 6),
513            mask(IMM8, 7),
514            mask(IMM8, 8),
515            mask(IMM8, 9),
516            mask(IMM8, 10),
517            mask(IMM8, 11),
518            mask(IMM8, 12),
519            mask(IMM8, 13),
520            mask(IMM8, 14),
521            mask(IMM8, 15),
522        ],
523    ))
524}
525
526/// Shifts `a` left by `IMM8` bytes while shifting in zeros.
527///
528/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_bslli_si128)
529#[inline]
530#[target_feature(enable = "sse2")]
531#[cfg_attr(test, assert_instr(pslldq, IMM8 = 1))]
532#[rustc_legacy_const_generics(1)]
533#[stable(feature = "simd_x86", since = "1.27.0")]
534#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
535pub const fn _mm_bslli_si128<const IMM8: i32>(a: __m128i) -> __m128i {
536    unsafe {
537        static_assert_uimm_bits!(IMM8, 8);
538        _mm_slli_si128_impl::<IMM8>(a)
539    }
540}
541
542/// Shifts `a` right by `IMM8` bytes while shifting in zeros.
543///
544/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_bsrli_si128)
545#[inline]
546#[target_feature(enable = "sse2")]
547#[cfg_attr(test, assert_instr(psrldq, IMM8 = 1))]
548#[rustc_legacy_const_generics(1)]
549#[stable(feature = "simd_x86", since = "1.27.0")]
550#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
551pub const fn _mm_bsrli_si128<const IMM8: i32>(a: __m128i) -> __m128i {
552    unsafe {
553        static_assert_uimm_bits!(IMM8, 8);
554        _mm_srli_si128_impl::<IMM8>(a)
555    }
556}
557
558/// Shifts packed 16-bit integers in `a` left by `IMM8` while shifting in zeros.
559///
560/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_slli_epi16)
561#[inline]
562#[target_feature(enable = "sse2")]
563#[cfg_attr(test, assert_instr(psllw, IMM8 = 7))]
564#[rustc_legacy_const_generics(1)]
565#[stable(feature = "simd_x86", since = "1.27.0")]
566#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
567pub const fn _mm_slli_epi16<const IMM8: i32>(a: __m128i) -> __m128i {
568    static_assert_uimm_bits!(IMM8, 8);
569    unsafe {
570        if IMM8 >= 16 {
571            _mm_setzero_si128()
572        } else {
573            transmute(simd_shl(a.as_u16x8(), u16x8::splat(IMM8 as u16)))
574        }
575    }
576}
577
578/// Shifts packed 16-bit integers in `a` left by `count` while shifting in
579/// zeros.
580///
581/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sll_epi16)
582#[inline]
583#[target_feature(enable = "sse2")]
584#[cfg_attr(test, assert_instr(psllw))]
585#[stable(feature = "simd_x86", since = "1.27.0")]
586pub fn _mm_sll_epi16(a: __m128i, count: __m128i) -> __m128i {
587    unsafe { transmute(psllw(a.as_i16x8(), count.as_i16x8())) }
588}
589
590/// Shifts packed 32-bit integers in `a` left by `IMM8` while shifting in zeros.
591///
592/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_slli_epi32)
593#[inline]
594#[target_feature(enable = "sse2")]
595#[cfg_attr(test, assert_instr(pslld, IMM8 = 7))]
596#[rustc_legacy_const_generics(1)]
597#[stable(feature = "simd_x86", since = "1.27.0")]
598#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
599pub const fn _mm_slli_epi32<const IMM8: i32>(a: __m128i) -> __m128i {
600    static_assert_uimm_bits!(IMM8, 8);
601    unsafe {
602        if IMM8 >= 32 {
603            _mm_setzero_si128()
604        } else {
605            transmute(simd_shl(a.as_u32x4(), u32x4::splat(IMM8 as u32)))
606        }
607    }
608}
609
610/// Shifts packed 32-bit integers in `a` left by `count` while shifting in
611/// zeros.
612///
613/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sll_epi32)
614#[inline]
615#[target_feature(enable = "sse2")]
616#[cfg_attr(test, assert_instr(pslld))]
617#[stable(feature = "simd_x86", since = "1.27.0")]
618pub fn _mm_sll_epi32(a: __m128i, count: __m128i) -> __m128i {
619    unsafe { transmute(pslld(a.as_i32x4(), count.as_i32x4())) }
620}
621
622/// Shifts packed 64-bit integers in `a` left by `IMM8` while shifting in zeros.
623///
624/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_slli_epi64)
625#[inline]
626#[target_feature(enable = "sse2")]
627#[cfg_attr(test, assert_instr(psllq, IMM8 = 7))]
628#[rustc_legacy_const_generics(1)]
629#[stable(feature = "simd_x86", since = "1.27.0")]
630#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
631pub const fn _mm_slli_epi64<const IMM8: i32>(a: __m128i) -> __m128i {
632    static_assert_uimm_bits!(IMM8, 8);
633    unsafe {
634        if IMM8 >= 64 {
635            _mm_setzero_si128()
636        } else {
637            transmute(simd_shl(a.as_u64x2(), u64x2::splat(IMM8 as u64)))
638        }
639    }
640}
641
642/// Shifts packed 64-bit integers in `a` left by `count` while shifting in
643/// zeros.
644///
645/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sll_epi64)
646#[inline]
647#[target_feature(enable = "sse2")]
648#[cfg_attr(test, assert_instr(psllq))]
649#[stable(feature = "simd_x86", since = "1.27.0")]
650pub fn _mm_sll_epi64(a: __m128i, count: __m128i) -> __m128i {
651    unsafe { transmute(psllq(a.as_i64x2(), count.as_i64x2())) }
652}
653
654/// Shifts packed 16-bit integers in `a` right by `IMM8` while shifting in sign
655/// bits.
656///
657/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srai_epi16)
658#[inline]
659#[target_feature(enable = "sse2")]
660#[cfg_attr(test, assert_instr(psraw, IMM8 = 1))]
661#[rustc_legacy_const_generics(1)]
662#[stable(feature = "simd_x86", since = "1.27.0")]
663#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
664pub const fn _mm_srai_epi16<const IMM8: i32>(a: __m128i) -> __m128i {
665    static_assert_uimm_bits!(IMM8, 8);
666    unsafe { transmute(simd_shr(a.as_i16x8(), i16x8::splat(IMM8.min(15) as i16))) }
667}
668
669/// Shifts packed 16-bit integers in `a` right by `count` while shifting in sign
670/// bits.
671///
672/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sra_epi16)
673#[inline]
674#[target_feature(enable = "sse2")]
675#[cfg_attr(test, assert_instr(psraw))]
676#[stable(feature = "simd_x86", since = "1.27.0")]
677pub fn _mm_sra_epi16(a: __m128i, count: __m128i) -> __m128i {
678    unsafe { transmute(psraw(a.as_i16x8(), count.as_i16x8())) }
679}
680
681/// Shifts packed 32-bit integers in `a` right by `IMM8` while shifting in sign
682/// bits.
683///
684/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srai_epi32)
685#[inline]
686#[target_feature(enable = "sse2")]
687#[cfg_attr(test, assert_instr(psrad, IMM8 = 1))]
688#[rustc_legacy_const_generics(1)]
689#[stable(feature = "simd_x86", since = "1.27.0")]
690#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
691pub const fn _mm_srai_epi32<const IMM8: i32>(a: __m128i) -> __m128i {
692    static_assert_uimm_bits!(IMM8, 8);
693    unsafe { transmute(simd_shr(a.as_i32x4(), i32x4::splat(IMM8.min(31)))) }
694}
695
696/// Shifts packed 32-bit integers in `a` right by `count` while shifting in sign
697/// bits.
698///
699/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sra_epi32)
700#[inline]
701#[target_feature(enable = "sse2")]
702#[cfg_attr(test, assert_instr(psrad))]
703#[stable(feature = "simd_x86", since = "1.27.0")]
704pub fn _mm_sra_epi32(a: __m128i, count: __m128i) -> __m128i {
705    unsafe { transmute(psrad(a.as_i32x4(), count.as_i32x4())) }
706}
707
708/// Shifts `a` right by `IMM8` bytes while shifting in zeros.
709///
710/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srli_si128)
711#[inline]
712#[target_feature(enable = "sse2")]
713#[cfg_attr(test, assert_instr(psrldq, IMM8 = 1))]
714#[rustc_legacy_const_generics(1)]
715#[stable(feature = "simd_x86", since = "1.27.0")]
716#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
717pub const fn _mm_srli_si128<const IMM8: i32>(a: __m128i) -> __m128i {
718    static_assert_uimm_bits!(IMM8, 8);
719    unsafe { _mm_srli_si128_impl::<IMM8>(a) }
720}
721
722/// Implementation detail: converts the immediate argument of the
723/// `_mm_srli_si128` intrinsic into a compile-time constant.
724#[inline]
725#[target_feature(enable = "sse2")]
726#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
727const unsafe fn _mm_srli_si128_impl<const IMM8: i32>(a: __m128i) -> __m128i {
728    const fn mask(shift: i32, i: u32) -> u32 {
729        if (shift as u32) > 15 {
730            i + 16
731        } else {
732            i + (shift as u32)
733        }
734    }
735    let x: i8x16 = simd_shuffle!(
736        a.as_i8x16(),
737        i8x16::ZERO,
738        [
739            mask(IMM8, 0),
740            mask(IMM8, 1),
741            mask(IMM8, 2),
742            mask(IMM8, 3),
743            mask(IMM8, 4),
744            mask(IMM8, 5),
745            mask(IMM8, 6),
746            mask(IMM8, 7),
747            mask(IMM8, 8),
748            mask(IMM8, 9),
749            mask(IMM8, 10),
750            mask(IMM8, 11),
751            mask(IMM8, 12),
752            mask(IMM8, 13),
753            mask(IMM8, 14),
754            mask(IMM8, 15),
755        ],
756    );
757    transmute(x)
758}
759
760/// Shifts packed 16-bit integers in `a` right by `IMM8` while shifting in
761/// zeros.
762///
763/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srli_epi16)
764#[inline]
765#[target_feature(enable = "sse2")]
766#[cfg_attr(test, assert_instr(psrlw, IMM8 = 1))]
767#[rustc_legacy_const_generics(1)]
768#[stable(feature = "simd_x86", since = "1.27.0")]
769#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
770pub const fn _mm_srli_epi16<const IMM8: i32>(a: __m128i) -> __m128i {
771    static_assert_uimm_bits!(IMM8, 8);
772    unsafe {
773        if IMM8 >= 16 {
774            _mm_setzero_si128()
775        } else {
776            transmute(simd_shr(a.as_u16x8(), u16x8::splat(IMM8 as u16)))
777        }
778    }
779}
780
781/// Shifts packed 16-bit integers in `a` right by `count` while shifting in
782/// zeros.
783///
784/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srl_epi16)
785#[inline]
786#[target_feature(enable = "sse2")]
787#[cfg_attr(test, assert_instr(psrlw))]
788#[stable(feature = "simd_x86", since = "1.27.0")]
789pub fn _mm_srl_epi16(a: __m128i, count: __m128i) -> __m128i {
790    unsafe { transmute(psrlw(a.as_i16x8(), count.as_i16x8())) }
791}
792
793/// Shifts packed 32-bit integers in `a` right by `IMM8` while shifting in
794/// zeros.
795///
796/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srli_epi32)
797#[inline]
798#[target_feature(enable = "sse2")]
799#[cfg_attr(test, assert_instr(psrld, IMM8 = 8))]
800#[rustc_legacy_const_generics(1)]
801#[stable(feature = "simd_x86", since = "1.27.0")]
802#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
803pub const fn _mm_srli_epi32<const IMM8: i32>(a: __m128i) -> __m128i {
804    static_assert_uimm_bits!(IMM8, 8);
805    unsafe {
806        if IMM8 >= 32 {
807            _mm_setzero_si128()
808        } else {
809            transmute(simd_shr(a.as_u32x4(), u32x4::splat(IMM8 as u32)))
810        }
811    }
812}
813
814/// Shifts packed 32-bit integers in `a` right by `count` while shifting in
815/// zeros.
816///
817/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srl_epi32)
818#[inline]
819#[target_feature(enable = "sse2")]
820#[cfg_attr(test, assert_instr(psrld))]
821#[stable(feature = "simd_x86", since = "1.27.0")]
822pub fn _mm_srl_epi32(a: __m128i, count: __m128i) -> __m128i {
823    unsafe { transmute(psrld(a.as_i32x4(), count.as_i32x4())) }
824}
825
826/// Shifts packed 64-bit integers in `a` right by `IMM8` while shifting in
827/// zeros.
828///
829/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srli_epi64)
830#[inline]
831#[target_feature(enable = "sse2")]
832#[cfg_attr(test, assert_instr(psrlq, IMM8 = 1))]
833#[rustc_legacy_const_generics(1)]
834#[stable(feature = "simd_x86", since = "1.27.0")]
835#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
836pub const fn _mm_srli_epi64<const IMM8: i32>(a: __m128i) -> __m128i {
837    static_assert_uimm_bits!(IMM8, 8);
838    unsafe {
839        if IMM8 >= 64 {
840            _mm_setzero_si128()
841        } else {
842            transmute(simd_shr(a.as_u64x2(), u64x2::splat(IMM8 as u64)))
843        }
844    }
845}
846
847/// Shifts packed 64-bit integers in `a` right by `count` while shifting in
848/// zeros.
849///
850/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srl_epi64)
851#[inline]
852#[target_feature(enable = "sse2")]
853#[cfg_attr(test, assert_instr(psrlq))]
854#[stable(feature = "simd_x86", since = "1.27.0")]
855pub fn _mm_srl_epi64(a: __m128i, count: __m128i) -> __m128i {
856    unsafe { transmute(psrlq(a.as_i64x2(), count.as_i64x2())) }
857}
858
859/// Computes the bitwise AND of 128 bits (representing integer data) in `a` and
860/// `b`.
861///
862/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_and_si128)
863#[inline]
864#[target_feature(enable = "sse2")]
865#[cfg_attr(test, assert_instr(andps))]
866#[stable(feature = "simd_x86", since = "1.27.0")]
867#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
868pub const fn _mm_and_si128(a: __m128i, b: __m128i) -> __m128i {
869    unsafe { simd_and(a, b) }
870}
871
872/// Computes the bitwise NOT of 128 bits (representing integer data) in `a` and
873/// then AND with `b`.
874///
875/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_andnot_si128)
876#[inline]
877#[target_feature(enable = "sse2")]
878#[cfg_attr(test, assert_instr(andnps))]
879#[stable(feature = "simd_x86", since = "1.27.0")]
880#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
881pub const fn _mm_andnot_si128(a: __m128i, b: __m128i) -> __m128i {
882    unsafe { simd_and(simd_xor(_mm_set1_epi8(-1), a), b) }
883}
884
885/// Computes the bitwise OR of 128 bits (representing integer data) in `a` and
886/// `b`.
887///
888/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_or_si128)
889#[ferrocene::prevalidated]
890#[inline]
891#[target_feature(enable = "sse2")]
892#[cfg_attr(test, assert_instr(orps))]
893#[stable(feature = "simd_x86", since = "1.27.0")]
894#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
895pub const fn _mm_or_si128(a: __m128i, b: __m128i) -> __m128i {
896    unsafe { simd_or(a, b) }
897}
898
899/// Computes the bitwise XOR of 128 bits (representing integer data) in `a` and
900/// `b`.
901///
902/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_xor_si128)
903#[inline]
904#[target_feature(enable = "sse2")]
905#[cfg_attr(test, assert_instr(xorps))]
906#[stable(feature = "simd_x86", since = "1.27.0")]
907#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
908pub const fn _mm_xor_si128(a: __m128i, b: __m128i) -> __m128i {
909    unsafe { simd_xor(a, b) }
910}
911
912/// Compares packed 8-bit integers in `a` and `b` for equality.
913///
914/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpeq_epi8)
915#[inline]
916#[target_feature(enable = "sse2")]
917#[cfg_attr(test, assert_instr(pcmpeqb))]
918#[stable(feature = "simd_x86", since = "1.27.0")]
919#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
920pub const fn _mm_cmpeq_epi8(a: __m128i, b: __m128i) -> __m128i {
921    unsafe { transmute::<i8x16, _>(simd_eq(a.as_i8x16(), b.as_i8x16())) }
922}
923
924/// Compares packed 16-bit integers in `a` and `b` for equality.
925///
926/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpeq_epi16)
927#[inline]
928#[target_feature(enable = "sse2")]
929#[cfg_attr(test, assert_instr(pcmpeqw))]
930#[stable(feature = "simd_x86", since = "1.27.0")]
931#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
932pub const fn _mm_cmpeq_epi16(a: __m128i, b: __m128i) -> __m128i {
933    unsafe { transmute::<i16x8, _>(simd_eq(a.as_i16x8(), b.as_i16x8())) }
934}
935
936/// Compares packed 32-bit integers in `a` and `b` for equality.
937///
938/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpeq_epi32)
939#[inline]
940#[target_feature(enable = "sse2")]
941#[cfg_attr(test, assert_instr(pcmpeqd))]
942#[stable(feature = "simd_x86", since = "1.27.0")]
943#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
944pub const fn _mm_cmpeq_epi32(a: __m128i, b: __m128i) -> __m128i {
945    unsafe { transmute::<i32x4, _>(simd_eq(a.as_i32x4(), b.as_i32x4())) }
946}
947
948/// Compares packed 8-bit integers in `a` and `b` for greater-than.
949///
950/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpgt_epi8)
951#[inline]
952#[target_feature(enable = "sse2")]
953#[cfg_attr(test, assert_instr(pcmpgtb))]
954#[stable(feature = "simd_x86", since = "1.27.0")]
955#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
956pub const fn _mm_cmpgt_epi8(a: __m128i, b: __m128i) -> __m128i {
957    unsafe { transmute::<i8x16, _>(simd_gt(a.as_i8x16(), b.as_i8x16())) }
958}
959
960/// Compares packed 16-bit integers in `a` and `b` for greater-than.
961///
962/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpgt_epi16)
963#[inline]
964#[target_feature(enable = "sse2")]
965#[cfg_attr(test, assert_instr(pcmpgtw))]
966#[stable(feature = "simd_x86", since = "1.27.0")]
967#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
968pub const fn _mm_cmpgt_epi16(a: __m128i, b: __m128i) -> __m128i {
969    unsafe { transmute::<i16x8, _>(simd_gt(a.as_i16x8(), b.as_i16x8())) }
970}
971
972/// Compares packed 32-bit integers in `a` and `b` for greater-than.
973///
974/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpgt_epi32)
975#[inline]
976#[target_feature(enable = "sse2")]
977#[cfg_attr(test, assert_instr(pcmpgtd))]
978#[stable(feature = "simd_x86", since = "1.27.0")]
979#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
980pub const fn _mm_cmpgt_epi32(a: __m128i, b: __m128i) -> __m128i {
981    unsafe { transmute::<i32x4, _>(simd_gt(a.as_i32x4(), b.as_i32x4())) }
982}
983
984/// Compares packed 8-bit integers in `a` and `b` for less-than.
985///
986/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmplt_epi8)
987#[inline]
988#[target_feature(enable = "sse2")]
989#[cfg_attr(test, assert_instr(pcmpgtb))]
990#[stable(feature = "simd_x86", since = "1.27.0")]
991#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
992pub const fn _mm_cmplt_epi8(a: __m128i, b: __m128i) -> __m128i {
993    unsafe { transmute::<i8x16, _>(simd_lt(a.as_i8x16(), b.as_i8x16())) }
994}
995
996/// Compares packed 16-bit integers in `a` and `b` for less-than.
997///
998/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmplt_epi16)
999#[inline]
1000#[target_feature(enable = "sse2")]
1001#[cfg_attr(test, assert_instr(pcmpgtw))]
1002#[stable(feature = "simd_x86", since = "1.27.0")]
1003#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1004pub const fn _mm_cmplt_epi16(a: __m128i, b: __m128i) -> __m128i {
1005    unsafe { transmute::<i16x8, _>(simd_lt(a.as_i16x8(), b.as_i16x8())) }
1006}
1007
1008/// Compares packed 32-bit integers in `a` and `b` for less-than.
1009///
1010/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmplt_epi32)
1011#[inline]
1012#[target_feature(enable = "sse2")]
1013#[cfg_attr(test, assert_instr(pcmpgtd))]
1014#[stable(feature = "simd_x86", since = "1.27.0")]
1015#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1016pub const fn _mm_cmplt_epi32(a: __m128i, b: __m128i) -> __m128i {
1017    unsafe { transmute::<i32x4, _>(simd_lt(a.as_i32x4(), b.as_i32x4())) }
1018}
1019
1020/// Converts the lower two packed 32-bit integers in `a` to packed
1021/// double-precision (64-bit) floating-point elements.
1022///
1023/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtepi32_pd)
1024#[inline]
1025#[target_feature(enable = "sse2")]
1026#[cfg_attr(test, assert_instr(cvtdq2pd))]
1027#[stable(feature = "simd_x86", since = "1.27.0")]
1028#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1029pub const fn _mm_cvtepi32_pd(a: __m128i) -> __m128d {
1030    unsafe {
1031        let a = a.as_i32x4();
1032        simd_cast::<i32x2, __m128d>(simd_shuffle!(a, a, [0, 1]))
1033    }
1034}
1035
1036/// Returns `a` with its lower element replaced by `b` after converting it to
1037/// an `f64`.
1038///
1039/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtsi32_sd)
1040#[inline]
1041#[target_feature(enable = "sse2")]
1042#[cfg_attr(test, assert_instr(cvtsi2sd))]
1043#[stable(feature = "simd_x86", since = "1.27.0")]
1044#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1045pub const fn _mm_cvtsi32_sd(a: __m128d, b: i32) -> __m128d {
1046    unsafe { simd_insert!(a, 0, b as f64) }
1047}
1048
1049/// Converts packed 32-bit integers in `a` to packed single-precision (32-bit)
1050/// floating-point elements.
1051///
1052/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtepi32_ps)
1053#[inline]
1054#[target_feature(enable = "sse2")]
1055#[cfg_attr(test, assert_instr(cvtdq2ps))]
1056#[stable(feature = "simd_x86", since = "1.27.0")]
1057#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1058pub const fn _mm_cvtepi32_ps(a: __m128i) -> __m128 {
1059    unsafe { transmute(simd_cast::<_, f32x4>(a.as_i32x4())) }
1060}
1061
1062/// Converts packed single-precision (32-bit) floating-point elements in `a`
1063/// to packed 32-bit integers.
1064///
1065/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtps_epi32)
1066#[inline]
1067#[target_feature(enable = "sse2")]
1068#[cfg_attr(test, assert_instr(cvtps2dq))]
1069#[stable(feature = "simd_x86", since = "1.27.0")]
1070pub fn _mm_cvtps_epi32(a: __m128) -> __m128i {
1071    unsafe { transmute(cvtps2dq(a)) }
1072}
1073
1074/// Returns a vector whose lowest element is `a` and all higher elements are
1075/// `0`.
1076///
1077/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtsi32_si128)
1078#[inline]
1079#[target_feature(enable = "sse2")]
1080#[stable(feature = "simd_x86", since = "1.27.0")]
1081#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1082pub const fn _mm_cvtsi32_si128(a: i32) -> __m128i {
1083    unsafe { transmute(i32x4::new(a, 0, 0, 0)) }
1084}
1085
1086/// Returns the lowest element of `a`.
1087///
1088/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtsi128_si32)
1089#[inline]
1090#[target_feature(enable = "sse2")]
1091#[stable(feature = "simd_x86", since = "1.27.0")]
1092#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1093pub const fn _mm_cvtsi128_si32(a: __m128i) -> i32 {
1094    unsafe { simd_extract!(a.as_i32x4(), 0) }
1095}
1096
1097/// Sets packed 64-bit integers with the supplied values, from highest to
1098/// lowest.
1099///
1100/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set_epi64x)
1101#[inline]
1102#[target_feature(enable = "sse2")]
1103// no particular instruction to test
1104#[stable(feature = "simd_x86", since = "1.27.0")]
1105#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1106pub const fn _mm_set_epi64x(e1: i64, e0: i64) -> __m128i {
1107    unsafe { transmute(i64x2::new(e0, e1)) }
1108}
1109
1110/// Sets packed 32-bit integers with the supplied values.
1111///
1112/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set_epi32)
1113#[inline]
1114#[target_feature(enable = "sse2")]
1115// no particular instruction to test
1116#[stable(feature = "simd_x86", since = "1.27.0")]
1117#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1118pub const fn _mm_set_epi32(e3: i32, e2: i32, e1: i32, e0: i32) -> __m128i {
1119    unsafe { transmute(i32x4::new(e0, e1, e2, e3)) }
1120}
1121
1122/// Sets packed 16-bit integers with the supplied values.
1123///
1124/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set_epi16)
1125#[inline]
1126#[target_feature(enable = "sse2")]
1127// no particular instruction to test
1128#[stable(feature = "simd_x86", since = "1.27.0")]
1129#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1130pub const fn _mm_set_epi16(
1131    e7: i16,
1132    e6: i16,
1133    e5: i16,
1134    e4: i16,
1135    e3: i16,
1136    e2: i16,
1137    e1: i16,
1138    e0: i16,
1139) -> __m128i {
1140    unsafe { transmute(i16x8::new(e0, e1, e2, e3, e4, e5, e6, e7)) }
1141}
1142
1143/// Sets packed 8-bit integers with the supplied values.
1144///
1145/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set_epi8)
1146#[inline]
1147#[target_feature(enable = "sse2")]
1148// no particular instruction to test
1149#[stable(feature = "simd_x86", since = "1.27.0")]
1150#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1151pub const fn _mm_set_epi8(
1152    e15: i8,
1153    e14: i8,
1154    e13: i8,
1155    e12: i8,
1156    e11: i8,
1157    e10: i8,
1158    e9: i8,
1159    e8: i8,
1160    e7: i8,
1161    e6: i8,
1162    e5: i8,
1163    e4: i8,
1164    e3: i8,
1165    e2: i8,
1166    e1: i8,
1167    e0: i8,
1168) -> __m128i {
1169    unsafe {
1170        #[rustfmt::skip]
1171        transmute(i8x16::new(
1172            e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15,
1173        ))
1174    }
1175}
1176
1177/// Broadcasts 64-bit integer `a` to all elements.
1178///
1179/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set1_epi64x)
1180#[inline]
1181#[target_feature(enable = "sse2")]
1182// no particular instruction to test
1183#[stable(feature = "simd_x86", since = "1.27.0")]
1184#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1185pub const fn _mm_set1_epi64x(a: i64) -> __m128i {
1186    i64x2::splat(a).as_m128i()
1187}
1188
1189/// Broadcasts 32-bit integer `a` to all elements.
1190///
1191/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set1_epi32)
1192#[inline]
1193#[target_feature(enable = "sse2")]
1194// no particular instruction to test
1195#[stable(feature = "simd_x86", since = "1.27.0")]
1196#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1197pub const fn _mm_set1_epi32(a: i32) -> __m128i {
1198    i32x4::splat(a).as_m128i()
1199}
1200
1201/// Broadcasts 16-bit integer `a` to all elements.
1202///
1203/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set1_epi16)
1204#[inline]
1205#[target_feature(enable = "sse2")]
1206// no particular instruction to test
1207#[stable(feature = "simd_x86", since = "1.27.0")]
1208#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1209pub const fn _mm_set1_epi16(a: i16) -> __m128i {
1210    i16x8::splat(a).as_m128i()
1211}
1212
1213/// Broadcasts 8-bit integer `a` to all elements.
1214///
1215/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set1_epi8)
1216#[inline]
1217#[target_feature(enable = "sse2")]
1218// no particular instruction to test
1219#[stable(feature = "simd_x86", since = "1.27.0")]
1220#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1221pub const fn _mm_set1_epi8(a: i8) -> __m128i {
1222    i8x16::splat(a).as_m128i()
1223}
1224
1225/// Sets packed 32-bit integers with the supplied values in reverse order.
1226///
1227/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_setr_epi32)
1228#[inline]
1229#[target_feature(enable = "sse2")]
1230// no particular instruction to test
1231#[stable(feature = "simd_x86", since = "1.27.0")]
1232#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1233pub const fn _mm_setr_epi32(e3: i32, e2: i32, e1: i32, e0: i32) -> __m128i {
1234    _mm_set_epi32(e0, e1, e2, e3)
1235}
1236
1237/// Sets packed 16-bit integers with the supplied values in reverse order.
1238///
1239/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_setr_epi16)
1240#[inline]
1241#[target_feature(enable = "sse2")]
1242// no particular instruction to test
1243#[stable(feature = "simd_x86", since = "1.27.0")]
1244#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1245pub const fn _mm_setr_epi16(
1246    e7: i16,
1247    e6: i16,
1248    e5: i16,
1249    e4: i16,
1250    e3: i16,
1251    e2: i16,
1252    e1: i16,
1253    e0: i16,
1254) -> __m128i {
1255    _mm_set_epi16(e0, e1, e2, e3, e4, e5, e6, e7)
1256}
1257
1258/// Sets packed 8-bit integers with the supplied values in reverse order.
1259///
1260/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_setr_epi8)
1261#[inline]
1262#[target_feature(enable = "sse2")]
1263// no particular instruction to test
1264#[stable(feature = "simd_x86", since = "1.27.0")]
1265#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1266pub const fn _mm_setr_epi8(
1267    e15: i8,
1268    e14: i8,
1269    e13: i8,
1270    e12: i8,
1271    e11: i8,
1272    e10: i8,
1273    e9: i8,
1274    e8: i8,
1275    e7: i8,
1276    e6: i8,
1277    e5: i8,
1278    e4: i8,
1279    e3: i8,
1280    e2: i8,
1281    e1: i8,
1282    e0: i8,
1283) -> __m128i {
1284    #[rustfmt::skip]
1285    _mm_set_epi8(
1286        e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15,
1287    )
1288}
1289
1290/// Returns a vector with all elements set to zero.
1291///
1292/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_setzero_si128)
1293#[inline]
1294#[target_feature(enable = "sse2")]
1295#[cfg_attr(test, assert_instr(xorps))]
1296#[stable(feature = "simd_x86", since = "1.27.0")]
1297#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1298pub const fn _mm_setzero_si128() -> __m128i {
1299    const { unsafe { mem::zeroed() } }
1300}
1301
1302/// Loads 64-bit integer from memory into first element of returned vector.
1303///
1304/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_loadl_epi64)
1305#[inline]
1306#[target_feature(enable = "sse2")]
1307#[stable(feature = "simd_x86", since = "1.27.0")]
1308#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1309pub const unsafe fn _mm_loadl_epi64(mem_addr: *const __m128i) -> __m128i {
1310    _mm_set_epi64x(0, ptr::read_unaligned(mem_addr as *const i64))
1311}
1312
1313/// Loads 128-bits of integer data from memory into a new vector.
1314///
1315/// `mem_addr` must be aligned on a 16-byte boundary.
1316///
1317/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_load_si128)
1318#[inline]
1319#[target_feature(enable = "sse2")]
1320#[cfg_attr(
1321    all(test, not(all(target_arch = "x86", target_env = "msvc"))),
1322    assert_instr(movaps)
1323)]
1324#[stable(feature = "simd_x86", since = "1.27.0")]
1325#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1326pub const unsafe fn _mm_load_si128(mem_addr: *const __m128i) -> __m128i {
1327    *mem_addr
1328}
1329
1330/// Loads 128-bits of integer data from memory into a new vector.
1331///
1332/// `mem_addr` does not need to be aligned on any particular boundary.
1333///
1334/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_loadu_si128)
1335#[ferrocene::prevalidated]
1336#[inline]
1337#[target_feature(enable = "sse2")]
1338#[cfg_attr(test, assert_instr(movups))]
1339#[stable(feature = "simd_x86", since = "1.27.0")]
1340#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1341pub const unsafe fn _mm_loadu_si128(mem_addr: *const __m128i) -> __m128i {
1342    let mut dst: __m128i = _mm_undefined_si128();
1343    ptr::copy_nonoverlapping(
1344        mem_addr as *const u8,
1345        ptr::addr_of_mut!(dst) as *mut u8,
1346        mem::size_of::<__m128i>(),
1347    );
1348    dst
1349}
1350
1351/// Conditionally store 8-bit integer elements from `a` into memory using
1352/// `mask` flagged as non-temporal (unlikely to be used again soon).
1353///
1354/// Elements are not stored when the highest bit is not set in the
1355/// corresponding element.
1356///
1357/// `mem_addr` should correspond to a 128-bit memory location and does not need
1358/// to be aligned on any particular boundary.
1359///
1360/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_maskmoveu_si128)
1361///
1362/// # Safety of non-temporal stores
1363///
1364/// After using this intrinsic, but before any other access to the memory that this intrinsic
1365/// mutates, a call to [`_mm_sfence`] must be performed by the thread that used the intrinsic. In
1366/// particular, functions that call this intrinsic should generally call `_mm_sfence` before they
1367/// return.
1368///
1369/// See [`_mm_sfence`] for details.
1370#[inline]
1371#[target_feature(enable = "sse2")]
1372#[cfg_attr(test, assert_instr(maskmovdqu))]
1373#[stable(feature = "simd_x86", since = "1.27.0")]
1374pub unsafe fn _mm_maskmoveu_si128(a: __m128i, mask: __m128i, mem_addr: *mut i8) {
1375    maskmovdqu(a.as_i8x16(), mask.as_i8x16(), mem_addr)
1376}
1377
1378/// Stores 128-bits of integer data from `a` into memory.
1379///
1380/// `mem_addr` must be aligned on a 16-byte boundary.
1381///
1382/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_store_si128)
1383#[inline]
1384#[target_feature(enable = "sse2")]
1385#[cfg_attr(
1386    all(test, not(all(target_arch = "x86", target_env = "msvc"))),
1387    assert_instr(movaps)
1388)]
1389#[stable(feature = "simd_x86", since = "1.27.0")]
1390#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1391pub const unsafe fn _mm_store_si128(mem_addr: *mut __m128i, a: __m128i) {
1392    *mem_addr = a;
1393}
1394
1395/// Stores 128-bits of integer data from `a` into memory.
1396///
1397/// `mem_addr` does not need to be aligned on any particular boundary.
1398///
1399/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_storeu_si128)
1400#[inline]
1401#[target_feature(enable = "sse2")]
1402#[cfg_attr(test, assert_instr(movups))] // FIXME movdqu expected
1403#[stable(feature = "simd_x86", since = "1.27.0")]
1404#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1405pub const unsafe fn _mm_storeu_si128(mem_addr: *mut __m128i, a: __m128i) {
1406    mem_addr.write_unaligned(a);
1407}
1408
1409/// Stores the lower 64-bit integer `a` to a memory location.
1410///
1411/// `mem_addr` does not need to be aligned on any particular boundary.
1412///
1413/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_storel_epi64)
1414#[inline]
1415#[target_feature(enable = "sse2")]
1416#[stable(feature = "simd_x86", since = "1.27.0")]
1417#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1418pub const unsafe fn _mm_storel_epi64(mem_addr: *mut __m128i, a: __m128i) {
1419    ptr::copy_nonoverlapping(ptr::addr_of!(a) as *const u8, mem_addr as *mut u8, 8);
1420}
1421
1422/// Stores a 128-bit integer vector to a 128-bit aligned memory location.
1423/// To minimize caching, the data is flagged as non-temporal (unlikely to be
1424/// used again soon).
1425///
1426/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_stream_si128)
1427///
1428/// # Safety of non-temporal stores
1429///
1430/// After using this intrinsic, but before any other access to the memory that this intrinsic
1431/// mutates, a call to [`_mm_sfence`] must be performed by the thread that used the intrinsic. In
1432/// particular, functions that call this intrinsic should generally call `_mm_sfence` before they
1433/// return.
1434///
1435/// See [`_mm_sfence`] for details.
1436#[inline]
1437#[target_feature(enable = "sse2")]
1438#[cfg_attr(test, assert_instr(movntdq))]
1439#[stable(feature = "simd_x86", since = "1.27.0")]
1440pub unsafe fn _mm_stream_si128(mem_addr: *mut __m128i, a: __m128i) {
1441    // see #1541, we should use inline asm to be sure, because LangRef isn't clear enough
1442    crate::arch::asm!(
1443        vps!("movntdq",  ",{a}"),
1444        p = in(reg) mem_addr,
1445        a = in(xmm_reg) a,
1446        options(nostack, preserves_flags),
1447    );
1448}
1449
1450/// Stores a 32-bit integer value in a 4-byte aligned memory location.
1451/// To minimize caching, the data is flagged as non-temporal (unlikely to be
1452/// used again soon).
1453///
1454/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_stream_si32)
1455///
1456/// # Safety of non-temporal stores
1457///
1458/// After using this intrinsic, but before any other access to the memory that this intrinsic
1459/// mutates, a call to [`_mm_sfence`] must be performed by the thread that used the intrinsic. In
1460/// particular, functions that call this intrinsic should generally call `_mm_sfence` before they
1461/// return.
1462///
1463/// See [`_mm_sfence`] for details.
1464#[inline]
1465#[target_feature(enable = "sse2")]
1466#[cfg_attr(test, assert_instr(movnti))]
1467#[stable(feature = "simd_x86", since = "1.27.0")]
1468pub unsafe fn _mm_stream_si32(mem_addr: *mut i32, a: i32) {
1469    // see #1541, we should use inline asm to be sure, because LangRef isn't clear enough
1470    crate::arch::asm!(
1471        vps!("movnti", ",{a:e}"), // `:e` for 32bit value
1472        p = in(reg) mem_addr,
1473        a = in(reg) a,
1474        options(nostack, preserves_flags),
1475    );
1476}
1477
1478/// Returns a vector where the low element is extracted from `a` and its upper
1479/// element is zero.
1480///
1481/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_move_epi64)
1482#[inline]
1483#[target_feature(enable = "sse2")]
1484// FIXME movd on msvc, movd on i686
1485#[cfg_attr(all(test, target_arch = "x86_64"), assert_instr(movq))]
1486#[stable(feature = "simd_x86", since = "1.27.0")]
1487#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1488pub const fn _mm_move_epi64(a: __m128i) -> __m128i {
1489    unsafe {
1490        let r: i64x2 = simd_shuffle!(a.as_i64x2(), i64x2::ZERO, [0, 2]);
1491        transmute(r)
1492    }
1493}
1494
1495/// Converts packed signed 16-bit integers from `a` and `b` to packed 8-bit integers
1496/// using signed saturation.
1497///
1498/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packs_epi16)
1499#[inline]
1500#[target_feature(enable = "sse2")]
1501#[cfg_attr(test, assert_instr(packsswb))]
1502#[stable(feature = "simd_x86", since = "1.27.0")]
1503#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1504pub const fn _mm_packs_epi16(a: __m128i, b: __m128i) -> __m128i {
1505    unsafe {
1506        let max = simd_splat(i8::MAX as i16);
1507        let min = simd_splat(i8::MIN as i16);
1508
1509        let clamped_a = simd_imax(simd_imin(a.as_i16x8(), max), min)
1510            .as_m128i()
1511            .as_i8x16();
1512        let clamped_b = simd_imax(simd_imin(b.as_i16x8(), max), min)
1513            .as_m128i()
1514            .as_i8x16();
1515
1516        // Shuffle the low i8 of each i16 from two concatenated vectors into
1517        // the low bits of the result register.
1518        const IDXS: [u32; 16] = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30];
1519        let result: i8x16 = simd_shuffle!(clamped_a, clamped_b, IDXS);
1520
1521        result.as_m128i()
1522    }
1523}
1524
1525/// Converts packed signed 32-bit integers from `a` and `b` to packed 16-bit integers
1526/// using signed saturation.
1527///
1528/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packs_epi32)
1529#[inline]
1530#[target_feature(enable = "sse2")]
1531#[cfg_attr(test, assert_instr(packssdw))]
1532#[stable(feature = "simd_x86", since = "1.27.0")]
1533#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1534pub const fn _mm_packs_epi32(a: __m128i, b: __m128i) -> __m128i {
1535    unsafe {
1536        let max = simd_splat(i16::MAX as i32);
1537        let min = simd_splat(i16::MIN as i32);
1538
1539        let clamped_a = simd_imax(simd_imin(a.as_i32x4(), max), min);
1540        let clamped_b = simd_imax(simd_imin(b.as_i32x4(), max), min);
1541
1542        let clamped_a: i16x4 = simd_cast(clamped_a);
1543        let clamped_b: i16x4 = simd_cast(clamped_b);
1544
1545        let a: i64 = transmute(clamped_a);
1546        let b: i64 = transmute(clamped_b);
1547        i64x2::new(a, b).as_m128i()
1548    }
1549}
1550
1551/// Converts packed signed 16-bit integers from `a` and `b` to packed 8-bit integers
1552/// using unsigned saturation.
1553///
1554/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_packus_epi16)
1555#[inline]
1556#[target_feature(enable = "sse2")]
1557#[cfg_attr(test, assert_instr(packuswb))]
1558#[stable(feature = "simd_x86", since = "1.27.0")]
1559#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1560pub const fn _mm_packus_epi16(a: __m128i, b: __m128i) -> __m128i {
1561    unsafe {
1562        let max = simd_splat(u8::MAX as i16);
1563        let min = simd_splat(u8::MIN as i16);
1564
1565        let clamped_a = simd_imax(simd_imin(a.as_i16x8(), max), min)
1566            .as_m128i()
1567            .as_i8x16();
1568        let clamped_b = simd_imax(simd_imin(b.as_i16x8(), max), min)
1569            .as_m128i()
1570            .as_i8x16();
1571
1572        // Shuffle the low bytes of each i16 from two concatenated vectors into
1573        // the low bits of the result register.
1574        // Without `simd_shuffle`, this intrinsic will cause the AVX-512BW
1575        // `_mm_mask_packus_epi16` and `_mm_maskz_packus_epi16` tests to fail.
1576        const IDXS: [u32; 16] = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30];
1577        let result: i8x16 = simd_shuffle!(clamped_a, clamped_b, IDXS);
1578
1579        result.as_m128i()
1580    }
1581}
1582
1583/// Returns the `imm8` element of `a`.
1584///
1585/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_extract_epi16)
1586#[inline]
1587#[target_feature(enable = "sse2")]
1588#[cfg_attr(test, assert_instr(pextrw, IMM8 = 7))]
1589#[rustc_legacy_const_generics(1)]
1590#[stable(feature = "simd_x86", since = "1.27.0")]
1591#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1592pub const fn _mm_extract_epi16<const IMM8: i32>(a: __m128i) -> i32 {
1593    static_assert_uimm_bits!(IMM8, 3);
1594    unsafe { simd_extract!(a.as_u16x8(), IMM8 as u32, u16) as i32 }
1595}
1596
1597/// Returns a new vector where the `imm8` element of `a` is replaced with `i`.
1598///
1599/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_insert_epi16)
1600#[inline]
1601#[target_feature(enable = "sse2")]
1602#[cfg_attr(test, assert_instr(pinsrw, IMM8 = 7))]
1603#[rustc_legacy_const_generics(2)]
1604#[stable(feature = "simd_x86", since = "1.27.0")]
1605#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1606pub const fn _mm_insert_epi16<const IMM8: i32>(a: __m128i, i: i32) -> __m128i {
1607    static_assert_uimm_bits!(IMM8, 3);
1608    unsafe { transmute(simd_insert!(a.as_i16x8(), IMM8 as u32, i as i16)) }
1609}
1610
1611/// Returns a mask of the most significant bit of each element in `a`.
1612///
1613/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_movemask_epi8)
1614#[ferrocene::prevalidated]
1615#[inline]
1616#[target_feature(enable = "sse2")]
1617#[cfg_attr(test, assert_instr(pmovmskb))]
1618#[stable(feature = "simd_x86", since = "1.27.0")]
1619#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1620pub const fn _mm_movemask_epi8(a: __m128i) -> i32 {
1621    unsafe {
1622        let z = i8x16::ZERO;
1623        let m: i8x16 = simd_lt(a.as_i8x16(), z);
1624        simd_bitmask::<_, u16>(m) as u32 as i32
1625    }
1626}
1627
1628/// Shuffles 32-bit integers in `a` using the control in `IMM8`.
1629///
1630/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shuffle_epi32)
1631#[inline]
1632#[target_feature(enable = "sse2")]
1633#[cfg_attr(test, assert_instr(pshufd, IMM8 = 9))]
1634#[rustc_legacy_const_generics(1)]
1635#[stable(feature = "simd_x86", since = "1.27.0")]
1636#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1637pub const fn _mm_shuffle_epi32<const IMM8: i32>(a: __m128i) -> __m128i {
1638    static_assert_uimm_bits!(IMM8, 8);
1639    unsafe {
1640        let a = a.as_i32x4();
1641        let x: i32x4 = simd_shuffle!(
1642            a,
1643            a,
1644            [
1645                IMM8 as u32 & 0b11,
1646                (IMM8 as u32 >> 2) & 0b11,
1647                (IMM8 as u32 >> 4) & 0b11,
1648                (IMM8 as u32 >> 6) & 0b11,
1649            ],
1650        );
1651        transmute(x)
1652    }
1653}
1654
1655/// Shuffles 16-bit integers in the high 64 bits of `a` using the control in
1656/// `IMM8`.
1657///
1658/// Put the results in the high 64 bits of the returned vector, with the low 64
1659/// bits being copied from `a`.
1660///
1661/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shufflehi_epi16)
1662#[inline]
1663#[target_feature(enable = "sse2")]
1664#[cfg_attr(test, assert_instr(pshufhw, IMM8 = 9))]
1665#[rustc_legacy_const_generics(1)]
1666#[stable(feature = "simd_x86", since = "1.27.0")]
1667#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1668pub const fn _mm_shufflehi_epi16<const IMM8: i32>(a: __m128i) -> __m128i {
1669    static_assert_uimm_bits!(IMM8, 8);
1670    unsafe {
1671        let a = a.as_i16x8();
1672        let x: i16x8 = simd_shuffle!(
1673            a,
1674            a,
1675            [
1676                0,
1677                1,
1678                2,
1679                3,
1680                (IMM8 as u32 & 0b11) + 4,
1681                ((IMM8 as u32 >> 2) & 0b11) + 4,
1682                ((IMM8 as u32 >> 4) & 0b11) + 4,
1683                ((IMM8 as u32 >> 6) & 0b11) + 4,
1684            ],
1685        );
1686        transmute(x)
1687    }
1688}
1689
1690/// Shuffles 16-bit integers in the low 64 bits of `a` using the control in
1691/// `IMM8`.
1692///
1693/// Put the results in the low 64 bits of the returned vector, with the high 64
1694/// bits being copied from `a`.
1695///
1696/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shufflelo_epi16)
1697#[inline]
1698#[target_feature(enable = "sse2")]
1699#[cfg_attr(test, assert_instr(pshuflw, IMM8 = 9))]
1700#[rustc_legacy_const_generics(1)]
1701#[stable(feature = "simd_x86", since = "1.27.0")]
1702#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1703pub const fn _mm_shufflelo_epi16<const IMM8: i32>(a: __m128i) -> __m128i {
1704    static_assert_uimm_bits!(IMM8, 8);
1705    unsafe {
1706        let a = a.as_i16x8();
1707        let x: i16x8 = simd_shuffle!(
1708            a,
1709            a,
1710            [
1711                IMM8 as u32 & 0b11,
1712                (IMM8 as u32 >> 2) & 0b11,
1713                (IMM8 as u32 >> 4) & 0b11,
1714                (IMM8 as u32 >> 6) & 0b11,
1715                4,
1716                5,
1717                6,
1718                7,
1719            ],
1720        );
1721        transmute(x)
1722    }
1723}
1724
1725/// Unpacks and interleave 8-bit integers from the high half of `a` and `b`.
1726///
1727/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpackhi_epi8)
1728#[inline]
1729#[target_feature(enable = "sse2")]
1730#[cfg_attr(test, assert_instr(punpckhbw))]
1731#[stable(feature = "simd_x86", since = "1.27.0")]
1732#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1733pub const fn _mm_unpackhi_epi8(a: __m128i, b: __m128i) -> __m128i {
1734    unsafe {
1735        transmute::<i8x16, _>(simd_shuffle!(
1736            a.as_i8x16(),
1737            b.as_i8x16(),
1738            [8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31],
1739        ))
1740    }
1741}
1742
1743/// Unpacks and interleave 16-bit integers from the high half of `a` and `b`.
1744///
1745/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpackhi_epi16)
1746#[inline]
1747#[target_feature(enable = "sse2")]
1748#[cfg_attr(test, assert_instr(punpckhwd))]
1749#[stable(feature = "simd_x86", since = "1.27.0")]
1750#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1751pub const fn _mm_unpackhi_epi16(a: __m128i, b: __m128i) -> __m128i {
1752    unsafe {
1753        let x = simd_shuffle!(a.as_i16x8(), b.as_i16x8(), [4, 12, 5, 13, 6, 14, 7, 15]);
1754        transmute::<i16x8, _>(x)
1755    }
1756}
1757
1758/// Unpacks and interleave 32-bit integers from the high half of `a` and `b`.
1759///
1760/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpackhi_epi32)
1761#[inline]
1762#[target_feature(enable = "sse2")]
1763#[cfg_attr(test, assert_instr(unpckhps))]
1764#[stable(feature = "simd_x86", since = "1.27.0")]
1765#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1766pub const fn _mm_unpackhi_epi32(a: __m128i, b: __m128i) -> __m128i {
1767    unsafe { transmute::<i32x4, _>(simd_shuffle!(a.as_i32x4(), b.as_i32x4(), [2, 6, 3, 7])) }
1768}
1769
1770/// Unpacks and interleave 64-bit integers from the high half of `a` and `b`.
1771///
1772/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpackhi_epi64)
1773#[inline]
1774#[target_feature(enable = "sse2")]
1775#[cfg_attr(test, assert_instr(unpckhpd))]
1776#[stable(feature = "simd_x86", since = "1.27.0")]
1777#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1778pub const fn _mm_unpackhi_epi64(a: __m128i, b: __m128i) -> __m128i {
1779    unsafe { transmute::<i64x2, _>(simd_shuffle!(a.as_i64x2(), b.as_i64x2(), [1, 3])) }
1780}
1781
1782/// Unpacks and interleave 8-bit integers from the low half of `a` and `b`.
1783///
1784/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpacklo_epi8)
1785#[inline]
1786#[target_feature(enable = "sse2")]
1787#[cfg_attr(test, assert_instr(punpcklbw))]
1788#[stable(feature = "simd_x86", since = "1.27.0")]
1789#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1790pub const fn _mm_unpacklo_epi8(a: __m128i, b: __m128i) -> __m128i {
1791    unsafe {
1792        transmute::<i8x16, _>(simd_shuffle!(
1793            a.as_i8x16(),
1794            b.as_i8x16(),
1795            [0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23],
1796        ))
1797    }
1798}
1799
1800/// Unpacks and interleave 16-bit integers from the low half of `a` and `b`.
1801///
1802/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpacklo_epi16)
1803#[inline]
1804#[target_feature(enable = "sse2")]
1805#[cfg_attr(test, assert_instr(punpcklwd))]
1806#[stable(feature = "simd_x86", since = "1.27.0")]
1807#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1808pub const fn _mm_unpacklo_epi16(a: __m128i, b: __m128i) -> __m128i {
1809    unsafe {
1810        let x = simd_shuffle!(a.as_i16x8(), b.as_i16x8(), [0, 8, 1, 9, 2, 10, 3, 11]);
1811        transmute::<i16x8, _>(x)
1812    }
1813}
1814
1815/// Unpacks and interleave 32-bit integers from the low half of `a` and `b`.
1816///
1817/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpacklo_epi32)
1818#[inline]
1819#[target_feature(enable = "sse2")]
1820#[cfg_attr(test, assert_instr(unpcklps))]
1821#[stable(feature = "simd_x86", since = "1.27.0")]
1822#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1823pub const fn _mm_unpacklo_epi32(a: __m128i, b: __m128i) -> __m128i {
1824    unsafe { transmute::<i32x4, _>(simd_shuffle!(a.as_i32x4(), b.as_i32x4(), [0, 4, 1, 5])) }
1825}
1826
1827/// Unpacks and interleave 64-bit integers from the low half of `a` and `b`.
1828///
1829/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpacklo_epi64)
1830#[inline]
1831#[target_feature(enable = "sse2")]
1832#[cfg_attr(test, assert_instr(movlhps))]
1833#[stable(feature = "simd_x86", since = "1.27.0")]
1834#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1835pub const fn _mm_unpacklo_epi64(a: __m128i, b: __m128i) -> __m128i {
1836    unsafe { transmute::<i64x2, _>(simd_shuffle!(a.as_i64x2(), b.as_i64x2(), [0, 2])) }
1837}
1838
1839/// Returns a new vector with the low element of `a` replaced by the sum of the
1840/// low elements of `a` and `b`.
1841///
1842/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_add_sd)
1843#[inline]
1844#[target_feature(enable = "sse2")]
1845#[cfg_attr(test, assert_instr(addsd))]
1846#[stable(feature = "simd_x86", since = "1.27.0")]
1847#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1848pub const fn _mm_add_sd(a: __m128d, b: __m128d) -> __m128d {
1849    unsafe { simd_insert!(a, 0, _mm_cvtsd_f64(a) + _mm_cvtsd_f64(b)) }
1850}
1851
1852/// Adds packed double-precision (64-bit) floating-point elements in `a` and
1853/// `b`.
1854///
1855/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_add_pd)
1856#[inline]
1857#[target_feature(enable = "sse2")]
1858#[cfg_attr(test, assert_instr(addpd))]
1859#[stable(feature = "simd_x86", since = "1.27.0")]
1860#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1861pub const fn _mm_add_pd(a: __m128d, b: __m128d) -> __m128d {
1862    unsafe { simd_add(a, b) }
1863}
1864
1865/// Returns a new vector with the low element of `a` replaced by the result of
1866/// diving the lower element of `a` by the lower element of `b`.
1867///
1868/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_div_sd)
1869#[inline]
1870#[target_feature(enable = "sse2")]
1871#[cfg_attr(test, assert_instr(divsd))]
1872#[stable(feature = "simd_x86", since = "1.27.0")]
1873#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1874pub const fn _mm_div_sd(a: __m128d, b: __m128d) -> __m128d {
1875    unsafe { simd_insert!(a, 0, _mm_cvtsd_f64(a) / _mm_cvtsd_f64(b)) }
1876}
1877
1878/// Divide packed double-precision (64-bit) floating-point elements in `a` by
1879/// packed elements in `b`.
1880///
1881/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_div_pd)
1882#[inline]
1883#[target_feature(enable = "sse2")]
1884#[cfg_attr(test, assert_instr(divpd))]
1885#[stable(feature = "simd_x86", since = "1.27.0")]
1886#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1887pub const fn _mm_div_pd(a: __m128d, b: __m128d) -> __m128d {
1888    unsafe { simd_div(a, b) }
1889}
1890
1891/// Returns a new vector with the low element of `a` replaced by the maximum
1892/// of the lower elements of `a` and `b`.
1893///
1894/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_max_sd)
1895#[inline]
1896#[target_feature(enable = "sse2")]
1897#[cfg_attr(test, assert_instr(maxsd))]
1898#[stable(feature = "simd_x86", since = "1.27.0")]
1899pub fn _mm_max_sd(a: __m128d, b: __m128d) -> __m128d {
1900    unsafe { maxsd(a, b) }
1901}
1902
1903/// Returns a new vector with the maximum values from corresponding elements in
1904/// `a` and `b`.
1905///
1906/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_max_pd)
1907#[inline]
1908#[target_feature(enable = "sse2")]
1909#[cfg_attr(test, assert_instr(maxpd))]
1910#[stable(feature = "simd_x86", since = "1.27.0")]
1911pub fn _mm_max_pd(a: __m128d, b: __m128d) -> __m128d {
1912    unsafe { maxpd(a, b) }
1913}
1914
1915/// Returns a new vector with the low element of `a` replaced by the minimum
1916/// of the lower elements of `a` and `b`.
1917///
1918/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_min_sd)
1919#[inline]
1920#[target_feature(enable = "sse2")]
1921#[cfg_attr(test, assert_instr(minsd))]
1922#[stable(feature = "simd_x86", since = "1.27.0")]
1923pub fn _mm_min_sd(a: __m128d, b: __m128d) -> __m128d {
1924    unsafe { minsd(a, b) }
1925}
1926
1927/// Returns a new vector with the minimum values from corresponding elements in
1928/// `a` and `b`.
1929///
1930/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_min_pd)
1931#[inline]
1932#[target_feature(enable = "sse2")]
1933#[cfg_attr(test, assert_instr(minpd))]
1934#[stable(feature = "simd_x86", since = "1.27.0")]
1935pub fn _mm_min_pd(a: __m128d, b: __m128d) -> __m128d {
1936    unsafe { minpd(a, b) }
1937}
1938
1939/// Returns a new vector with the low element of `a` replaced by multiplying the
1940/// low elements of `a` and `b`.
1941///
1942/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mul_sd)
1943#[inline]
1944#[target_feature(enable = "sse2")]
1945#[cfg_attr(test, assert_instr(mulsd))]
1946#[stable(feature = "simd_x86", since = "1.27.0")]
1947#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1948pub const fn _mm_mul_sd(a: __m128d, b: __m128d) -> __m128d {
1949    unsafe { simd_insert!(a, 0, _mm_cvtsd_f64(a) * _mm_cvtsd_f64(b)) }
1950}
1951
1952/// Multiplies packed double-precision (64-bit) floating-point elements in `a`
1953/// and `b`.
1954///
1955/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mul_pd)
1956#[inline]
1957#[target_feature(enable = "sse2")]
1958#[cfg_attr(test, assert_instr(mulpd))]
1959#[stable(feature = "simd_x86", since = "1.27.0")]
1960#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1961pub const fn _mm_mul_pd(a: __m128d, b: __m128d) -> __m128d {
1962    unsafe { simd_mul(a, b) }
1963}
1964
1965/// Returns a new vector with the low element of `a` replaced by the square
1966/// root of the lower element `b`.
1967///
1968/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sqrt_sd)
1969#[inline]
1970#[target_feature(enable = "sse2")]
1971#[cfg_attr(test, assert_instr(sqrtsd))]
1972#[stable(feature = "simd_x86", since = "1.27.0")]
1973pub fn _mm_sqrt_sd(a: __m128d, b: __m128d) -> __m128d {
1974    unsafe { simd_insert!(a, 0, sqrtf64(_mm_cvtsd_f64(b))) }
1975}
1976
1977/// Returns a new vector with the square root of each of the values in `a`.
1978///
1979/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sqrt_pd)
1980#[inline]
1981#[target_feature(enable = "sse2")]
1982#[cfg_attr(test, assert_instr(sqrtpd))]
1983#[stable(feature = "simd_x86", since = "1.27.0")]
1984pub fn _mm_sqrt_pd(a: __m128d) -> __m128d {
1985    unsafe { simd_fsqrt(a) }
1986}
1987
1988/// Returns a new vector with the low element of `a` replaced by subtracting the
1989/// low element by `b` from the low element of `a`.
1990///
1991/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sub_sd)
1992#[inline]
1993#[target_feature(enable = "sse2")]
1994#[cfg_attr(test, assert_instr(subsd))]
1995#[stable(feature = "simd_x86", since = "1.27.0")]
1996#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
1997pub const fn _mm_sub_sd(a: __m128d, b: __m128d) -> __m128d {
1998    unsafe { simd_insert!(a, 0, _mm_cvtsd_f64(a) - _mm_cvtsd_f64(b)) }
1999}
2000
2001/// Subtract packed double-precision (64-bit) floating-point elements in `b`
2002/// from `a`.
2003///
2004/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sub_pd)
2005#[inline]
2006#[target_feature(enable = "sse2")]
2007#[cfg_attr(test, assert_instr(subpd))]
2008#[stable(feature = "simd_x86", since = "1.27.0")]
2009#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2010pub const fn _mm_sub_pd(a: __m128d, b: __m128d) -> __m128d {
2011    unsafe { simd_sub(a, b) }
2012}
2013
2014/// Computes the bitwise AND of packed double-precision (64-bit) floating-point
2015/// elements in `a` and `b`.
2016///
2017/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_and_pd)
2018#[inline]
2019#[target_feature(enable = "sse2")]
2020#[cfg_attr(test, assert_instr(andps))]
2021#[stable(feature = "simd_x86", since = "1.27.0")]
2022#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2023pub const fn _mm_and_pd(a: __m128d, b: __m128d) -> __m128d {
2024    unsafe {
2025        let a: __m128i = transmute(a);
2026        let b: __m128i = transmute(b);
2027        transmute(_mm_and_si128(a, b))
2028    }
2029}
2030
2031/// Computes the bitwise NOT of `a` and then AND with `b`.
2032///
2033/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_andnot_pd)
2034#[inline]
2035#[target_feature(enable = "sse2")]
2036#[cfg_attr(test, assert_instr(andnps))]
2037#[stable(feature = "simd_x86", since = "1.27.0")]
2038#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2039pub const fn _mm_andnot_pd(a: __m128d, b: __m128d) -> __m128d {
2040    unsafe {
2041        let a: __m128i = transmute(a);
2042        let b: __m128i = transmute(b);
2043        transmute(_mm_andnot_si128(a, b))
2044    }
2045}
2046
2047/// Computes the bitwise OR of `a` and `b`.
2048///
2049/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_or_pd)
2050#[inline]
2051#[target_feature(enable = "sse2")]
2052#[cfg_attr(test, assert_instr(orps))]
2053#[stable(feature = "simd_x86", since = "1.27.0")]
2054#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2055pub const fn _mm_or_pd(a: __m128d, b: __m128d) -> __m128d {
2056    unsafe {
2057        let a: __m128i = transmute(a);
2058        let b: __m128i = transmute(b);
2059        transmute(_mm_or_si128(a, b))
2060    }
2061}
2062
2063/// Computes the bitwise XOR of `a` and `b`.
2064///
2065/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_xor_pd)
2066#[inline]
2067#[target_feature(enable = "sse2")]
2068#[cfg_attr(test, assert_instr(xorps))]
2069#[stable(feature = "simd_x86", since = "1.27.0")]
2070#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2071pub const fn _mm_xor_pd(a: __m128d, b: __m128d) -> __m128d {
2072    unsafe {
2073        let a: __m128i = transmute(a);
2074        let b: __m128i = transmute(b);
2075        transmute(_mm_xor_si128(a, b))
2076    }
2077}
2078
2079/// Returns a new vector with the low element of `a` replaced by the equality
2080/// comparison of the lower elements of `a` and `b`.
2081///
2082/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpeq_sd)
2083#[inline]
2084#[target_feature(enable = "sse2")]
2085#[cfg_attr(test, assert_instr(cmpeqsd))]
2086#[stable(feature = "simd_x86", since = "1.27.0")]
2087pub fn _mm_cmpeq_sd(a: __m128d, b: __m128d) -> __m128d {
2088    unsafe { cmpsd(a, b, 0) }
2089}
2090
2091/// Returns a new vector with the low element of `a` replaced by the less-than
2092/// comparison of the lower elements of `a` and `b`.
2093///
2094/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmplt_sd)
2095#[inline]
2096#[target_feature(enable = "sse2")]
2097#[cfg_attr(test, assert_instr(cmpltsd))]
2098#[stable(feature = "simd_x86", since = "1.27.0")]
2099pub fn _mm_cmplt_sd(a: __m128d, b: __m128d) -> __m128d {
2100    unsafe { cmpsd(a, b, 1) }
2101}
2102
2103/// Returns a new vector with the low element of `a` replaced by the
2104/// less-than-or-equal comparison of the lower elements of `a` and `b`.
2105///
2106/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmple_sd)
2107#[inline]
2108#[target_feature(enable = "sse2")]
2109#[cfg_attr(test, assert_instr(cmplesd))]
2110#[stable(feature = "simd_x86", since = "1.27.0")]
2111pub fn _mm_cmple_sd(a: __m128d, b: __m128d) -> __m128d {
2112    unsafe { cmpsd(a, b, 2) }
2113}
2114
2115/// Returns a new vector with the low element of `a` replaced by the
2116/// greater-than comparison of the lower elements of `a` and `b`.
2117///
2118/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpgt_sd)
2119#[inline]
2120#[target_feature(enable = "sse2")]
2121#[cfg_attr(test, assert_instr(cmpltsd))]
2122#[stable(feature = "simd_x86", since = "1.27.0")]
2123pub fn _mm_cmpgt_sd(a: __m128d, b: __m128d) -> __m128d {
2124    unsafe { simd_insert!(_mm_cmplt_sd(b, a), 1, simd_extract!(a, 1, f64)) }
2125}
2126
2127/// Returns a new vector with the low element of `a` replaced by the
2128/// greater-than-or-equal comparison of the lower elements of `a` and `b`.
2129///
2130/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpge_sd)
2131#[inline]
2132#[target_feature(enable = "sse2")]
2133#[cfg_attr(test, assert_instr(cmplesd))]
2134#[stable(feature = "simd_x86", since = "1.27.0")]
2135pub fn _mm_cmpge_sd(a: __m128d, b: __m128d) -> __m128d {
2136    unsafe { simd_insert!(_mm_cmple_sd(b, a), 1, simd_extract!(a, 1, f64)) }
2137}
2138
2139/// Returns a new vector with the low element of `a` replaced by the result
2140/// of comparing both of the lower elements of `a` and `b` to `NaN`. If
2141/// neither are equal to `NaN` then `0xFFFFFFFFFFFFFFFF` is used and `0`
2142/// otherwise.
2143///
2144/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpord_sd)
2145#[inline]
2146#[target_feature(enable = "sse2")]
2147#[cfg_attr(test, assert_instr(cmpordsd))]
2148#[stable(feature = "simd_x86", since = "1.27.0")]
2149pub fn _mm_cmpord_sd(a: __m128d, b: __m128d) -> __m128d {
2150    unsafe { cmpsd(a, b, 7) }
2151}
2152
2153/// Returns a new vector with the low element of `a` replaced by the result of
2154/// comparing both of the lower elements of `a` and `b` to `NaN`. If either is
2155/// equal to `NaN` then `0xFFFFFFFFFFFFFFFF` is used and `0` otherwise.
2156///
2157/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpunord_sd)
2158#[inline]
2159#[target_feature(enable = "sse2")]
2160#[cfg_attr(test, assert_instr(cmpunordsd))]
2161#[stable(feature = "simd_x86", since = "1.27.0")]
2162pub fn _mm_cmpunord_sd(a: __m128d, b: __m128d) -> __m128d {
2163    unsafe { cmpsd(a, b, 3) }
2164}
2165
2166/// Returns a new vector with the low element of `a` replaced by the not-equal
2167/// comparison of the lower elements of `a` and `b`.
2168///
2169/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpneq_sd)
2170#[inline]
2171#[target_feature(enable = "sse2")]
2172#[cfg_attr(test, assert_instr(cmpneqsd))]
2173#[stable(feature = "simd_x86", since = "1.27.0")]
2174pub fn _mm_cmpneq_sd(a: __m128d, b: __m128d) -> __m128d {
2175    unsafe { cmpsd(a, b, 4) }
2176}
2177
2178/// Returns a new vector with the low element of `a` replaced by the
2179/// not-less-than comparison of the lower elements of `a` and `b`.
2180///
2181/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpnlt_sd)
2182#[inline]
2183#[target_feature(enable = "sse2")]
2184#[cfg_attr(test, assert_instr(cmpnltsd))]
2185#[stable(feature = "simd_x86", since = "1.27.0")]
2186pub fn _mm_cmpnlt_sd(a: __m128d, b: __m128d) -> __m128d {
2187    unsafe { cmpsd(a, b, 5) }
2188}
2189
2190/// Returns a new vector with the low element of `a` replaced by the
2191/// not-less-than-or-equal comparison of the lower elements of `a` and `b`.
2192///
2193/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpnle_sd)
2194#[inline]
2195#[target_feature(enable = "sse2")]
2196#[cfg_attr(test, assert_instr(cmpnlesd))]
2197#[stable(feature = "simd_x86", since = "1.27.0")]
2198pub fn _mm_cmpnle_sd(a: __m128d, b: __m128d) -> __m128d {
2199    unsafe { cmpsd(a, b, 6) }
2200}
2201
2202/// Returns a new vector with the low element of `a` replaced by the
2203/// not-greater-than comparison of the lower elements of `a` and `b`.
2204///
2205/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpngt_sd)
2206#[inline]
2207#[target_feature(enable = "sse2")]
2208#[cfg_attr(test, assert_instr(cmpnltsd))]
2209#[stable(feature = "simd_x86", since = "1.27.0")]
2210pub fn _mm_cmpngt_sd(a: __m128d, b: __m128d) -> __m128d {
2211    unsafe { simd_insert!(_mm_cmpnlt_sd(b, a), 1, simd_extract!(a, 1, f64)) }
2212}
2213
2214/// Returns a new vector with the low element of `a` replaced by the
2215/// not-greater-than-or-equal comparison of the lower elements of `a` and `b`.
2216///
2217/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpnge_sd)
2218#[inline]
2219#[target_feature(enable = "sse2")]
2220#[cfg_attr(test, assert_instr(cmpnlesd))]
2221#[stable(feature = "simd_x86", since = "1.27.0")]
2222pub fn _mm_cmpnge_sd(a: __m128d, b: __m128d) -> __m128d {
2223    unsafe { simd_insert!(_mm_cmpnle_sd(b, a), 1, simd_extract!(a, 1, f64)) }
2224}
2225
2226/// Compares corresponding elements in `a` and `b` for equality.
2227///
2228/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpeq_pd)
2229#[inline]
2230#[target_feature(enable = "sse2")]
2231#[cfg_attr(test, assert_instr(cmpeqpd))]
2232#[stable(feature = "simd_x86", since = "1.27.0")]
2233pub fn _mm_cmpeq_pd(a: __m128d, b: __m128d) -> __m128d {
2234    unsafe { cmppd(a, b, 0) }
2235}
2236
2237/// Compares corresponding elements in `a` and `b` for less-than.
2238///
2239/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmplt_pd)
2240#[inline]
2241#[target_feature(enable = "sse2")]
2242#[cfg_attr(test, assert_instr(cmpltpd))]
2243#[stable(feature = "simd_x86", since = "1.27.0")]
2244pub fn _mm_cmplt_pd(a: __m128d, b: __m128d) -> __m128d {
2245    unsafe { cmppd(a, b, 1) }
2246}
2247
2248/// Compares corresponding elements in `a` and `b` for less-than-or-equal
2249///
2250/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmple_pd)
2251#[inline]
2252#[target_feature(enable = "sse2")]
2253#[cfg_attr(test, assert_instr(cmplepd))]
2254#[stable(feature = "simd_x86", since = "1.27.0")]
2255pub fn _mm_cmple_pd(a: __m128d, b: __m128d) -> __m128d {
2256    unsafe { cmppd(a, b, 2) }
2257}
2258
2259/// Compares corresponding elements in `a` and `b` for greater-than.
2260///
2261/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpgt_pd)
2262#[inline]
2263#[target_feature(enable = "sse2")]
2264#[cfg_attr(test, assert_instr(cmpltpd))]
2265#[stable(feature = "simd_x86", since = "1.27.0")]
2266pub fn _mm_cmpgt_pd(a: __m128d, b: __m128d) -> __m128d {
2267    _mm_cmplt_pd(b, a)
2268}
2269
2270/// Compares corresponding elements in `a` and `b` for greater-than-or-equal.
2271///
2272/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpge_pd)
2273#[inline]
2274#[target_feature(enable = "sse2")]
2275#[cfg_attr(test, assert_instr(cmplepd))]
2276#[stable(feature = "simd_x86", since = "1.27.0")]
2277pub fn _mm_cmpge_pd(a: __m128d, b: __m128d) -> __m128d {
2278    _mm_cmple_pd(b, a)
2279}
2280
2281/// Compares corresponding elements in `a` and `b` to see if neither is `NaN`.
2282///
2283/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpord_pd)
2284#[inline]
2285#[target_feature(enable = "sse2")]
2286#[cfg_attr(test, assert_instr(cmpordpd))]
2287#[stable(feature = "simd_x86", since = "1.27.0")]
2288pub fn _mm_cmpord_pd(a: __m128d, b: __m128d) -> __m128d {
2289    unsafe { cmppd(a, b, 7) }
2290}
2291
2292/// Compares corresponding elements in `a` and `b` to see if either is `NaN`.
2293///
2294/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpunord_pd)
2295#[inline]
2296#[target_feature(enable = "sse2")]
2297#[cfg_attr(test, assert_instr(cmpunordpd))]
2298#[stable(feature = "simd_x86", since = "1.27.0")]
2299pub fn _mm_cmpunord_pd(a: __m128d, b: __m128d) -> __m128d {
2300    unsafe { cmppd(a, b, 3) }
2301}
2302
2303/// Compares corresponding elements in `a` and `b` for not-equal.
2304///
2305/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpneq_pd)
2306#[inline]
2307#[target_feature(enable = "sse2")]
2308#[cfg_attr(test, assert_instr(cmpneqpd))]
2309#[stable(feature = "simd_x86", since = "1.27.0")]
2310pub fn _mm_cmpneq_pd(a: __m128d, b: __m128d) -> __m128d {
2311    unsafe { cmppd(a, b, 4) }
2312}
2313
2314/// Compares corresponding elements in `a` and `b` for not-less-than.
2315///
2316/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpnlt_pd)
2317#[inline]
2318#[target_feature(enable = "sse2")]
2319#[cfg_attr(test, assert_instr(cmpnltpd))]
2320#[stable(feature = "simd_x86", since = "1.27.0")]
2321pub fn _mm_cmpnlt_pd(a: __m128d, b: __m128d) -> __m128d {
2322    unsafe { cmppd(a, b, 5) }
2323}
2324
2325/// Compares corresponding elements in `a` and `b` for not-less-than-or-equal.
2326///
2327/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpnle_pd)
2328#[inline]
2329#[target_feature(enable = "sse2")]
2330#[cfg_attr(test, assert_instr(cmpnlepd))]
2331#[stable(feature = "simd_x86", since = "1.27.0")]
2332pub fn _mm_cmpnle_pd(a: __m128d, b: __m128d) -> __m128d {
2333    unsafe { cmppd(a, b, 6) }
2334}
2335
2336/// Compares corresponding elements in `a` and `b` for not-greater-than.
2337///
2338/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpngt_pd)
2339#[inline]
2340#[target_feature(enable = "sse2")]
2341#[cfg_attr(test, assert_instr(cmpnltpd))]
2342#[stable(feature = "simd_x86", since = "1.27.0")]
2343pub fn _mm_cmpngt_pd(a: __m128d, b: __m128d) -> __m128d {
2344    _mm_cmpnlt_pd(b, a)
2345}
2346
2347/// Compares corresponding elements in `a` and `b` for
2348/// not-greater-than-or-equal.
2349///
2350/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpnge_pd)
2351#[inline]
2352#[target_feature(enable = "sse2")]
2353#[cfg_attr(test, assert_instr(cmpnlepd))]
2354#[stable(feature = "simd_x86", since = "1.27.0")]
2355pub fn _mm_cmpnge_pd(a: __m128d, b: __m128d) -> __m128d {
2356    _mm_cmpnle_pd(b, a)
2357}
2358
2359/// Compares the lower element of `a` and `b` for equality.
2360///
2361/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_comieq_sd)
2362#[inline]
2363#[target_feature(enable = "sse2")]
2364#[cfg_attr(test, assert_instr(comisd))]
2365#[stable(feature = "simd_x86", since = "1.27.0")]
2366pub fn _mm_comieq_sd(a: __m128d, b: __m128d) -> i32 {
2367    unsafe { comieqsd(a, b) }
2368}
2369
2370/// Compares the lower element of `a` and `b` for less-than.
2371///
2372/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_comilt_sd)
2373#[inline]
2374#[target_feature(enable = "sse2")]
2375#[cfg_attr(test, assert_instr(comisd))]
2376#[stable(feature = "simd_x86", since = "1.27.0")]
2377pub fn _mm_comilt_sd(a: __m128d, b: __m128d) -> i32 {
2378    unsafe { comiltsd(a, b) }
2379}
2380
2381/// Compares the lower element of `a` and `b` for less-than-or-equal.
2382///
2383/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_comile_sd)
2384#[inline]
2385#[target_feature(enable = "sse2")]
2386#[cfg_attr(test, assert_instr(comisd))]
2387#[stable(feature = "simd_x86", since = "1.27.0")]
2388pub fn _mm_comile_sd(a: __m128d, b: __m128d) -> i32 {
2389    unsafe { comilesd(a, b) }
2390}
2391
2392/// Compares the lower element of `a` and `b` for greater-than.
2393///
2394/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_comigt_sd)
2395#[inline]
2396#[target_feature(enable = "sse2")]
2397#[cfg_attr(test, assert_instr(comisd))]
2398#[stable(feature = "simd_x86", since = "1.27.0")]
2399pub fn _mm_comigt_sd(a: __m128d, b: __m128d) -> i32 {
2400    unsafe { comigtsd(a, b) }
2401}
2402
2403/// Compares the lower element of `a` and `b` for greater-than-or-equal.
2404///
2405/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_comige_sd)
2406#[inline]
2407#[target_feature(enable = "sse2")]
2408#[cfg_attr(test, assert_instr(comisd))]
2409#[stable(feature = "simd_x86", since = "1.27.0")]
2410pub fn _mm_comige_sd(a: __m128d, b: __m128d) -> i32 {
2411    unsafe { comigesd(a, b) }
2412}
2413
2414/// Compares the lower element of `a` and `b` for not-equal.
2415///
2416/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_comineq_sd)
2417#[inline]
2418#[target_feature(enable = "sse2")]
2419#[cfg_attr(test, assert_instr(comisd))]
2420#[stable(feature = "simd_x86", since = "1.27.0")]
2421pub fn _mm_comineq_sd(a: __m128d, b: __m128d) -> i32 {
2422    unsafe { comineqsd(a, b) }
2423}
2424
2425/// Compares the lower element of `a` and `b` for equality.
2426///
2427/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_ucomieq_sd)
2428#[inline]
2429#[target_feature(enable = "sse2")]
2430#[cfg_attr(test, assert_instr(ucomisd))]
2431#[stable(feature = "simd_x86", since = "1.27.0")]
2432pub fn _mm_ucomieq_sd(a: __m128d, b: __m128d) -> i32 {
2433    unsafe { ucomieqsd(a, b) }
2434}
2435
2436/// Compares the lower element of `a` and `b` for less-than.
2437///
2438/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_ucomilt_sd)
2439#[inline]
2440#[target_feature(enable = "sse2")]
2441#[cfg_attr(test, assert_instr(ucomisd))]
2442#[stable(feature = "simd_x86", since = "1.27.0")]
2443pub fn _mm_ucomilt_sd(a: __m128d, b: __m128d) -> i32 {
2444    unsafe { ucomiltsd(a, b) }
2445}
2446
2447/// Compares the lower element of `a` and `b` for less-than-or-equal.
2448///
2449/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_ucomile_sd)
2450#[inline]
2451#[target_feature(enable = "sse2")]
2452#[cfg_attr(test, assert_instr(ucomisd))]
2453#[stable(feature = "simd_x86", since = "1.27.0")]
2454pub fn _mm_ucomile_sd(a: __m128d, b: __m128d) -> i32 {
2455    unsafe { ucomilesd(a, b) }
2456}
2457
2458/// Compares the lower element of `a` and `b` for greater-than.
2459///
2460/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_ucomigt_sd)
2461#[inline]
2462#[target_feature(enable = "sse2")]
2463#[cfg_attr(test, assert_instr(ucomisd))]
2464#[stable(feature = "simd_x86", since = "1.27.0")]
2465pub fn _mm_ucomigt_sd(a: __m128d, b: __m128d) -> i32 {
2466    unsafe { ucomigtsd(a, b) }
2467}
2468
2469/// Compares the lower element of `a` and `b` for greater-than-or-equal.
2470///
2471/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_ucomige_sd)
2472#[inline]
2473#[target_feature(enable = "sse2")]
2474#[cfg_attr(test, assert_instr(ucomisd))]
2475#[stable(feature = "simd_x86", since = "1.27.0")]
2476pub fn _mm_ucomige_sd(a: __m128d, b: __m128d) -> i32 {
2477    unsafe { ucomigesd(a, b) }
2478}
2479
2480/// Compares the lower element of `a` and `b` for not-equal.
2481///
2482/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_ucomineq_sd)
2483#[inline]
2484#[target_feature(enable = "sse2")]
2485#[cfg_attr(test, assert_instr(ucomisd))]
2486#[stable(feature = "simd_x86", since = "1.27.0")]
2487pub fn _mm_ucomineq_sd(a: __m128d, b: __m128d) -> i32 {
2488    unsafe { ucomineqsd(a, b) }
2489}
2490
2491/// Converts packed double-precision (64-bit) floating-point elements in `a` to
2492/// packed single-precision (32-bit) floating-point elements
2493///
2494/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtpd_ps)
2495#[inline]
2496#[target_feature(enable = "sse2")]
2497#[cfg_attr(test, assert_instr(cvtpd2ps))]
2498#[stable(feature = "simd_x86", since = "1.27.0")]
2499#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2500pub const fn _mm_cvtpd_ps(a: __m128d) -> __m128 {
2501    unsafe {
2502        let r = simd_cast::<_, f32x2>(a.as_f64x2());
2503        let zero = f32x2::ZERO;
2504        transmute::<f32x4, _>(simd_shuffle!(r, zero, [0, 1, 2, 3]))
2505    }
2506}
2507
2508/// Converts packed single-precision (32-bit) floating-point elements in `a` to
2509/// packed
2510/// double-precision (64-bit) floating-point elements.
2511///
2512/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtps_pd)
2513#[inline]
2514#[target_feature(enable = "sse2")]
2515#[cfg_attr(test, assert_instr(cvtps2pd))]
2516#[stable(feature = "simd_x86", since = "1.27.0")]
2517#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2518pub const fn _mm_cvtps_pd(a: __m128) -> __m128d {
2519    unsafe {
2520        let a = a.as_f32x4();
2521        transmute(simd_cast::<f32x2, f64x2>(simd_shuffle!(a, a, [0, 1])))
2522    }
2523}
2524
2525/// Converts packed double-precision (64-bit) floating-point elements in `a` to
2526/// packed 32-bit integers.
2527///
2528/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtpd_epi32)
2529#[inline]
2530#[target_feature(enable = "sse2")]
2531#[cfg_attr(test, assert_instr(cvtpd2dq))]
2532#[stable(feature = "simd_x86", since = "1.27.0")]
2533pub fn _mm_cvtpd_epi32(a: __m128d) -> __m128i {
2534    unsafe { transmute(cvtpd2dq(a)) }
2535}
2536
2537/// Converts the lower double-precision (64-bit) floating-point element in a to
2538/// a 32-bit integer.
2539///
2540/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtsd_si32)
2541#[inline]
2542#[target_feature(enable = "sse2")]
2543#[cfg_attr(test, assert_instr(cvtsd2si))]
2544#[stable(feature = "simd_x86", since = "1.27.0")]
2545pub fn _mm_cvtsd_si32(a: __m128d) -> i32 {
2546    unsafe { cvtsd2si(a) }
2547}
2548
2549/// Converts the lower double-precision (64-bit) floating-point element in `b`
2550/// to a single-precision (32-bit) floating-point element, store the result in
2551/// the lower element of the return value, and copies the upper element from `a`
2552/// to the upper element the return value.
2553///
2554/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtsd_ss)
2555#[inline]
2556#[target_feature(enable = "sse2")]
2557#[cfg_attr(test, assert_instr(cvtsd2ss))]
2558#[stable(feature = "simd_x86", since = "1.27.0")]
2559pub fn _mm_cvtsd_ss(a: __m128, b: __m128d) -> __m128 {
2560    unsafe { cvtsd2ss(a, b) }
2561}
2562
2563/// Returns the lower double-precision (64-bit) floating-point element of `a`.
2564///
2565/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtsd_f64)
2566#[inline]
2567#[target_feature(enable = "sse2")]
2568#[stable(feature = "simd_x86", since = "1.27.0")]
2569#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2570pub const fn _mm_cvtsd_f64(a: __m128d) -> f64 {
2571    unsafe { simd_extract!(a, 0) }
2572}
2573
2574/// Converts the lower single-precision (32-bit) floating-point element in `b`
2575/// to a double-precision (64-bit) floating-point element, store the result in
2576/// the lower element of the return value, and copies the upper element from `a`
2577/// to the upper element the return value.
2578///
2579/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtss_sd)
2580#[inline]
2581#[target_feature(enable = "sse2")]
2582#[cfg_attr(test, assert_instr(cvtss2sd))]
2583#[stable(feature = "simd_x86", since = "1.27.0")]
2584#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2585pub const fn _mm_cvtss_sd(a: __m128d, b: __m128) -> __m128d {
2586    unsafe {
2587        let elt: f32 = simd_extract!(b, 0);
2588        simd_insert!(a, 0, elt as f64)
2589    }
2590}
2591
2592/// Converts packed double-precision (64-bit) floating-point elements in `a` to
2593/// packed 32-bit integers with truncation.
2594///
2595/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvttpd_epi32)
2596#[inline]
2597#[target_feature(enable = "sse2")]
2598#[cfg_attr(test, assert_instr(cvttpd2dq))]
2599#[stable(feature = "simd_x86", since = "1.27.0")]
2600pub fn _mm_cvttpd_epi32(a: __m128d) -> __m128i {
2601    unsafe { transmute(cvttpd2dq(a)) }
2602}
2603
2604/// Converts the lower double-precision (64-bit) floating-point element in `a`
2605/// to a 32-bit integer with truncation.
2606///
2607/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvttsd_si32)
2608#[inline]
2609#[target_feature(enable = "sse2")]
2610#[cfg_attr(test, assert_instr(cvttsd2si))]
2611#[stable(feature = "simd_x86", since = "1.27.0")]
2612pub fn _mm_cvttsd_si32(a: __m128d) -> i32 {
2613    unsafe { cvttsd2si(a) }
2614}
2615
2616/// Converts packed single-precision (32-bit) floating-point elements in `a` to
2617/// packed 32-bit integers with truncation.
2618///
2619/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvttps_epi32)
2620#[inline]
2621#[target_feature(enable = "sse2")]
2622#[cfg_attr(test, assert_instr(cvttps2dq))]
2623#[stable(feature = "simd_x86", since = "1.27.0")]
2624pub fn _mm_cvttps_epi32(a: __m128) -> __m128i {
2625    unsafe { transmute(cvttps2dq(a)) }
2626}
2627
2628/// Copies double-precision (64-bit) floating-point element `a` to the lower
2629/// element of the packed 64-bit return value.
2630///
2631/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set_sd)
2632#[inline]
2633#[target_feature(enable = "sse2")]
2634#[stable(feature = "simd_x86", since = "1.27.0")]
2635#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2636pub const fn _mm_set_sd(a: f64) -> __m128d {
2637    _mm_set_pd(0.0, a)
2638}
2639
2640/// Broadcasts double-precision (64-bit) floating-point value a to all elements
2641/// of the return value.
2642///
2643/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set1_pd)
2644#[inline]
2645#[target_feature(enable = "sse2")]
2646#[stable(feature = "simd_x86", since = "1.27.0")]
2647#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2648pub const fn _mm_set1_pd(a: f64) -> __m128d {
2649    _mm_set_pd(a, a)
2650}
2651
2652/// Broadcasts double-precision (64-bit) floating-point value a to all elements
2653/// of the return value.
2654///
2655/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set_pd1)
2656#[inline]
2657#[target_feature(enable = "sse2")]
2658#[stable(feature = "simd_x86", since = "1.27.0")]
2659#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2660pub const fn _mm_set_pd1(a: f64) -> __m128d {
2661    _mm_set_pd(a, a)
2662}
2663
2664/// Sets packed double-precision (64-bit) floating-point elements in the return
2665/// value with the supplied values.
2666///
2667/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_set_pd)
2668#[inline]
2669#[target_feature(enable = "sse2")]
2670#[stable(feature = "simd_x86", since = "1.27.0")]
2671#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2672pub const fn _mm_set_pd(a: f64, b: f64) -> __m128d {
2673    __m128d([b, a])
2674}
2675
2676/// Sets packed double-precision (64-bit) floating-point elements in the return
2677/// value with the supplied values in reverse order.
2678///
2679/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_setr_pd)
2680#[inline]
2681#[target_feature(enable = "sse2")]
2682#[stable(feature = "simd_x86", since = "1.27.0")]
2683#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2684pub const fn _mm_setr_pd(a: f64, b: f64) -> __m128d {
2685    _mm_set_pd(b, a)
2686}
2687
2688/// Returns packed double-precision (64-bit) floating-point elements with all
2689/// zeros.
2690///
2691/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_setzero_pd)
2692#[inline]
2693#[target_feature(enable = "sse2")]
2694#[cfg_attr(test, assert_instr(xorp))]
2695#[stable(feature = "simd_x86", since = "1.27.0")]
2696#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2697pub const fn _mm_setzero_pd() -> __m128d {
2698    const { unsafe { mem::zeroed() } }
2699}
2700
2701/// Returns a mask of the most significant bit of each element in `a`.
2702///
2703/// The mask is stored in the 2 least significant bits of the return value.
2704/// All other bits are set to `0`.
2705///
2706/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_movemask_pd)
2707#[inline]
2708#[target_feature(enable = "sse2")]
2709#[cfg_attr(test, assert_instr(movmskpd))]
2710#[stable(feature = "simd_x86", since = "1.27.0")]
2711#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2712pub const fn _mm_movemask_pd(a: __m128d) -> i32 {
2713    // Propagate the highest bit to the rest, because simd_bitmask
2714    // requires all-1 or all-0.
2715    unsafe {
2716        let mask: i64x2 = simd_lt(transmute(a), i64x2::ZERO);
2717        simd_bitmask::<i64x2, u8>(mask) as i32
2718    }
2719}
2720
2721/// Loads 128-bits (composed of 2 packed double-precision (64-bit)
2722/// floating-point elements) from memory into the returned vector.
2723/// `mem_addr` must be aligned on a 16-byte boundary or a general-protection
2724/// exception may be generated.
2725///
2726/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_load_pd)
2727#[inline]
2728#[target_feature(enable = "sse2")]
2729#[cfg_attr(
2730    all(test, not(all(target_arch = "x86", target_env = "msvc"))),
2731    assert_instr(movaps)
2732)]
2733#[stable(feature = "simd_x86", since = "1.27.0")]
2734#[allow(clippy::cast_ptr_alignment)]
2735#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2736pub const unsafe fn _mm_load_pd(mem_addr: *const f64) -> __m128d {
2737    *(mem_addr as *const __m128d)
2738}
2739
2740/// Loads a 64-bit double-precision value to the low element of a
2741/// 128-bit integer vector and clears the upper element.
2742///
2743/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_load_sd)
2744#[inline]
2745#[target_feature(enable = "sse2")]
2746#[cfg_attr(test, assert_instr(movsd))]
2747#[stable(feature = "simd_x86", since = "1.27.0")]
2748#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2749pub const unsafe fn _mm_load_sd(mem_addr: *const f64) -> __m128d {
2750    _mm_setr_pd(*mem_addr, 0.)
2751}
2752
2753/// Loads a double-precision value into the high-order bits of a 128-bit
2754/// vector of `[2 x double]`. The low-order bits are copied from the low-order
2755/// bits of the first operand.
2756///
2757/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_loadh_pd)
2758#[inline]
2759#[target_feature(enable = "sse2")]
2760#[cfg_attr(test, assert_instr(movhps))]
2761#[stable(feature = "simd_x86", since = "1.27.0")]
2762#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2763pub const unsafe fn _mm_loadh_pd(a: __m128d, mem_addr: *const f64) -> __m128d {
2764    _mm_setr_pd(simd_extract!(a, 0), *mem_addr)
2765}
2766
2767/// Loads a double-precision value into the low-order bits of a 128-bit
2768/// vector of `[2 x double]`. The high-order bits are copied from the
2769/// high-order bits of the first operand.
2770///
2771/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_loadl_pd)
2772#[inline]
2773#[target_feature(enable = "sse2")]
2774#[cfg_attr(test, assert_instr(movlps))]
2775#[stable(feature = "simd_x86", since = "1.27.0")]
2776#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2777pub const unsafe fn _mm_loadl_pd(a: __m128d, mem_addr: *const f64) -> __m128d {
2778    _mm_setr_pd(*mem_addr, simd_extract!(a, 1))
2779}
2780
2781/// Stores a 128-bit floating point vector of `[2 x double]` to a 128-bit
2782/// aligned memory location.
2783/// To minimize caching, the data is flagged as non-temporal (unlikely to be
2784/// used again soon).
2785///
2786/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_stream_pd)
2787///
2788/// # Safety of non-temporal stores
2789///
2790/// After using this intrinsic, but before any other access to the memory that this intrinsic
2791/// mutates, a call to [`_mm_sfence`] must be performed by the thread that used the intrinsic. In
2792/// particular, functions that call this intrinsic should generally call `_mm_sfence` before they
2793/// return.
2794///
2795/// See [`_mm_sfence`] for details.
2796#[inline]
2797#[target_feature(enable = "sse2")]
2798#[cfg_attr(test, assert_instr(movntpd))]
2799#[stable(feature = "simd_x86", since = "1.27.0")]
2800#[allow(clippy::cast_ptr_alignment)]
2801pub unsafe fn _mm_stream_pd(mem_addr: *mut f64, a: __m128d) {
2802    // see #1541, we should use inline asm to be sure, because LangRef isn't clear enough
2803    crate::arch::asm!(
2804        vps!("movntpd", ",{a}"),
2805        p = in(reg) mem_addr,
2806        a = in(xmm_reg) a,
2807        options(nostack, preserves_flags),
2808    );
2809}
2810
2811/// Stores the lower 64 bits of a 128-bit vector of `[2 x double]` to a
2812/// memory location.
2813///
2814/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_store_sd)
2815#[inline]
2816#[target_feature(enable = "sse2")]
2817#[cfg_attr(test, assert_instr(movlps))]
2818#[stable(feature = "simd_x86", since = "1.27.0")]
2819#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2820pub const unsafe fn _mm_store_sd(mem_addr: *mut f64, a: __m128d) {
2821    *mem_addr = simd_extract!(a, 0)
2822}
2823
2824/// Stores 128-bits (composed of 2 packed double-precision (64-bit)
2825/// floating-point elements) from `a` into memory. `mem_addr` must be aligned
2826/// on a 16-byte boundary or a general-protection exception may be generated.
2827///
2828/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_store_pd)
2829#[inline]
2830#[target_feature(enable = "sse2")]
2831#[cfg_attr(
2832    all(test, not(all(target_arch = "x86", target_env = "msvc"))),
2833    assert_instr(movaps)
2834)]
2835#[stable(feature = "simd_x86", since = "1.27.0")]
2836#[allow(clippy::cast_ptr_alignment)]
2837#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2838pub const unsafe fn _mm_store_pd(mem_addr: *mut f64, a: __m128d) {
2839    *(mem_addr as *mut __m128d) = a;
2840}
2841
2842/// Stores 128-bits (composed of 2 packed double-precision (64-bit)
2843/// floating-point elements) from `a` into memory.
2844/// `mem_addr` does not need to be aligned on any particular boundary.
2845///
2846/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_storeu_pd)
2847#[inline]
2848#[target_feature(enable = "sse2")]
2849#[cfg_attr(test, assert_instr(movups))] // FIXME movupd expected
2850#[stable(feature = "simd_x86", since = "1.27.0")]
2851#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2852pub const unsafe fn _mm_storeu_pd(mem_addr: *mut f64, a: __m128d) {
2853    mem_addr.cast::<__m128d>().write_unaligned(a);
2854}
2855
2856/// Store 16-bit integer from the first element of a into memory.
2857///
2858/// `mem_addr` does not need to be aligned on any particular boundary.
2859///
2860/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_storeu_si16)
2861#[inline]
2862#[target_feature(enable = "sse2")]
2863#[stable(feature = "simd_x86_updates", since = "1.82.0")]
2864#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2865pub const unsafe fn _mm_storeu_si16(mem_addr: *mut u8, a: __m128i) {
2866    ptr::write_unaligned(mem_addr as *mut i16, simd_extract(a.as_i16x8(), 0))
2867}
2868
2869/// Store 32-bit integer from the first element of a into memory.
2870///
2871/// `mem_addr` does not need to be aligned on any particular boundary.
2872///
2873/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_storeu_si32)
2874#[inline]
2875#[target_feature(enable = "sse2")]
2876#[stable(feature = "simd_x86_updates", since = "1.82.0")]
2877#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2878pub const unsafe fn _mm_storeu_si32(mem_addr: *mut u8, a: __m128i) {
2879    ptr::write_unaligned(mem_addr as *mut i32, simd_extract(a.as_i32x4(), 0))
2880}
2881
2882/// Store 64-bit integer from the first element of a into memory.
2883///
2884/// `mem_addr` does not need to be aligned on any particular boundary.
2885///
2886/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_storeu_si64)
2887#[inline]
2888#[target_feature(enable = "sse2")]
2889#[stable(feature = "simd_x86_updates", since = "1.82.0")]
2890#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2891pub const unsafe fn _mm_storeu_si64(mem_addr: *mut u8, a: __m128i) {
2892    ptr::write_unaligned(mem_addr as *mut i64, simd_extract(a.as_i64x2(), 0))
2893}
2894
2895/// Stores the lower double-precision (64-bit) floating-point element from `a`
2896/// into 2 contiguous elements in memory. `mem_addr` must be aligned on a
2897/// 16-byte boundary or a general-protection exception may be generated.
2898///
2899/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_store1_pd)
2900#[inline]
2901#[target_feature(enable = "sse2")]
2902#[stable(feature = "simd_x86", since = "1.27.0")]
2903#[allow(clippy::cast_ptr_alignment)]
2904#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2905pub const unsafe fn _mm_store1_pd(mem_addr: *mut f64, a: __m128d) {
2906    let b: __m128d = simd_shuffle!(a, a, [0, 0]);
2907    *(mem_addr as *mut __m128d) = b;
2908}
2909
2910/// Stores the lower double-precision (64-bit) floating-point element from `a`
2911/// into 2 contiguous elements in memory. `mem_addr` must be aligned on a
2912/// 16-byte boundary or a general-protection exception may be generated.
2913///
2914/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_store_pd1)
2915#[inline]
2916#[target_feature(enable = "sse2")]
2917#[stable(feature = "simd_x86", since = "1.27.0")]
2918#[allow(clippy::cast_ptr_alignment)]
2919#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2920pub const unsafe fn _mm_store_pd1(mem_addr: *mut f64, a: __m128d) {
2921    let b: __m128d = simd_shuffle!(a, a, [0, 0]);
2922    *(mem_addr as *mut __m128d) = b;
2923}
2924
2925/// Stores 2 double-precision (64-bit) floating-point elements from `a` into
2926/// memory in reverse order.
2927/// `mem_addr` must be aligned on a 16-byte boundary or a general-protection
2928/// exception may be generated.
2929///
2930/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_storer_pd)
2931#[inline]
2932#[target_feature(enable = "sse2")]
2933#[stable(feature = "simd_x86", since = "1.27.0")]
2934#[allow(clippy::cast_ptr_alignment)]
2935#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2936pub const unsafe fn _mm_storer_pd(mem_addr: *mut f64, a: __m128d) {
2937    let b: __m128d = simd_shuffle!(a, a, [1, 0]);
2938    *(mem_addr as *mut __m128d) = b;
2939}
2940
2941/// Stores the upper 64 bits of a 128-bit vector of `[2 x double]` to a
2942/// memory location.
2943///
2944/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_storeh_pd)
2945#[inline]
2946#[target_feature(enable = "sse2")]
2947#[cfg_attr(test, assert_instr(movhps))]
2948#[stable(feature = "simd_x86", since = "1.27.0")]
2949#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2950pub const unsafe fn _mm_storeh_pd(mem_addr: *mut f64, a: __m128d) {
2951    *mem_addr = simd_extract!(a, 1);
2952}
2953
2954/// Stores the lower 64 bits of a 128-bit vector of `[2 x double]` to a
2955/// memory location.
2956///
2957/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_storel_pd)
2958#[inline]
2959#[target_feature(enable = "sse2")]
2960#[cfg_attr(test, assert_instr(movlps))]
2961#[stable(feature = "simd_x86", since = "1.27.0")]
2962#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2963pub const unsafe fn _mm_storel_pd(mem_addr: *mut f64, a: __m128d) {
2964    *mem_addr = simd_extract!(a, 0);
2965}
2966
2967/// Loads a double-precision (64-bit) floating-point element from memory
2968/// into both elements of returned vector.
2969///
2970/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_load1_pd)
2971#[inline]
2972#[target_feature(enable = "sse2")]
2973// #[cfg_attr(test, assert_instr(movapd))] // FIXME LLVM uses different codegen
2974#[stable(feature = "simd_x86", since = "1.27.0")]
2975#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2976pub const unsafe fn _mm_load1_pd(mem_addr: *const f64) -> __m128d {
2977    let d = *mem_addr;
2978    _mm_setr_pd(d, d)
2979}
2980
2981/// Loads a double-precision (64-bit) floating-point element from memory
2982/// into both elements of returned vector.
2983///
2984/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_load_pd1)
2985#[inline]
2986#[target_feature(enable = "sse2")]
2987// #[cfg_attr(test, assert_instr(movapd))] // FIXME same as _mm_load1_pd
2988#[stable(feature = "simd_x86", since = "1.27.0")]
2989#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
2990pub const unsafe fn _mm_load_pd1(mem_addr: *const f64) -> __m128d {
2991    _mm_load1_pd(mem_addr)
2992}
2993
2994/// Loads 2 double-precision (64-bit) floating-point elements from memory into
2995/// the returned vector in reverse order. `mem_addr` must be aligned on a
2996/// 16-byte boundary or a general-protection exception may be generated.
2997///
2998/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_loadr_pd)
2999#[inline]
3000#[target_feature(enable = "sse2")]
3001#[cfg_attr(
3002    all(test, not(all(target_arch = "x86", target_env = "msvc"))),
3003    assert_instr(movaps)
3004)]
3005#[stable(feature = "simd_x86", since = "1.27.0")]
3006#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3007pub const unsafe fn _mm_loadr_pd(mem_addr: *const f64) -> __m128d {
3008    let a = _mm_load_pd(mem_addr);
3009    simd_shuffle!(a, a, [1, 0])
3010}
3011
3012/// Loads 128-bits (composed of 2 packed double-precision (64-bit)
3013/// floating-point elements) from memory into the returned vector.
3014/// `mem_addr` does not need to be aligned on any particular boundary.
3015///
3016/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_loadu_pd)
3017#[inline]
3018#[target_feature(enable = "sse2")]
3019#[cfg_attr(test, assert_instr(movups))]
3020#[stable(feature = "simd_x86", since = "1.27.0")]
3021#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3022pub const unsafe fn _mm_loadu_pd(mem_addr: *const f64) -> __m128d {
3023    let mut dst = _mm_undefined_pd();
3024    ptr::copy_nonoverlapping(
3025        mem_addr as *const u8,
3026        ptr::addr_of_mut!(dst) as *mut u8,
3027        mem::size_of::<__m128d>(),
3028    );
3029    dst
3030}
3031
3032/// Loads unaligned 16-bits of integer data from memory into new vector.
3033///
3034/// `mem_addr` does not need to be aligned on any particular boundary.
3035///
3036/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_loadu_si16)
3037#[inline]
3038#[target_feature(enable = "sse2")]
3039#[stable(feature = "simd_x86_updates", since = "1.82.0")]
3040#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3041pub const unsafe fn _mm_loadu_si16(mem_addr: *const u8) -> __m128i {
3042    transmute(i16x8::new(
3043        ptr::read_unaligned(mem_addr as *const i16),
3044        0,
3045        0,
3046        0,
3047        0,
3048        0,
3049        0,
3050        0,
3051    ))
3052}
3053
3054/// Loads unaligned 32-bits of integer data from memory into new vector.
3055///
3056/// `mem_addr` does not need to be aligned on any particular boundary.
3057///
3058/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_loadu_si32)
3059#[inline]
3060#[target_feature(enable = "sse2")]
3061#[stable(feature = "simd_x86_updates", since = "1.82.0")]
3062#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3063pub const unsafe fn _mm_loadu_si32(mem_addr: *const u8) -> __m128i {
3064    transmute(i32x4::new(
3065        ptr::read_unaligned(mem_addr as *const i32),
3066        0,
3067        0,
3068        0,
3069    ))
3070}
3071
3072/// Loads unaligned 64-bits of integer data from memory into new vector.
3073///
3074/// `mem_addr` does not need to be aligned on any particular boundary.
3075///
3076/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_loadu_si64)
3077#[inline]
3078#[target_feature(enable = "sse2")]
3079#[stable(feature = "simd_x86_mm_loadu_si64", since = "1.46.0")]
3080#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3081pub const unsafe fn _mm_loadu_si64(mem_addr: *const u8) -> __m128i {
3082    transmute(i64x2::new(ptr::read_unaligned(mem_addr as *const i64), 0))
3083}
3084
3085/// Constructs a 128-bit floating-point vector of `[2 x double]` from two
3086/// 128-bit vector parameters of `[2 x double]`, using the immediate-value
3087/// parameter as a specifier.
3088///
3089/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shuffle_pd)
3090#[inline]
3091#[target_feature(enable = "sse2")]
3092#[cfg_attr(test, assert_instr(shufps, MASK = 2))]
3093#[rustc_legacy_const_generics(2)]
3094#[stable(feature = "simd_x86", since = "1.27.0")]
3095#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3096pub const fn _mm_shuffle_pd<const MASK: i32>(a: __m128d, b: __m128d) -> __m128d {
3097    static_assert_uimm_bits!(MASK, 8);
3098    unsafe { simd_shuffle!(a, b, [MASK as u32 & 0b1, ((MASK as u32 >> 1) & 0b1) + 2]) }
3099}
3100
3101/// Constructs a 128-bit floating-point vector of `[2 x double]`. The lower
3102/// 64 bits are set to the lower 64 bits of the second parameter. The upper
3103/// 64 bits are set to the upper 64 bits of the first parameter.
3104///
3105/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_move_sd)
3106#[inline]
3107#[target_feature(enable = "sse2")]
3108#[cfg_attr(test, assert_instr(movsd))]
3109#[stable(feature = "simd_x86", since = "1.27.0")]
3110#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3111pub const fn _mm_move_sd(a: __m128d, b: __m128d) -> __m128d {
3112    unsafe { _mm_setr_pd(simd_extract!(b, 0), simd_extract!(a, 1)) }
3113}
3114
3115/// Casts a 128-bit floating-point vector of `[2 x double]` into a 128-bit
3116/// floating-point vector of `[4 x float]`.
3117///
3118/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_castpd_ps)
3119#[inline]
3120#[target_feature(enable = "sse2")]
3121#[stable(feature = "simd_x86", since = "1.27.0")]
3122#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3123pub const fn _mm_castpd_ps(a: __m128d) -> __m128 {
3124    unsafe { transmute(a) }
3125}
3126
3127/// Casts a 128-bit floating-point vector of `[2 x double]` into a 128-bit
3128/// integer vector.
3129///
3130/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_castpd_si128)
3131#[inline]
3132#[target_feature(enable = "sse2")]
3133#[stable(feature = "simd_x86", since = "1.27.0")]
3134#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3135pub const fn _mm_castpd_si128(a: __m128d) -> __m128i {
3136    unsafe { transmute(a) }
3137}
3138
3139/// Casts a 128-bit floating-point vector of `[4 x float]` into a 128-bit
3140/// floating-point vector of `[2 x double]`.
3141///
3142/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_castps_pd)
3143#[inline]
3144#[target_feature(enable = "sse2")]
3145#[stable(feature = "simd_x86", since = "1.27.0")]
3146#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3147pub const fn _mm_castps_pd(a: __m128) -> __m128d {
3148    unsafe { transmute(a) }
3149}
3150
3151/// Casts a 128-bit floating-point vector of `[4 x float]` into a 128-bit
3152/// integer vector.
3153///
3154/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_castps_si128)
3155#[inline]
3156#[target_feature(enable = "sse2")]
3157#[stable(feature = "simd_x86", since = "1.27.0")]
3158#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3159pub const fn _mm_castps_si128(a: __m128) -> __m128i {
3160    unsafe { transmute(a) }
3161}
3162
3163/// Casts a 128-bit integer vector into a 128-bit floating-point vector
3164/// of `[2 x double]`.
3165///
3166/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_castsi128_pd)
3167#[inline]
3168#[target_feature(enable = "sse2")]
3169#[stable(feature = "simd_x86", since = "1.27.0")]
3170#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3171pub const fn _mm_castsi128_pd(a: __m128i) -> __m128d {
3172    unsafe { transmute(a) }
3173}
3174
3175/// Casts a 128-bit integer vector into a 128-bit floating-point vector
3176/// of `[4 x float]`.
3177///
3178/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_castsi128_ps)
3179#[inline]
3180#[target_feature(enable = "sse2")]
3181#[stable(feature = "simd_x86", since = "1.27.0")]
3182#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3183pub const fn _mm_castsi128_ps(a: __m128i) -> __m128 {
3184    unsafe { transmute(a) }
3185}
3186
3187/// Returns vector of type __m128d with indeterminate elements.with indetermination elements.
3188/// Despite using the word "undefined" (following Intel's naming scheme), this non-deterministically
3189/// picks some valid value and is not equivalent to [`mem::MaybeUninit`].
3190/// In practice, this is typically equivalent to [`mem::zeroed`].
3191///
3192/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_undefined_pd)
3193#[inline]
3194#[target_feature(enable = "sse2")]
3195#[stable(feature = "simd_x86", since = "1.27.0")]
3196#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3197pub const fn _mm_undefined_pd() -> __m128d {
3198    const { unsafe { mem::zeroed() } }
3199}
3200
3201/// Returns vector of type __m128i with indeterminate elements.with indetermination elements.
3202/// Despite using the word "undefined" (following Intel's naming scheme), this non-deterministically
3203/// picks some valid value and is not equivalent to [`mem::MaybeUninit`].
3204/// In practice, this is typically equivalent to [`mem::zeroed`].
3205///
3206/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_undefined_si128)
3207#[ferrocene::prevalidated]
3208#[inline]
3209#[target_feature(enable = "sse2")]
3210#[stable(feature = "simd_x86", since = "1.27.0")]
3211#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3212pub const fn _mm_undefined_si128() -> __m128i {
3213    const { unsafe { mem::zeroed() } }
3214}
3215
3216/// The resulting `__m128d` element is composed by the low-order values of
3217/// the two `__m128d` interleaved input elements, i.e.:
3218///
3219/// * The `[127:64]` bits are copied from the `[127:64]` bits of the second input
3220/// * The `[63:0]` bits are copied from the `[127:64]` bits of the first input
3221///
3222/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpackhi_pd)
3223#[inline]
3224#[target_feature(enable = "sse2")]
3225#[cfg_attr(test, assert_instr(unpckhpd))]
3226#[stable(feature = "simd_x86", since = "1.27.0")]
3227#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3228pub const fn _mm_unpackhi_pd(a: __m128d, b: __m128d) -> __m128d {
3229    unsafe { simd_shuffle!(a, b, [1, 3]) }
3230}
3231
3232/// The resulting `__m128d` element is composed by the high-order values of
3233/// the two `__m128d` interleaved input elements, i.e.:
3234///
3235/// * The `[127:64]` bits are copied from the `[63:0]` bits of the second input
3236/// * The `[63:0]` bits are copied from the `[63:0]` bits of the first input
3237///
3238/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_unpacklo_pd)
3239#[inline]
3240#[target_feature(enable = "sse2")]
3241#[cfg_attr(test, assert_instr(movlhps))]
3242#[stable(feature = "simd_x86", since = "1.27.0")]
3243#[rustc_const_unstable(feature = "stdarch_const_x86", issue = "149298")]
3244pub const fn _mm_unpacklo_pd(a: __m128d, b: __m128d) -> __m128d {
3245    unsafe { simd_shuffle!(a, b, [0, 2]) }
3246}
3247
3248#[allow(improper_ctypes)]
3249unsafe extern "unadjusted" {
3250    #[link_name = "llvm.x86.sse2.pause"]
3251    fn pause();
3252    #[link_name = "llvm.x86.sse2.clflush"]
3253    fn clflush(p: *const u8);
3254    #[link_name = "llvm.x86.sse2.lfence"]
3255    fn lfence();
3256    #[link_name = "llvm.x86.sse2.mfence"]
3257    fn mfence();
3258    #[link_name = "llvm.x86.sse2.pmadd.wd"]
3259    fn pmaddwd(a: i16x8, b: i16x8) -> i32x4;
3260    #[link_name = "llvm.x86.sse2.psad.bw"]
3261    fn psadbw(a: u8x16, b: u8x16) -> u64x2;
3262    #[link_name = "llvm.x86.sse2.psll.w"]
3263    fn psllw(a: i16x8, count: i16x8) -> i16x8;
3264    #[link_name = "llvm.x86.sse2.psll.d"]
3265    fn pslld(a: i32x4, count: i32x4) -> i32x4;
3266    #[link_name = "llvm.x86.sse2.psll.q"]
3267    fn psllq(a: i64x2, count: i64x2) -> i64x2;
3268    #[link_name = "llvm.x86.sse2.psra.w"]
3269    fn psraw(a: i16x8, count: i16x8) -> i16x8;
3270    #[link_name = "llvm.x86.sse2.psra.d"]
3271    fn psrad(a: i32x4, count: i32x4) -> i32x4;
3272    #[link_name = "llvm.x86.sse2.psrl.w"]
3273    fn psrlw(a: i16x8, count: i16x8) -> i16x8;
3274    #[link_name = "llvm.x86.sse2.psrl.d"]
3275    fn psrld(a: i32x4, count: i32x4) -> i32x4;
3276    #[link_name = "llvm.x86.sse2.psrl.q"]
3277    fn psrlq(a: i64x2, count: i64x2) -> i64x2;
3278    #[link_name = "llvm.x86.sse2.cvtps2dq"]
3279    fn cvtps2dq(a: __m128) -> i32x4;
3280    #[link_name = "llvm.x86.sse2.maskmov.dqu"]
3281    fn maskmovdqu(a: i8x16, mask: i8x16, mem_addr: *mut i8);
3282    #[link_name = "llvm.x86.sse2.max.sd"]
3283    fn maxsd(a: __m128d, b: __m128d) -> __m128d;
3284    #[link_name = "llvm.x86.sse2.max.pd"]
3285    fn maxpd(a: __m128d, b: __m128d) -> __m128d;
3286    #[link_name = "llvm.x86.sse2.min.sd"]
3287    fn minsd(a: __m128d, b: __m128d) -> __m128d;
3288    #[link_name = "llvm.x86.sse2.min.pd"]
3289    fn minpd(a: __m128d, b: __m128d) -> __m128d;
3290    #[link_name = "llvm.x86.sse2.cmp.sd"]
3291    fn cmpsd(a: __m128d, b: __m128d, imm8: i8) -> __m128d;
3292    #[link_name = "llvm.x86.sse2.cmp.pd"]
3293    fn cmppd(a: __m128d, b: __m128d, imm8: i8) -> __m128d;
3294    #[link_name = "llvm.x86.sse2.comieq.sd"]
3295    fn comieqsd(a: __m128d, b: __m128d) -> i32;
3296    #[link_name = "llvm.x86.sse2.comilt.sd"]
3297    fn comiltsd(a: __m128d, b: __m128d) -> i32;
3298    #[link_name = "llvm.x86.sse2.comile.sd"]
3299    fn comilesd(a: __m128d, b: __m128d) -> i32;
3300    #[link_name = "llvm.x86.sse2.comigt.sd"]
3301    fn comigtsd(a: __m128d, b: __m128d) -> i32;
3302    #[link_name = "llvm.x86.sse2.comige.sd"]
3303    fn comigesd(a: __m128d, b: __m128d) -> i32;
3304    #[link_name = "llvm.x86.sse2.comineq.sd"]
3305    fn comineqsd(a: __m128d, b: __m128d) -> i32;
3306    #[link_name = "llvm.x86.sse2.ucomieq.sd"]
3307    fn ucomieqsd(a: __m128d, b: __m128d) -> i32;
3308    #[link_name = "llvm.x86.sse2.ucomilt.sd"]
3309    fn ucomiltsd(a: __m128d, b: __m128d) -> i32;
3310    #[link_name = "llvm.x86.sse2.ucomile.sd"]
3311    fn ucomilesd(a: __m128d, b: __m128d) -> i32;
3312    #[link_name = "llvm.x86.sse2.ucomigt.sd"]
3313    fn ucomigtsd(a: __m128d, b: __m128d) -> i32;
3314    #[link_name = "llvm.x86.sse2.ucomige.sd"]
3315    fn ucomigesd(a: __m128d, b: __m128d) -> i32;
3316    #[link_name = "llvm.x86.sse2.ucomineq.sd"]
3317    fn ucomineqsd(a: __m128d, b: __m128d) -> i32;
3318    #[link_name = "llvm.x86.sse2.cvtpd2dq"]
3319    fn cvtpd2dq(a: __m128d) -> i32x4;
3320    #[link_name = "llvm.x86.sse2.cvtsd2si"]
3321    fn cvtsd2si(a: __m128d) -> i32;
3322    #[link_name = "llvm.x86.sse2.cvtsd2ss"]
3323    fn cvtsd2ss(a: __m128, b: __m128d) -> __m128;
3324    #[link_name = "llvm.x86.sse2.cvttpd2dq"]
3325    fn cvttpd2dq(a: __m128d) -> i32x4;
3326    #[link_name = "llvm.x86.sse2.cvttsd2si"]
3327    fn cvttsd2si(a: __m128d) -> i32;
3328    #[link_name = "llvm.x86.sse2.cvttps2dq"]
3329    fn cvttps2dq(a: __m128) -> i32x4;
3330}
3331
3332#[cfg(test)]
3333mod tests {
3334    use crate::core_arch::assert_eq_const as assert_eq;
3335    use crate::{
3336        core_arch::{simd::*, x86::*},
3337        hint::black_box,
3338    };
3339    use std::{boxed, f32, f64, mem, ptr};
3340    use stdarch_test::simd_test;
3341
3342    const NAN: f64 = f64::NAN;
3343
3344    #[test]
3345    fn test_mm_pause() {
3346        _mm_pause()
3347    }
3348
3349    #[simd_test(enable = "sse2")]
3350    fn test_mm_clflush() {
3351        let x = 0_u8;
3352        unsafe {
3353            _mm_clflush(ptr::addr_of!(x));
3354        }
3355    }
3356
3357    #[simd_test(enable = "sse2")]
3358    // Miri cannot support this until it is clear how it fits in the Rust memory model
3359    #[cfg_attr(miri, ignore)]
3360    fn test_mm_lfence() {
3361        _mm_lfence();
3362    }
3363
3364    #[simd_test(enable = "sse2")]
3365    // Miri cannot support this until it is clear how it fits in the Rust memory model
3366    #[cfg_attr(miri, ignore)]
3367    fn test_mm_mfence() {
3368        _mm_mfence();
3369    }
3370
3371    #[simd_test(enable = "sse2")]
3372    const fn test_mm_add_epi8() {
3373        let a = _mm_setr_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
3374        #[rustfmt::skip]
3375        let b = _mm_setr_epi8(
3376            16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
3377        );
3378        let r = _mm_add_epi8(a, b);
3379        #[rustfmt::skip]
3380        let e = _mm_setr_epi8(
3381            16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46,
3382        );
3383        assert_eq_m128i(r, e);
3384    }
3385
3386    #[simd_test(enable = "sse2")]
3387    fn test_mm_add_epi8_overflow() {
3388        let a = _mm_set1_epi8(0x7F);
3389        let b = _mm_set1_epi8(1);
3390        let r = _mm_add_epi8(a, b);
3391        assert_eq_m128i(r, _mm_set1_epi8(-128));
3392    }
3393
3394    #[simd_test(enable = "sse2")]
3395    const fn test_mm_add_epi16() {
3396        let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7);
3397        let b = _mm_setr_epi16(8, 9, 10, 11, 12, 13, 14, 15);
3398        let r = _mm_add_epi16(a, b);
3399        let e = _mm_setr_epi16(8, 10, 12, 14, 16, 18, 20, 22);
3400        assert_eq_m128i(r, e);
3401    }
3402
3403    #[simd_test(enable = "sse2")]
3404    const fn test_mm_add_epi32() {
3405        let a = _mm_setr_epi32(0, 1, 2, 3);
3406        let b = _mm_setr_epi32(4, 5, 6, 7);
3407        let r = _mm_add_epi32(a, b);
3408        let e = _mm_setr_epi32(4, 6, 8, 10);
3409        assert_eq_m128i(r, e);
3410    }
3411
3412    #[simd_test(enable = "sse2")]
3413    const fn test_mm_add_epi64() {
3414        let a = _mm_setr_epi64x(0, 1);
3415        let b = _mm_setr_epi64x(2, 3);
3416        let r = _mm_add_epi64(a, b);
3417        let e = _mm_setr_epi64x(2, 4);
3418        assert_eq_m128i(r, e);
3419    }
3420
3421    #[simd_test(enable = "sse2")]
3422    const fn test_mm_adds_epi8() {
3423        let a = _mm_setr_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
3424        #[rustfmt::skip]
3425        let b = _mm_setr_epi8(
3426            16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
3427        );
3428        let r = _mm_adds_epi8(a, b);
3429        #[rustfmt::skip]
3430        let e = _mm_setr_epi8(
3431            16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46,
3432        );
3433        assert_eq_m128i(r, e);
3434    }
3435
3436    #[simd_test(enable = "sse2")]
3437    fn test_mm_adds_epi8_saturate_positive() {
3438        let a = _mm_set1_epi8(0x7F);
3439        let b = _mm_set1_epi8(1);
3440        let r = _mm_adds_epi8(a, b);
3441        assert_eq_m128i(r, a);
3442    }
3443
3444    #[simd_test(enable = "sse2")]
3445    fn test_mm_adds_epi8_saturate_negative() {
3446        let a = _mm_set1_epi8(-0x80);
3447        let b = _mm_set1_epi8(-1);
3448        let r = _mm_adds_epi8(a, b);
3449        assert_eq_m128i(r, a);
3450    }
3451
3452    #[simd_test(enable = "sse2")]
3453    const fn test_mm_adds_epi16() {
3454        let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7);
3455        let b = _mm_setr_epi16(8, 9, 10, 11, 12, 13, 14, 15);
3456        let r = _mm_adds_epi16(a, b);
3457        let e = _mm_setr_epi16(8, 10, 12, 14, 16, 18, 20, 22);
3458        assert_eq_m128i(r, e);
3459    }
3460
3461    #[simd_test(enable = "sse2")]
3462    fn test_mm_adds_epi16_saturate_positive() {
3463        let a = _mm_set1_epi16(0x7FFF);
3464        let b = _mm_set1_epi16(1);
3465        let r = _mm_adds_epi16(a, b);
3466        assert_eq_m128i(r, a);
3467    }
3468
3469    #[simd_test(enable = "sse2")]
3470    fn test_mm_adds_epi16_saturate_negative() {
3471        let a = _mm_set1_epi16(-0x8000);
3472        let b = _mm_set1_epi16(-1);
3473        let r = _mm_adds_epi16(a, b);
3474        assert_eq_m128i(r, a);
3475    }
3476
3477    #[simd_test(enable = "sse2")]
3478    const fn test_mm_adds_epu8() {
3479        let a = _mm_setr_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
3480        #[rustfmt::skip]
3481        let b = _mm_setr_epi8(
3482            16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
3483        );
3484        let r = _mm_adds_epu8(a, b);
3485        #[rustfmt::skip]
3486        let e = _mm_setr_epi8(
3487            16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46,
3488        );
3489        assert_eq_m128i(r, e);
3490    }
3491
3492    #[simd_test(enable = "sse2")]
3493    fn test_mm_adds_epu8_saturate() {
3494        let a = _mm_set1_epi8(!0);
3495        let b = _mm_set1_epi8(1);
3496        let r = _mm_adds_epu8(a, b);
3497        assert_eq_m128i(r, a);
3498    }
3499
3500    #[simd_test(enable = "sse2")]
3501    const fn test_mm_adds_epu16() {
3502        let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7);
3503        let b = _mm_setr_epi16(8, 9, 10, 11, 12, 13, 14, 15);
3504        let r = _mm_adds_epu16(a, b);
3505        let e = _mm_setr_epi16(8, 10, 12, 14, 16, 18, 20, 22);
3506        assert_eq_m128i(r, e);
3507    }
3508
3509    #[simd_test(enable = "sse2")]
3510    fn test_mm_adds_epu16_saturate() {
3511        let a = _mm_set1_epi16(!0);
3512        let b = _mm_set1_epi16(1);
3513        let r = _mm_adds_epu16(a, b);
3514        assert_eq_m128i(r, a);
3515    }
3516
3517    #[simd_test(enable = "sse2")]
3518    const fn test_mm_avg_epu8() {
3519        let (a, b) = (_mm_set1_epi8(3), _mm_set1_epi8(9));
3520        let r = _mm_avg_epu8(a, b);
3521        assert_eq_m128i(r, _mm_set1_epi8(6));
3522    }
3523
3524    #[simd_test(enable = "sse2")]
3525    const fn test_mm_avg_epu16() {
3526        let (a, b) = (_mm_set1_epi16(3), _mm_set1_epi16(9));
3527        let r = _mm_avg_epu16(a, b);
3528        assert_eq_m128i(r, _mm_set1_epi16(6));
3529    }
3530
3531    #[simd_test(enable = "sse2")]
3532    fn test_mm_madd_epi16() {
3533        let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8);
3534        let b = _mm_setr_epi16(9, 10, 11, 12, 13, 14, 15, 16);
3535        let r = _mm_madd_epi16(a, b);
3536        let e = _mm_setr_epi32(29, 81, 149, 233);
3537        assert_eq_m128i(r, e);
3538
3539        // Test large values.
3540        // MIN*MIN+MIN*MIN will overflow into i32::MIN.
3541        let a = _mm_setr_epi16(
3542            i16::MAX,
3543            i16::MAX,
3544            i16::MIN,
3545            i16::MIN,
3546            i16::MIN,
3547            i16::MAX,
3548            0,
3549            0,
3550        );
3551        let b = _mm_setr_epi16(
3552            i16::MAX,
3553            i16::MAX,
3554            i16::MIN,
3555            i16::MIN,
3556            i16::MAX,
3557            i16::MIN,
3558            0,
3559            0,
3560        );
3561        let r = _mm_madd_epi16(a, b);
3562        let e = _mm_setr_epi32(0x7FFE0002, i32::MIN, -0x7FFF0000, 0);
3563        assert_eq_m128i(r, e);
3564    }
3565
3566    #[simd_test(enable = "sse2")]
3567    const fn test_mm_max_epi16() {
3568        let a = _mm_set1_epi16(1);
3569        let b = _mm_set1_epi16(-1);
3570        let r = _mm_max_epi16(a, b);
3571        assert_eq_m128i(r, a);
3572    }
3573
3574    #[simd_test(enable = "sse2")]
3575    const fn test_mm_max_epu8() {
3576        let a = _mm_set1_epi8(1);
3577        let b = _mm_set1_epi8(!0);
3578        let r = _mm_max_epu8(a, b);
3579        assert_eq_m128i(r, b);
3580    }
3581
3582    #[simd_test(enable = "sse2")]
3583    const fn test_mm_min_epi16() {
3584        let a = _mm_set1_epi16(1);
3585        let b = _mm_set1_epi16(-1);
3586        let r = _mm_min_epi16(a, b);
3587        assert_eq_m128i(r, b);
3588    }
3589
3590    #[simd_test(enable = "sse2")]
3591    const fn test_mm_min_epu8() {
3592        let a = _mm_set1_epi8(1);
3593        let b = _mm_set1_epi8(!0);
3594        let r = _mm_min_epu8(a, b);
3595        assert_eq_m128i(r, a);
3596    }
3597
3598    #[simd_test(enable = "sse2")]
3599    const fn test_mm_mulhi_epi16() {
3600        let (a, b) = (_mm_set1_epi16(1000), _mm_set1_epi16(-1001));
3601        let r = _mm_mulhi_epi16(a, b);
3602        assert_eq_m128i(r, _mm_set1_epi16(-16));
3603    }
3604
3605    #[simd_test(enable = "sse2")]
3606    const fn test_mm_mulhi_epu16() {
3607        let (a, b) = (_mm_set1_epi16(1000), _mm_set1_epi16(1001));
3608        let r = _mm_mulhi_epu16(a, b);
3609        assert_eq_m128i(r, _mm_set1_epi16(15));
3610    }
3611
3612    #[simd_test(enable = "sse2")]
3613    const fn test_mm_mullo_epi16() {
3614        let (a, b) = (_mm_set1_epi16(1000), _mm_set1_epi16(-1001));
3615        let r = _mm_mullo_epi16(a, b);
3616        assert_eq_m128i(r, _mm_set1_epi16(-17960));
3617    }
3618
3619    #[simd_test(enable = "sse2")]
3620    const fn test_mm_mul_epu32() {
3621        let a = _mm_setr_epi64x(1_000_000_000, 1 << 34);
3622        let b = _mm_setr_epi64x(1_000_000_000, 1 << 35);
3623        let r = _mm_mul_epu32(a, b);
3624        let e = _mm_setr_epi64x(1_000_000_000 * 1_000_000_000, 0);
3625        assert_eq_m128i(r, e);
3626    }
3627
3628    #[simd_test(enable = "sse2")]
3629    fn test_mm_sad_epu8() {
3630        #[rustfmt::skip]
3631        let a = _mm_setr_epi8(
3632            255u8 as i8, 254u8 as i8, 253u8 as i8, 252u8 as i8,
3633            1, 2, 3, 4,
3634            155u8 as i8, 154u8 as i8, 153u8 as i8, 152u8 as i8,
3635            1, 2, 3, 4,
3636        );
3637        let b = _mm_setr_epi8(0, 0, 0, 0, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2);
3638        let r = _mm_sad_epu8(a, b);
3639        let e = _mm_setr_epi64x(1020, 614);
3640        assert_eq_m128i(r, e);
3641    }
3642
3643    #[simd_test(enable = "sse2")]
3644    const fn test_mm_sub_epi8() {
3645        let (a, b) = (_mm_set1_epi8(5), _mm_set1_epi8(6));
3646        let r = _mm_sub_epi8(a, b);
3647        assert_eq_m128i(r, _mm_set1_epi8(-1));
3648    }
3649
3650    #[simd_test(enable = "sse2")]
3651    const fn test_mm_sub_epi16() {
3652        let (a, b) = (_mm_set1_epi16(5), _mm_set1_epi16(6));
3653        let r = _mm_sub_epi16(a, b);
3654        assert_eq_m128i(r, _mm_set1_epi16(-1));
3655    }
3656
3657    #[simd_test(enable = "sse2")]
3658    const fn test_mm_sub_epi32() {
3659        let (a, b) = (_mm_set1_epi32(5), _mm_set1_epi32(6));
3660        let r = _mm_sub_epi32(a, b);
3661        assert_eq_m128i(r, _mm_set1_epi32(-1));
3662    }
3663
3664    #[simd_test(enable = "sse2")]
3665    const fn test_mm_sub_epi64() {
3666        let (a, b) = (_mm_set1_epi64x(5), _mm_set1_epi64x(6));
3667        let r = _mm_sub_epi64(a, b);
3668        assert_eq_m128i(r, _mm_set1_epi64x(-1));
3669    }
3670
3671    #[simd_test(enable = "sse2")]
3672    const fn test_mm_subs_epi8() {
3673        let (a, b) = (_mm_set1_epi8(5), _mm_set1_epi8(2));
3674        let r = _mm_subs_epi8(a, b);
3675        assert_eq_m128i(r, _mm_set1_epi8(3));
3676    }
3677
3678    #[simd_test(enable = "sse2")]
3679    fn test_mm_subs_epi8_saturate_positive() {
3680        let a = _mm_set1_epi8(0x7F);
3681        let b = _mm_set1_epi8(-1);
3682        let r = _mm_subs_epi8(a, b);
3683        assert_eq_m128i(r, a);
3684    }
3685
3686    #[simd_test(enable = "sse2")]
3687    fn test_mm_subs_epi8_saturate_negative() {
3688        let a = _mm_set1_epi8(-0x80);
3689        let b = _mm_set1_epi8(1);
3690        let r = _mm_subs_epi8(a, b);
3691        assert_eq_m128i(r, a);
3692    }
3693
3694    #[simd_test(enable = "sse2")]
3695    const fn test_mm_subs_epi16() {
3696        let (a, b) = (_mm_set1_epi16(5), _mm_set1_epi16(2));
3697        let r = _mm_subs_epi16(a, b);
3698        assert_eq_m128i(r, _mm_set1_epi16(3));
3699    }
3700
3701    #[simd_test(enable = "sse2")]
3702    fn test_mm_subs_epi16_saturate_positive() {
3703        let a = _mm_set1_epi16(0x7FFF);
3704        let b = _mm_set1_epi16(-1);
3705        let r = _mm_subs_epi16(a, b);
3706        assert_eq_m128i(r, a);
3707    }
3708
3709    #[simd_test(enable = "sse2")]
3710    fn test_mm_subs_epi16_saturate_negative() {
3711        let a = _mm_set1_epi16(-0x8000);
3712        let b = _mm_set1_epi16(1);
3713        let r = _mm_subs_epi16(a, b);
3714        assert_eq_m128i(r, a);
3715    }
3716
3717    #[simd_test(enable = "sse2")]
3718    const fn test_mm_subs_epu8() {
3719        let (a, b) = (_mm_set1_epi8(5), _mm_set1_epi8(2));
3720        let r = _mm_subs_epu8(a, b);
3721        assert_eq_m128i(r, _mm_set1_epi8(3));
3722    }
3723
3724    #[simd_test(enable = "sse2")]
3725    fn test_mm_subs_epu8_saturate() {
3726        let a = _mm_set1_epi8(0);
3727        let b = _mm_set1_epi8(1);
3728        let r = _mm_subs_epu8(a, b);
3729        assert_eq_m128i(r, a);
3730    }
3731
3732    #[simd_test(enable = "sse2")]
3733    const fn test_mm_subs_epu16() {
3734        let (a, b) = (_mm_set1_epi16(5), _mm_set1_epi16(2));
3735        let r = _mm_subs_epu16(a, b);
3736        assert_eq_m128i(r, _mm_set1_epi16(3));
3737    }
3738
3739    #[simd_test(enable = "sse2")]
3740    fn test_mm_subs_epu16_saturate() {
3741        let a = _mm_set1_epi16(0);
3742        let b = _mm_set1_epi16(1);
3743        let r = _mm_subs_epu16(a, b);
3744        assert_eq_m128i(r, a);
3745    }
3746
3747    #[simd_test(enable = "sse2")]
3748    const fn test_mm_slli_si128() {
3749        #[rustfmt::skip]
3750        let a = _mm_setr_epi8(
3751            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
3752        );
3753        let r = _mm_slli_si128::<1>(a);
3754        let e = _mm_setr_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
3755        assert_eq_m128i(r, e);
3756
3757        #[rustfmt::skip]
3758        let a = _mm_setr_epi8(
3759            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
3760        );
3761        let r = _mm_slli_si128::<15>(a);
3762        let e = _mm_setr_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
3763        assert_eq_m128i(r, e);
3764
3765        #[rustfmt::skip]
3766        let a = _mm_setr_epi8(
3767            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
3768        );
3769        let r = _mm_slli_si128::<16>(a);
3770        assert_eq_m128i(r, _mm_set1_epi8(0));
3771    }
3772
3773    #[simd_test(enable = "sse2")]
3774    const fn test_mm_slli_epi16() {
3775        let a = _mm_setr_epi16(0xCC, -0xCC, 0xDD, -0xDD, 0xEE, -0xEE, 0xFF, -0xFF);
3776        let r = _mm_slli_epi16::<4>(a);
3777        assert_eq_m128i(
3778            r,
3779            _mm_setr_epi16(0xCC0, -0xCC0, 0xDD0, -0xDD0, 0xEE0, -0xEE0, 0xFF0, -0xFF0),
3780        );
3781        let r = _mm_slli_epi16::<16>(a);
3782        assert_eq_m128i(r, _mm_set1_epi16(0));
3783    }
3784
3785    #[simd_test(enable = "sse2")]
3786    fn test_mm_sll_epi16() {
3787        let a = _mm_setr_epi16(0xCC, -0xCC, 0xDD, -0xDD, 0xEE, -0xEE, 0xFF, -0xFF);
3788        let r = _mm_sll_epi16(a, _mm_set_epi64x(0, 4));
3789        assert_eq_m128i(
3790            r,
3791            _mm_setr_epi16(0xCC0, -0xCC0, 0xDD0, -0xDD0, 0xEE0, -0xEE0, 0xFF0, -0xFF0),
3792        );
3793        let r = _mm_sll_epi16(a, _mm_set_epi64x(4, 0));
3794        assert_eq_m128i(r, a);
3795        let r = _mm_sll_epi16(a, _mm_set_epi64x(0, 16));
3796        assert_eq_m128i(r, _mm_set1_epi16(0));
3797        let r = _mm_sll_epi16(a, _mm_set_epi64x(0, i64::MAX));
3798        assert_eq_m128i(r, _mm_set1_epi16(0));
3799    }
3800
3801    #[simd_test(enable = "sse2")]
3802    const fn test_mm_slli_epi32() {
3803        let a = _mm_setr_epi32(0xEEEE, -0xEEEE, 0xFFFF, -0xFFFF);
3804        let r = _mm_slli_epi32::<4>(a);
3805        assert_eq_m128i(r, _mm_setr_epi32(0xEEEE0, -0xEEEE0, 0xFFFF0, -0xFFFF0));
3806        let r = _mm_slli_epi32::<32>(a);
3807        assert_eq_m128i(r, _mm_set1_epi32(0));
3808    }
3809
3810    #[simd_test(enable = "sse2")]
3811    fn test_mm_sll_epi32() {
3812        let a = _mm_setr_epi32(0xEEEE, -0xEEEE, 0xFFFF, -0xFFFF);
3813        let r = _mm_sll_epi32(a, _mm_set_epi64x(0, 4));
3814        assert_eq_m128i(r, _mm_setr_epi32(0xEEEE0, -0xEEEE0, 0xFFFF0, -0xFFFF0));
3815        let r = _mm_sll_epi32(a, _mm_set_epi64x(4, 0));
3816        assert_eq_m128i(r, a);
3817        let r = _mm_sll_epi32(a, _mm_set_epi64x(0, 32));
3818        assert_eq_m128i(r, _mm_set1_epi32(0));
3819        let r = _mm_sll_epi32(a, _mm_set_epi64x(0, i64::MAX));
3820        assert_eq_m128i(r, _mm_set1_epi32(0));
3821    }
3822
3823    #[simd_test(enable = "sse2")]
3824    const fn test_mm_slli_epi64() {
3825        let a = _mm_set_epi64x(0xFFFFFFFF, -0xFFFFFFFF);
3826        let r = _mm_slli_epi64::<4>(a);
3827        assert_eq_m128i(r, _mm_set_epi64x(0xFFFFFFFF0, -0xFFFFFFFF0));
3828        let r = _mm_slli_epi64::<64>(a);
3829        assert_eq_m128i(r, _mm_set1_epi64x(0));
3830    }
3831
3832    #[simd_test(enable = "sse2")]
3833    fn test_mm_sll_epi64() {
3834        let a = _mm_set_epi64x(0xFFFFFFFF, -0xFFFFFFFF);
3835        let r = _mm_sll_epi64(a, _mm_set_epi64x(0, 4));
3836        assert_eq_m128i(r, _mm_set_epi64x(0xFFFFFFFF0, -0xFFFFFFFF0));
3837        let r = _mm_sll_epi64(a, _mm_set_epi64x(4, 0));
3838        assert_eq_m128i(r, a);
3839        let r = _mm_sll_epi64(a, _mm_set_epi64x(0, 64));
3840        assert_eq_m128i(r, _mm_set1_epi64x(0));
3841        let r = _mm_sll_epi64(a, _mm_set_epi64x(0, i64::MAX));
3842        assert_eq_m128i(r, _mm_set1_epi64x(0));
3843    }
3844
3845    #[simd_test(enable = "sse2")]
3846    const fn test_mm_srai_epi16() {
3847        let a = _mm_setr_epi16(0xCC, -0xCC, 0xDD, -0xDD, 0xEE, -0xEE, 0xFF, -0xFF);
3848        let r = _mm_srai_epi16::<4>(a);
3849        assert_eq_m128i(
3850            r,
3851            _mm_setr_epi16(0xC, -0xD, 0xD, -0xE, 0xE, -0xF, 0xF, -0x10),
3852        );
3853        let r = _mm_srai_epi16::<16>(a);
3854        assert_eq_m128i(r, _mm_setr_epi16(0, -1, 0, -1, 0, -1, 0, -1));
3855    }
3856
3857    #[simd_test(enable = "sse2")]
3858    fn test_mm_sra_epi16() {
3859        let a = _mm_setr_epi16(0xCC, -0xCC, 0xDD, -0xDD, 0xEE, -0xEE, 0xFF, -0xFF);
3860        let r = _mm_sra_epi16(a, _mm_set_epi64x(0, 4));
3861        assert_eq_m128i(
3862            r,
3863            _mm_setr_epi16(0xC, -0xD, 0xD, -0xE, 0xE, -0xF, 0xF, -0x10),
3864        );
3865        let r = _mm_sra_epi16(a, _mm_set_epi64x(4, 0));
3866        assert_eq_m128i(r, a);
3867        let r = _mm_sra_epi16(a, _mm_set_epi64x(0, 16));
3868        assert_eq_m128i(r, _mm_setr_epi16(0, -1, 0, -1, 0, -1, 0, -1));
3869        let r = _mm_sra_epi16(a, _mm_set_epi64x(0, i64::MAX));
3870        assert_eq_m128i(r, _mm_setr_epi16(0, -1, 0, -1, 0, -1, 0, -1));
3871    }
3872
3873    #[simd_test(enable = "sse2")]
3874    const fn test_mm_srai_epi32() {
3875        let a = _mm_setr_epi32(0xEEEE, -0xEEEE, 0xFFFF, -0xFFFF);
3876        let r = _mm_srai_epi32::<4>(a);
3877        assert_eq_m128i(r, _mm_setr_epi32(0xEEE, -0xEEF, 0xFFF, -0x1000));
3878        let r = _mm_srai_epi32::<32>(a);
3879        assert_eq_m128i(r, _mm_setr_epi32(0, -1, 0, -1));
3880    }
3881
3882    #[simd_test(enable = "sse2")]
3883    fn test_mm_sra_epi32() {
3884        let a = _mm_setr_epi32(0xEEEE, -0xEEEE, 0xFFFF, -0xFFFF);
3885        let r = _mm_sra_epi32(a, _mm_set_epi64x(0, 4));
3886        assert_eq_m128i(r, _mm_setr_epi32(0xEEE, -0xEEF, 0xFFF, -0x1000));
3887        let r = _mm_sra_epi32(a, _mm_set_epi64x(4, 0));
3888        assert_eq_m128i(r, a);
3889        let r = _mm_sra_epi32(a, _mm_set_epi64x(0, 32));
3890        assert_eq_m128i(r, _mm_setr_epi32(0, -1, 0, -1));
3891        let r = _mm_sra_epi32(a, _mm_set_epi64x(0, i64::MAX));
3892        assert_eq_m128i(r, _mm_setr_epi32(0, -1, 0, -1));
3893    }
3894
3895    #[simd_test(enable = "sse2")]
3896    const fn test_mm_srli_si128() {
3897        #[rustfmt::skip]
3898        let a = _mm_setr_epi8(
3899            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
3900        );
3901        let r = _mm_srli_si128::<1>(a);
3902        #[rustfmt::skip]
3903        let e = _mm_setr_epi8(
3904            2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0,
3905        );
3906        assert_eq_m128i(r, e);
3907
3908        #[rustfmt::skip]
3909        let a = _mm_setr_epi8(
3910            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
3911        );
3912        let r = _mm_srli_si128::<15>(a);
3913        let e = _mm_setr_epi8(16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
3914        assert_eq_m128i(r, e);
3915
3916        #[rustfmt::skip]
3917        let a = _mm_setr_epi8(
3918            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
3919        );
3920        let r = _mm_srli_si128::<16>(a);
3921        assert_eq_m128i(r, _mm_set1_epi8(0));
3922    }
3923
3924    #[simd_test(enable = "sse2")]
3925    const fn test_mm_srli_epi16() {
3926        let a = _mm_setr_epi16(0xCC, -0xCC, 0xDD, -0xDD, 0xEE, -0xEE, 0xFF, -0xFF);
3927        let r = _mm_srli_epi16::<4>(a);
3928        assert_eq_m128i(
3929            r,
3930            _mm_setr_epi16(0xC, 0xFF3, 0xD, 0xFF2, 0xE, 0xFF1, 0xF, 0xFF0),
3931        );
3932        let r = _mm_srli_epi16::<16>(a);
3933        assert_eq_m128i(r, _mm_set1_epi16(0));
3934    }
3935
3936    #[simd_test(enable = "sse2")]
3937    fn test_mm_srl_epi16() {
3938        let a = _mm_setr_epi16(0xCC, -0xCC, 0xDD, -0xDD, 0xEE, -0xEE, 0xFF, -0xFF);
3939        let r = _mm_srl_epi16(a, _mm_set_epi64x(0, 4));
3940        assert_eq_m128i(
3941            r,
3942            _mm_setr_epi16(0xC, 0xFF3, 0xD, 0xFF2, 0xE, 0xFF1, 0xF, 0xFF0),
3943        );
3944        let r = _mm_srl_epi16(a, _mm_set_epi64x(4, 0));
3945        assert_eq_m128i(r, a);
3946        let r = _mm_srl_epi16(a, _mm_set_epi64x(0, 16));
3947        assert_eq_m128i(r, _mm_set1_epi16(0));
3948        let r = _mm_srl_epi16(a, _mm_set_epi64x(0, i64::MAX));
3949        assert_eq_m128i(r, _mm_set1_epi16(0));
3950    }
3951
3952    #[simd_test(enable = "sse2")]
3953    const fn test_mm_srli_epi32() {
3954        let a = _mm_setr_epi32(0xEEEE, -0xEEEE, 0xFFFF, -0xFFFF);
3955        let r = _mm_srli_epi32::<4>(a);
3956        assert_eq_m128i(r, _mm_setr_epi32(0xEEE, 0xFFFF111, 0xFFF, 0xFFFF000));
3957        let r = _mm_srli_epi32::<32>(a);
3958        assert_eq_m128i(r, _mm_set1_epi32(0));
3959    }
3960
3961    #[simd_test(enable = "sse2")]
3962    fn test_mm_srl_epi32() {
3963        let a = _mm_setr_epi32(0xEEEE, -0xEEEE, 0xFFFF, -0xFFFF);
3964        let r = _mm_srl_epi32(a, _mm_set_epi64x(0, 4));
3965        assert_eq_m128i(r, _mm_setr_epi32(0xEEE, 0xFFFF111, 0xFFF, 0xFFFF000));
3966        let r = _mm_srl_epi32(a, _mm_set_epi64x(4, 0));
3967        assert_eq_m128i(r, a);
3968        let r = _mm_srl_epi32(a, _mm_set_epi64x(0, 32));
3969        assert_eq_m128i(r, _mm_set1_epi32(0));
3970        let r = _mm_srl_epi32(a, _mm_set_epi64x(0, i64::MAX));
3971        assert_eq_m128i(r, _mm_set1_epi32(0));
3972    }
3973
3974    #[simd_test(enable = "sse2")]
3975    const fn test_mm_srli_epi64() {
3976        let a = _mm_set_epi64x(0xFFFFFFFF, -0xFFFFFFFF);
3977        let r = _mm_srli_epi64::<4>(a);
3978        assert_eq_m128i(r, _mm_set_epi64x(0xFFFFFFF, 0xFFFFFFFF0000000));
3979        let r = _mm_srli_epi64::<64>(a);
3980        assert_eq_m128i(r, _mm_set1_epi64x(0));
3981    }
3982
3983    #[simd_test(enable = "sse2")]
3984    fn test_mm_srl_epi64() {
3985        let a = _mm_set_epi64x(0xFFFFFFFF, -0xFFFFFFFF);
3986        let r = _mm_srl_epi64(a, _mm_set_epi64x(0, 4));
3987        assert_eq_m128i(r, _mm_set_epi64x(0xFFFFFFF, 0xFFFFFFFF0000000));
3988        let r = _mm_srl_epi64(a, _mm_set_epi64x(4, 0));
3989        assert_eq_m128i(r, a);
3990        let r = _mm_srl_epi64(a, _mm_set_epi64x(0, 64));
3991        assert_eq_m128i(r, _mm_set1_epi64x(0));
3992        let r = _mm_srl_epi64(a, _mm_set_epi64x(0, i64::MAX));
3993        assert_eq_m128i(r, _mm_set1_epi64x(0));
3994    }
3995
3996    #[simd_test(enable = "sse2")]
3997    const fn test_mm_and_si128() {
3998        let a = _mm_set1_epi8(5);
3999        let b = _mm_set1_epi8(3);
4000        let r = _mm_and_si128(a, b);
4001        assert_eq_m128i(r, _mm_set1_epi8(1));
4002    }
4003
4004    #[simd_test(enable = "sse2")]
4005    const fn test_mm_andnot_si128() {
4006        let a = _mm_set1_epi8(5);
4007        let b = _mm_set1_epi8(3);
4008        let r = _mm_andnot_si128(a, b);
4009        assert_eq_m128i(r, _mm_set1_epi8(2));
4010    }
4011
4012    #[simd_test(enable = "sse2")]
4013    const fn test_mm_or_si128() {
4014        let a = _mm_set1_epi8(5);
4015        let b = _mm_set1_epi8(3);
4016        let r = _mm_or_si128(a, b);
4017        assert_eq_m128i(r, _mm_set1_epi8(7));
4018    }
4019
4020    #[simd_test(enable = "sse2")]
4021    const fn test_mm_xor_si128() {
4022        let a = _mm_set1_epi8(5);
4023        let b = _mm_set1_epi8(3);
4024        let r = _mm_xor_si128(a, b);
4025        assert_eq_m128i(r, _mm_set1_epi8(6));
4026    }
4027
4028    #[simd_test(enable = "sse2")]
4029    const fn test_mm_cmpeq_epi8() {
4030        let a = _mm_setr_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
4031        let b = _mm_setr_epi8(15, 14, 2, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
4032        let r = _mm_cmpeq_epi8(a, b);
4033        #[rustfmt::skip]
4034        assert_eq_m128i(
4035            r,
4036            _mm_setr_epi8(
4037                0, 0, 0xFFu8 as i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
4038            )
4039        );
4040    }
4041
4042    #[simd_test(enable = "sse2")]
4043    const fn test_mm_cmpeq_epi16() {
4044        let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7);
4045        let b = _mm_setr_epi16(7, 6, 2, 4, 3, 2, 1, 0);
4046        let r = _mm_cmpeq_epi16(a, b);
4047        assert_eq_m128i(r, _mm_setr_epi16(0, 0, !0, 0, 0, 0, 0, 0));
4048    }
4049
4050    #[simd_test(enable = "sse2")]
4051    const fn test_mm_cmpeq_epi32() {
4052        let a = _mm_setr_epi32(0, 1, 2, 3);
4053        let b = _mm_setr_epi32(3, 2, 2, 0);
4054        let r = _mm_cmpeq_epi32(a, b);
4055        assert_eq_m128i(r, _mm_setr_epi32(0, 0, !0, 0));
4056    }
4057
4058    #[simd_test(enable = "sse2")]
4059    const fn test_mm_cmpgt_epi8() {
4060        let a = _mm_set_epi8(5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
4061        let b = _mm_set1_epi8(0);
4062        let r = _mm_cmpgt_epi8(a, b);
4063        let e = _mm_set_epi8(!0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
4064        assert_eq_m128i(r, e);
4065    }
4066
4067    #[simd_test(enable = "sse2")]
4068    const fn test_mm_cmpgt_epi16() {
4069        let a = _mm_set_epi16(5, 0, 0, 0, 0, 0, 0, 0);
4070        let b = _mm_set1_epi16(0);
4071        let r = _mm_cmpgt_epi16(a, b);
4072        let e = _mm_set_epi16(!0, 0, 0, 0, 0, 0, 0, 0);
4073        assert_eq_m128i(r, e);
4074    }
4075
4076    #[simd_test(enable = "sse2")]
4077    const fn test_mm_cmpgt_epi32() {
4078        let a = _mm_set_epi32(5, 0, 0, 0);
4079        let b = _mm_set1_epi32(0);
4080        let r = _mm_cmpgt_epi32(a, b);
4081        assert_eq_m128i(r, _mm_set_epi32(!0, 0, 0, 0));
4082    }
4083
4084    #[simd_test(enable = "sse2")]
4085    const fn test_mm_cmplt_epi8() {
4086        let a = _mm_set1_epi8(0);
4087        let b = _mm_set_epi8(5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
4088        let r = _mm_cmplt_epi8(a, b);
4089        let e = _mm_set_epi8(!0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
4090        assert_eq_m128i(r, e);
4091    }
4092
4093    #[simd_test(enable = "sse2")]
4094    const fn test_mm_cmplt_epi16() {
4095        let a = _mm_set1_epi16(0);
4096        let b = _mm_set_epi16(5, 0, 0, 0, 0, 0, 0, 0);
4097        let r = _mm_cmplt_epi16(a, b);
4098        let e = _mm_set_epi16(!0, 0, 0, 0, 0, 0, 0, 0);
4099        assert_eq_m128i(r, e);
4100    }
4101
4102    #[simd_test(enable = "sse2")]
4103    const fn test_mm_cmplt_epi32() {
4104        let a = _mm_set1_epi32(0);
4105        let b = _mm_set_epi32(5, 0, 0, 0);
4106        let r = _mm_cmplt_epi32(a, b);
4107        assert_eq_m128i(r, _mm_set_epi32(!0, 0, 0, 0));
4108    }
4109
4110    #[simd_test(enable = "sse2")]
4111    const fn test_mm_cvtepi32_pd() {
4112        let a = _mm_set_epi32(35, 25, 15, 5);
4113        let r = _mm_cvtepi32_pd(a);
4114        assert_eq_m128d(r, _mm_setr_pd(5.0, 15.0));
4115    }
4116
4117    #[simd_test(enable = "sse2")]
4118    const fn test_mm_cvtsi32_sd() {
4119        let a = _mm_set1_pd(3.5);
4120        let r = _mm_cvtsi32_sd(a, 5);
4121        assert_eq_m128d(r, _mm_setr_pd(5.0, 3.5));
4122    }
4123
4124    #[simd_test(enable = "sse2")]
4125    const fn test_mm_cvtepi32_ps() {
4126        let a = _mm_setr_epi32(1, 2, 3, 4);
4127        let r = _mm_cvtepi32_ps(a);
4128        assert_eq_m128(r, _mm_setr_ps(1.0, 2.0, 3.0, 4.0));
4129    }
4130
4131    #[simd_test(enable = "sse2")]
4132    fn test_mm_cvtps_epi32() {
4133        let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
4134        let r = _mm_cvtps_epi32(a);
4135        assert_eq_m128i(r, _mm_setr_epi32(1, 2, 3, 4));
4136    }
4137
4138    #[simd_test(enable = "sse2")]
4139    const fn test_mm_cvtsi32_si128() {
4140        let r = _mm_cvtsi32_si128(5);
4141        assert_eq_m128i(r, _mm_setr_epi32(5, 0, 0, 0));
4142    }
4143
4144    #[simd_test(enable = "sse2")]
4145    const fn test_mm_cvtsi128_si32() {
4146        let r = _mm_cvtsi128_si32(_mm_setr_epi32(5, 0, 0, 0));
4147        assert_eq!(r, 5);
4148    }
4149
4150    #[simd_test(enable = "sse2")]
4151    const fn test_mm_set_epi64x() {
4152        let r = _mm_set_epi64x(0, 1);
4153        assert_eq_m128i(r, _mm_setr_epi64x(1, 0));
4154    }
4155
4156    #[simd_test(enable = "sse2")]
4157    const fn test_mm_set_epi32() {
4158        let r = _mm_set_epi32(0, 1, 2, 3);
4159        assert_eq_m128i(r, _mm_setr_epi32(3, 2, 1, 0));
4160    }
4161
4162    #[simd_test(enable = "sse2")]
4163    const fn test_mm_set_epi16() {
4164        let r = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7);
4165        assert_eq_m128i(r, _mm_setr_epi16(7, 6, 5, 4, 3, 2, 1, 0));
4166    }
4167
4168    #[simd_test(enable = "sse2")]
4169    const fn test_mm_set_epi8() {
4170        #[rustfmt::skip]
4171        let r = _mm_set_epi8(
4172            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
4173        );
4174        #[rustfmt::skip]
4175        let e = _mm_setr_epi8(
4176            15, 14, 13, 12, 11, 10, 9, 8,
4177            7, 6, 5, 4, 3, 2, 1, 0,
4178        );
4179        assert_eq_m128i(r, e);
4180    }
4181
4182    #[simd_test(enable = "sse2")]
4183    const fn test_mm_set1_epi64x() {
4184        let r = _mm_set1_epi64x(1);
4185        assert_eq_m128i(r, _mm_set1_epi64x(1));
4186    }
4187
4188    #[simd_test(enable = "sse2")]
4189    const fn test_mm_set1_epi32() {
4190        let r = _mm_set1_epi32(1);
4191        assert_eq_m128i(r, _mm_set1_epi32(1));
4192    }
4193
4194    #[simd_test(enable = "sse2")]
4195    const fn test_mm_set1_epi16() {
4196        let r = _mm_set1_epi16(1);
4197        assert_eq_m128i(r, _mm_set1_epi16(1));
4198    }
4199
4200    #[simd_test(enable = "sse2")]
4201    const fn test_mm_set1_epi8() {
4202        let r = _mm_set1_epi8(1);
4203        assert_eq_m128i(r, _mm_set1_epi8(1));
4204    }
4205
4206    #[simd_test(enable = "sse2")]
4207    const fn test_mm_setr_epi32() {
4208        let r = _mm_setr_epi32(0, 1, 2, 3);
4209        assert_eq_m128i(r, _mm_setr_epi32(0, 1, 2, 3));
4210    }
4211
4212    #[simd_test(enable = "sse2")]
4213    const fn test_mm_setr_epi16() {
4214        let r = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7);
4215        assert_eq_m128i(r, _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7));
4216    }
4217
4218    #[simd_test(enable = "sse2")]
4219    const fn test_mm_setr_epi8() {
4220        #[rustfmt::skip]
4221        let r = _mm_setr_epi8(
4222            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
4223        );
4224        #[rustfmt::skip]
4225        let e = _mm_setr_epi8(
4226            0, 1, 2, 3, 4, 5, 6, 7,
4227            8, 9, 10, 11, 12, 13, 14, 15,
4228        );
4229        assert_eq_m128i(r, e);
4230    }
4231
4232    #[simd_test(enable = "sse2")]
4233    const fn test_mm_setzero_si128() {
4234        let r = _mm_setzero_si128();
4235        assert_eq_m128i(r, _mm_set1_epi64x(0));
4236    }
4237
4238    #[simd_test(enable = "sse2")]
4239    const fn test_mm_loadl_epi64() {
4240        let a = _mm_setr_epi64x(6, 5);
4241        let r = unsafe { _mm_loadl_epi64(ptr::addr_of!(a)) };
4242        assert_eq_m128i(r, _mm_setr_epi64x(6, 0));
4243    }
4244
4245    #[simd_test(enable = "sse2")]
4246    const fn test_mm_load_si128() {
4247        let a = _mm_set_epi64x(5, 6);
4248        let r = unsafe { _mm_load_si128(ptr::addr_of!(a) as *const _) };
4249        assert_eq_m128i(a, r);
4250    }
4251
4252    #[simd_test(enable = "sse2")]
4253    const fn test_mm_loadu_si128() {
4254        let a = _mm_set_epi64x(5, 6);
4255        let r = unsafe { _mm_loadu_si128(ptr::addr_of!(a) as *const _) };
4256        assert_eq_m128i(a, r);
4257    }
4258
4259    #[simd_test(enable = "sse2")]
4260    // Miri cannot support this until it is clear how it fits in the Rust memory model
4261    // (non-temporal store)
4262    #[cfg_attr(miri, ignore)]
4263    fn test_mm_maskmoveu_si128() {
4264        let a = _mm_set1_epi8(9);
4265        #[rustfmt::skip]
4266        let mask = _mm_set_epi8(
4267            0, 0, 0x80u8 as i8, 0, 0, 0, 0, 0,
4268            0, 0, 0, 0, 0, 0, 0, 0,
4269        );
4270        let mut r = _mm_set1_epi8(0);
4271        unsafe {
4272            _mm_maskmoveu_si128(a, mask, ptr::addr_of_mut!(r) as *mut i8);
4273        }
4274        _mm_sfence();
4275        let e = _mm_set_epi8(0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
4276        assert_eq_m128i(r, e);
4277    }
4278
4279    #[simd_test(enable = "sse2")]
4280    const fn test_mm_store_si128() {
4281        let a = _mm_set1_epi8(9);
4282        let mut r = _mm_set1_epi8(0);
4283        unsafe {
4284            _mm_store_si128(&mut r, a);
4285        }
4286        assert_eq_m128i(r, a);
4287    }
4288
4289    #[simd_test(enable = "sse2")]
4290    const fn test_mm_storeu_si128() {
4291        let a = _mm_set1_epi8(9);
4292        let mut r = _mm_set1_epi8(0);
4293        unsafe {
4294            _mm_storeu_si128(&mut r, a);
4295        }
4296        assert_eq_m128i(r, a);
4297    }
4298
4299    #[simd_test(enable = "sse2")]
4300    const fn test_mm_storel_epi64() {
4301        let a = _mm_setr_epi64x(2, 9);
4302        let mut r = _mm_set1_epi8(0);
4303        unsafe {
4304            _mm_storel_epi64(&mut r, a);
4305        }
4306        assert_eq_m128i(r, _mm_setr_epi64x(2, 0));
4307    }
4308
4309    #[simd_test(enable = "sse2")]
4310    // Miri cannot support this until it is clear how it fits in the Rust memory model
4311    // (non-temporal store)
4312    #[cfg_attr(miri, ignore)]
4313    fn test_mm_stream_si128() {
4314        let a = _mm_setr_epi32(1, 2, 3, 4);
4315        let mut r = _mm_undefined_si128();
4316        unsafe {
4317            _mm_stream_si128(ptr::addr_of_mut!(r), a);
4318        }
4319        _mm_sfence();
4320        assert_eq_m128i(r, a);
4321    }
4322
4323    #[simd_test(enable = "sse2")]
4324    // Miri cannot support this until it is clear how it fits in the Rust memory model
4325    // (non-temporal store)
4326    #[cfg_attr(miri, ignore)]
4327    fn test_mm_stream_si32() {
4328        let a: i32 = 7;
4329        let mut mem = boxed::Box::<i32>::new(-1);
4330        unsafe {
4331            _mm_stream_si32(ptr::addr_of_mut!(*mem), a);
4332        }
4333        _mm_sfence();
4334        assert_eq!(a, *mem);
4335    }
4336
4337    #[simd_test(enable = "sse2")]
4338    const fn test_mm_move_epi64() {
4339        let a = _mm_setr_epi64x(5, 6);
4340        let r = _mm_move_epi64(a);
4341        assert_eq_m128i(r, _mm_setr_epi64x(5, 0));
4342    }
4343
4344    #[simd_test(enable = "sse2")]
4345    const fn test_mm_packs_epi16() {
4346        let a = _mm_setr_epi16(0x80, -0x81, 0, 0, 0, 0, 0, 0);
4347        let b = _mm_setr_epi16(0, 0, 0, 0, 0, 0, -0x81, 0x80);
4348        let r = _mm_packs_epi16(a, b);
4349        #[rustfmt::skip]
4350        assert_eq_m128i(
4351            r,
4352            _mm_setr_epi8(
4353                0x7F, -0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0x80, 0x7F
4354            )
4355        );
4356    }
4357
4358    #[simd_test(enable = "sse2")]
4359    const fn test_mm_packs_epi32() {
4360        let a = _mm_setr_epi32(0x8000, -0x8001, 0, 0);
4361        let b = _mm_setr_epi32(0, 0, -0x8001, 0x8000);
4362        let r = _mm_packs_epi32(a, b);
4363        assert_eq_m128i(
4364            r,
4365            _mm_setr_epi16(0x7FFF, -0x8000, 0, 0, 0, 0, -0x8000, 0x7FFF),
4366        );
4367    }
4368
4369    #[simd_test(enable = "sse2")]
4370    const fn test_mm_packus_epi16() {
4371        let a = _mm_setr_epi16(0x100, -1, 0, 0, 0, 0, 0, 0);
4372        let b = _mm_setr_epi16(0, 0, 0, 0, 0, 0, -1, 0x100);
4373        let r = _mm_packus_epi16(a, b);
4374        assert_eq_m128i(
4375            r,
4376            _mm_setr_epi8(!0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, !0),
4377        );
4378    }
4379
4380    #[simd_test(enable = "sse2")]
4381    const fn test_mm_extract_epi16() {
4382        let a = _mm_setr_epi16(-1, 1, 2, 3, 4, 5, 6, 7);
4383        let r1 = _mm_extract_epi16::<0>(a);
4384        let r2 = _mm_extract_epi16::<3>(a);
4385        assert_eq!(r1, 0xFFFF);
4386        assert_eq!(r2, 3);
4387    }
4388
4389    #[simd_test(enable = "sse2")]
4390    const fn test_mm_insert_epi16() {
4391        let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7);
4392        let r = _mm_insert_epi16::<0>(a, 9);
4393        let e = _mm_setr_epi16(9, 1, 2, 3, 4, 5, 6, 7);
4394        assert_eq_m128i(r, e);
4395    }
4396
4397    #[simd_test(enable = "sse2")]
4398    const fn test_mm_movemask_epi8() {
4399        #[rustfmt::skip]
4400        let a = _mm_setr_epi8(
4401            0b1000_0000u8 as i8, 0b0, 0b1000_0000u8 as i8, 0b01,
4402            0b0101, 0b1111_0000u8 as i8, 0, 0,
4403            0, 0b1011_0101u8 as i8, 0b1111_0000u8 as i8, 0b0101,
4404            0b01, 0b1000_0000u8 as i8, 0b0, 0b1000_0000u8 as i8,
4405        );
4406        let r = _mm_movemask_epi8(a);
4407        assert_eq!(r, 0b10100110_00100101);
4408    }
4409
4410    #[simd_test(enable = "sse2")]
4411    const fn test_mm_shuffle_epi32() {
4412        let a = _mm_setr_epi32(5, 10, 15, 20);
4413        let r = _mm_shuffle_epi32::<0b00_01_01_11>(a);
4414        let e = _mm_setr_epi32(20, 10, 10, 5);
4415        assert_eq_m128i(r, e);
4416    }
4417
4418    #[simd_test(enable = "sse2")]
4419    const fn test_mm_shufflehi_epi16() {
4420        let a = _mm_setr_epi16(1, 2, 3, 4, 5, 10, 15, 20);
4421        let r = _mm_shufflehi_epi16::<0b00_01_01_11>(a);
4422        let e = _mm_setr_epi16(1, 2, 3, 4, 20, 10, 10, 5);
4423        assert_eq_m128i(r, e);
4424    }
4425
4426    #[simd_test(enable = "sse2")]
4427    const fn test_mm_shufflelo_epi16() {
4428        let a = _mm_setr_epi16(5, 10, 15, 20, 1, 2, 3, 4);
4429        let r = _mm_shufflelo_epi16::<0b00_01_01_11>(a);
4430        let e = _mm_setr_epi16(20, 10, 10, 5, 1, 2, 3, 4);
4431        assert_eq_m128i(r, e);
4432    }
4433
4434    #[simd_test(enable = "sse2")]
4435    const fn test_mm_unpackhi_epi8() {
4436        #[rustfmt::skip]
4437        let a = _mm_setr_epi8(
4438            0, 1, 2, 3, 4, 5, 6, 7,
4439            8, 9, 10, 11, 12, 13, 14, 15,
4440        );
4441        #[rustfmt::skip]
4442        let b = _mm_setr_epi8(
4443            16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
4444        );
4445        let r = _mm_unpackhi_epi8(a, b);
4446        #[rustfmt::skip]
4447        let e = _mm_setr_epi8(
4448            8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31,
4449        );
4450        assert_eq_m128i(r, e);
4451    }
4452
4453    #[simd_test(enable = "sse2")]
4454    const fn test_mm_unpackhi_epi16() {
4455        let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7);
4456        let b = _mm_setr_epi16(8, 9, 10, 11, 12, 13, 14, 15);
4457        let r = _mm_unpackhi_epi16(a, b);
4458        let e = _mm_setr_epi16(4, 12, 5, 13, 6, 14, 7, 15);
4459        assert_eq_m128i(r, e);
4460    }
4461
4462    #[simd_test(enable = "sse2")]
4463    const fn test_mm_unpackhi_epi32() {
4464        let a = _mm_setr_epi32(0, 1, 2, 3);
4465        let b = _mm_setr_epi32(4, 5, 6, 7);
4466        let r = _mm_unpackhi_epi32(a, b);
4467        let e = _mm_setr_epi32(2, 6, 3, 7);
4468        assert_eq_m128i(r, e);
4469    }
4470
4471    #[simd_test(enable = "sse2")]
4472    const fn test_mm_unpackhi_epi64() {
4473        let a = _mm_setr_epi64x(0, 1);
4474        let b = _mm_setr_epi64x(2, 3);
4475        let r = _mm_unpackhi_epi64(a, b);
4476        let e = _mm_setr_epi64x(1, 3);
4477        assert_eq_m128i(r, e);
4478    }
4479
4480    #[simd_test(enable = "sse2")]
4481    const fn test_mm_unpacklo_epi8() {
4482        #[rustfmt::skip]
4483        let a = _mm_setr_epi8(
4484            0, 1, 2, 3, 4, 5, 6, 7,
4485            8, 9, 10, 11, 12, 13, 14, 15,
4486        );
4487        #[rustfmt::skip]
4488        let b = _mm_setr_epi8(
4489            16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
4490        );
4491        let r = _mm_unpacklo_epi8(a, b);
4492        #[rustfmt::skip]
4493        let e = _mm_setr_epi8(
4494            0, 16, 1, 17, 2, 18, 3, 19,
4495            4, 20, 5, 21, 6, 22, 7, 23,
4496        );
4497        assert_eq_m128i(r, e);
4498    }
4499
4500    #[simd_test(enable = "sse2")]
4501    const fn test_mm_unpacklo_epi16() {
4502        let a = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7);
4503        let b = _mm_setr_epi16(8, 9, 10, 11, 12, 13, 14, 15);
4504        let r = _mm_unpacklo_epi16(a, b);
4505        let e = _mm_setr_epi16(0, 8, 1, 9, 2, 10, 3, 11);
4506        assert_eq_m128i(r, e);
4507    }
4508
4509    #[simd_test(enable = "sse2")]
4510    const fn test_mm_unpacklo_epi32() {
4511        let a = _mm_setr_epi32(0, 1, 2, 3);
4512        let b = _mm_setr_epi32(4, 5, 6, 7);
4513        let r = _mm_unpacklo_epi32(a, b);
4514        let e = _mm_setr_epi32(0, 4, 1, 5);
4515        assert_eq_m128i(r, e);
4516    }
4517
4518    #[simd_test(enable = "sse2")]
4519    const fn test_mm_unpacklo_epi64() {
4520        let a = _mm_setr_epi64x(0, 1);
4521        let b = _mm_setr_epi64x(2, 3);
4522        let r = _mm_unpacklo_epi64(a, b);
4523        let e = _mm_setr_epi64x(0, 2);
4524        assert_eq_m128i(r, e);
4525    }
4526
4527    #[simd_test(enable = "sse2")]
4528    const fn test_mm_add_sd() {
4529        let a = _mm_setr_pd(1.0, 2.0);
4530        let b = _mm_setr_pd(5.0, 10.0);
4531        let r = _mm_add_sd(a, b);
4532        assert_eq_m128d(r, _mm_setr_pd(6.0, 2.0));
4533    }
4534
4535    #[simd_test(enable = "sse2")]
4536    const fn test_mm_add_pd() {
4537        let a = _mm_setr_pd(1.0, 2.0);
4538        let b = _mm_setr_pd(5.0, 10.0);
4539        let r = _mm_add_pd(a, b);
4540        assert_eq_m128d(r, _mm_setr_pd(6.0, 12.0));
4541    }
4542
4543    #[simd_test(enable = "sse2")]
4544    const fn test_mm_div_sd() {
4545        let a = _mm_setr_pd(1.0, 2.0);
4546        let b = _mm_setr_pd(5.0, 10.0);
4547        let r = _mm_div_sd(a, b);
4548        assert_eq_m128d(r, _mm_setr_pd(0.2, 2.0));
4549    }
4550
4551    #[simd_test(enable = "sse2")]
4552    const fn test_mm_div_pd() {
4553        let a = _mm_setr_pd(1.0, 2.0);
4554        let b = _mm_setr_pd(5.0, 10.0);
4555        let r = _mm_div_pd(a, b);
4556        assert_eq_m128d(r, _mm_setr_pd(0.2, 0.2));
4557    }
4558
4559    #[simd_test(enable = "sse2")]
4560    fn test_mm_max_sd() {
4561        let a = _mm_setr_pd(1.0, 2.0);
4562        let b = _mm_setr_pd(5.0, 10.0);
4563        let r = _mm_max_sd(a, b);
4564        assert_eq_m128d(r, _mm_setr_pd(5.0, 2.0));
4565    }
4566
4567    #[simd_test(enable = "sse2")]
4568    fn test_mm_max_pd() {
4569        let a = _mm_setr_pd(1.0, 2.0);
4570        let b = _mm_setr_pd(5.0, 10.0);
4571        let r = _mm_max_pd(a, b);
4572        assert_eq_m128d(r, _mm_setr_pd(5.0, 10.0));
4573
4574        // Check SSE(2)-specific semantics for -0.0 handling.
4575        let a = _mm_setr_pd(-0.0, 0.0);
4576        let b = _mm_setr_pd(0.0, 0.0);
4577        // Cast to __m128i to compare exact bit patterns
4578        let r1 = _mm_castpd_si128(_mm_max_pd(a, b));
4579        let r2 = _mm_castpd_si128(_mm_max_pd(b, a));
4580        let a = _mm_castpd_si128(a);
4581        let b = _mm_castpd_si128(b);
4582        assert_eq_m128i(r1, b);
4583        assert_eq_m128i(r2, a);
4584        assert_ne!(a.as_u8x16(), b.as_u8x16()); // sanity check that -0.0 is actually present
4585    }
4586
4587    #[simd_test(enable = "sse2")]
4588    fn test_mm_min_sd() {
4589        let a = _mm_setr_pd(1.0, 2.0);
4590        let b = _mm_setr_pd(5.0, 10.0);
4591        let r = _mm_min_sd(a, b);
4592        assert_eq_m128d(r, _mm_setr_pd(1.0, 2.0));
4593    }
4594
4595    #[simd_test(enable = "sse2")]
4596    fn test_mm_min_pd() {
4597        let a = _mm_setr_pd(1.0, 2.0);
4598        let b = _mm_setr_pd(5.0, 10.0);
4599        let r = _mm_min_pd(a, b);
4600        assert_eq_m128d(r, _mm_setr_pd(1.0, 2.0));
4601
4602        // Check SSE(2)-specific semantics for -0.0 handling.
4603        let a = _mm_setr_pd(-0.0, 0.0);
4604        let b = _mm_setr_pd(0.0, 0.0);
4605        // Cast to __m128i to compare exact bit patterns
4606        let r1 = _mm_castpd_si128(_mm_min_pd(a, b));
4607        let r2 = _mm_castpd_si128(_mm_min_pd(b, a));
4608        let a = _mm_castpd_si128(a);
4609        let b = _mm_castpd_si128(b);
4610        assert_eq_m128i(r1, b);
4611        assert_eq_m128i(r2, a);
4612        assert_ne!(a.as_u8x16(), b.as_u8x16()); // sanity check that -0.0 is actually present
4613    }
4614
4615    #[simd_test(enable = "sse2")]
4616    const fn test_mm_mul_sd() {
4617        let a = _mm_setr_pd(1.0, 2.0);
4618        let b = _mm_setr_pd(5.0, 10.0);
4619        let r = _mm_mul_sd(a, b);
4620        assert_eq_m128d(r, _mm_setr_pd(5.0, 2.0));
4621    }
4622
4623    #[simd_test(enable = "sse2")]
4624    const fn test_mm_mul_pd() {
4625        let a = _mm_setr_pd(1.0, 2.0);
4626        let b = _mm_setr_pd(5.0, 10.0);
4627        let r = _mm_mul_pd(a, b);
4628        assert_eq_m128d(r, _mm_setr_pd(5.0, 20.0));
4629    }
4630
4631    #[simd_test(enable = "sse2")]
4632    fn test_mm_sqrt_sd() {
4633        let a = _mm_setr_pd(1.0, 2.0);
4634        let b = _mm_setr_pd(5.0, 10.0);
4635        let r = _mm_sqrt_sd(a, b);
4636        assert_eq_m128d(r, _mm_setr_pd(5.0f64.sqrt(), 2.0));
4637    }
4638
4639    #[simd_test(enable = "sse2")]
4640    fn test_mm_sqrt_pd() {
4641        let r = _mm_sqrt_pd(_mm_setr_pd(1.0, 2.0));
4642        assert_eq_m128d(r, _mm_setr_pd(1.0f64.sqrt(), 2.0f64.sqrt()));
4643    }
4644
4645    #[simd_test(enable = "sse2")]
4646    const fn test_mm_sub_sd() {
4647        let a = _mm_setr_pd(1.0, 2.0);
4648        let b = _mm_setr_pd(5.0, 10.0);
4649        let r = _mm_sub_sd(a, b);
4650        assert_eq_m128d(r, _mm_setr_pd(-4.0, 2.0));
4651    }
4652
4653    #[simd_test(enable = "sse2")]
4654    const fn test_mm_sub_pd() {
4655        let a = _mm_setr_pd(1.0, 2.0);
4656        let b = _mm_setr_pd(5.0, 10.0);
4657        let r = _mm_sub_pd(a, b);
4658        assert_eq_m128d(r, _mm_setr_pd(-4.0, -8.0));
4659    }
4660
4661    #[simd_test(enable = "sse2")]
4662    const fn test_mm_and_pd() {
4663        let a = f64x2::from_bits(u64x2::splat(5)).as_m128d();
4664        let b = f64x2::from_bits(u64x2::splat(3)).as_m128d();
4665        let r = _mm_and_pd(a, b);
4666        let e = f64x2::from_bits(u64x2::splat(1)).as_m128d();
4667        assert_eq_m128d(r, e);
4668    }
4669
4670    #[simd_test(enable = "sse2")]
4671    const fn test_mm_andnot_pd() {
4672        let a = f64x2::from_bits(u64x2::splat(5)).as_m128d();
4673        let b = f64x2::from_bits(u64x2::splat(3)).as_m128d();
4674        let r = _mm_andnot_pd(a, b);
4675        let e = f64x2::from_bits(u64x2::splat(2)).as_m128d();
4676        assert_eq_m128d(r, e);
4677    }
4678
4679    #[simd_test(enable = "sse2")]
4680    const fn test_mm_or_pd() {
4681        let a = f64x2::from_bits(u64x2::splat(5)).as_m128d();
4682        let b = f64x2::from_bits(u64x2::splat(3)).as_m128d();
4683        let r = _mm_or_pd(a, b);
4684        let e = f64x2::from_bits(u64x2::splat(7)).as_m128d();
4685        assert_eq_m128d(r, e);
4686    }
4687
4688    #[simd_test(enable = "sse2")]
4689    const fn test_mm_xor_pd() {
4690        let a = f64x2::from_bits(u64x2::splat(5)).as_m128d();
4691        let b = f64x2::from_bits(u64x2::splat(3)).as_m128d();
4692        let r = _mm_xor_pd(a, b);
4693        let e = f64x2::from_bits(u64x2::splat(6)).as_m128d();
4694        assert_eq_m128d(r, e);
4695    }
4696
4697    #[simd_test(enable = "sse2")]
4698    fn test_mm_cmpeq_sd() {
4699        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4700        let e = _mm_setr_epi64x(!0, 2.0f64.to_bits() as i64);
4701        let r = _mm_castpd_si128(_mm_cmpeq_sd(a, b));
4702        assert_eq_m128i(r, e);
4703    }
4704
4705    #[simd_test(enable = "sse2")]
4706    fn test_mm_cmplt_sd() {
4707        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(5.0, 3.0));
4708        let e = _mm_setr_epi64x(!0, 2.0f64.to_bits() as i64);
4709        let r = _mm_castpd_si128(_mm_cmplt_sd(a, b));
4710        assert_eq_m128i(r, e);
4711    }
4712
4713    #[simd_test(enable = "sse2")]
4714    fn test_mm_cmple_sd() {
4715        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4716        let e = _mm_setr_epi64x(!0, 2.0f64.to_bits() as i64);
4717        let r = _mm_castpd_si128(_mm_cmple_sd(a, b));
4718        assert_eq_m128i(r, e);
4719    }
4720
4721    #[simd_test(enable = "sse2")]
4722    fn test_mm_cmpgt_sd() {
4723        let (a, b) = (_mm_setr_pd(5.0, 2.0), _mm_setr_pd(1.0, 3.0));
4724        let e = _mm_setr_epi64x(!0, 2.0f64.to_bits() as i64);
4725        let r = _mm_castpd_si128(_mm_cmpgt_sd(a, b));
4726        assert_eq_m128i(r, e);
4727    }
4728
4729    #[simd_test(enable = "sse2")]
4730    fn test_mm_cmpge_sd() {
4731        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4732        let e = _mm_setr_epi64x(!0, 2.0f64.to_bits() as i64);
4733        let r = _mm_castpd_si128(_mm_cmpge_sd(a, b));
4734        assert_eq_m128i(r, e);
4735    }
4736
4737    #[simd_test(enable = "sse2")]
4738    fn test_mm_cmpord_sd() {
4739        let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(5.0, 3.0));
4740        let e = _mm_setr_epi64x(0, 2.0f64.to_bits() as i64);
4741        let r = _mm_castpd_si128(_mm_cmpord_sd(a, b));
4742        assert_eq_m128i(r, e);
4743    }
4744
4745    #[simd_test(enable = "sse2")]
4746    fn test_mm_cmpunord_sd() {
4747        let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(5.0, 3.0));
4748        let e = _mm_setr_epi64x(!0, 2.0f64.to_bits() as i64);
4749        let r = _mm_castpd_si128(_mm_cmpunord_sd(a, b));
4750        assert_eq_m128i(r, e);
4751    }
4752
4753    #[simd_test(enable = "sse2")]
4754    fn test_mm_cmpneq_sd() {
4755        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(5.0, 3.0));
4756        let e = _mm_setr_epi64x(!0, 2.0f64.to_bits() as i64);
4757        let r = _mm_castpd_si128(_mm_cmpneq_sd(a, b));
4758        assert_eq_m128i(r, e);
4759    }
4760
4761    #[simd_test(enable = "sse2")]
4762    fn test_mm_cmpnlt_sd() {
4763        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(5.0, 3.0));
4764        let e = _mm_setr_epi64x(0, 2.0f64.to_bits() as i64);
4765        let r = _mm_castpd_si128(_mm_cmpnlt_sd(a, b));
4766        assert_eq_m128i(r, e);
4767    }
4768
4769    #[simd_test(enable = "sse2")]
4770    fn test_mm_cmpnle_sd() {
4771        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4772        let e = _mm_setr_epi64x(0, 2.0f64.to_bits() as i64);
4773        let r = _mm_castpd_si128(_mm_cmpnle_sd(a, b));
4774        assert_eq_m128i(r, e);
4775    }
4776
4777    #[simd_test(enable = "sse2")]
4778    fn test_mm_cmpngt_sd() {
4779        let (a, b) = (_mm_setr_pd(5.0, 2.0), _mm_setr_pd(1.0, 3.0));
4780        let e = _mm_setr_epi64x(0, 2.0f64.to_bits() as i64);
4781        let r = _mm_castpd_si128(_mm_cmpngt_sd(a, b));
4782        assert_eq_m128i(r, e);
4783    }
4784
4785    #[simd_test(enable = "sse2")]
4786    fn test_mm_cmpnge_sd() {
4787        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4788        let e = _mm_setr_epi64x(0, 2.0f64.to_bits() as i64);
4789        let r = _mm_castpd_si128(_mm_cmpnge_sd(a, b));
4790        assert_eq_m128i(r, e);
4791    }
4792
4793    #[simd_test(enable = "sse2")]
4794    fn test_mm_cmpeq_pd() {
4795        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4796        let e = _mm_setr_epi64x(!0, 0);
4797        let r = _mm_castpd_si128(_mm_cmpeq_pd(a, b));
4798        assert_eq_m128i(r, e);
4799    }
4800
4801    #[simd_test(enable = "sse2")]
4802    fn test_mm_cmplt_pd() {
4803        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4804        let e = _mm_setr_epi64x(0, !0);
4805        let r = _mm_castpd_si128(_mm_cmplt_pd(a, b));
4806        assert_eq_m128i(r, e);
4807    }
4808
4809    #[simd_test(enable = "sse2")]
4810    fn test_mm_cmple_pd() {
4811        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4812        let e = _mm_setr_epi64x(!0, !0);
4813        let r = _mm_castpd_si128(_mm_cmple_pd(a, b));
4814        assert_eq_m128i(r, e);
4815    }
4816
4817    #[simd_test(enable = "sse2")]
4818    fn test_mm_cmpgt_pd() {
4819        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4820        let e = _mm_setr_epi64x(0, 0);
4821        let r = _mm_castpd_si128(_mm_cmpgt_pd(a, b));
4822        assert_eq_m128i(r, e);
4823    }
4824
4825    #[simd_test(enable = "sse2")]
4826    fn test_mm_cmpge_pd() {
4827        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4828        let e = _mm_setr_epi64x(!0, 0);
4829        let r = _mm_castpd_si128(_mm_cmpge_pd(a, b));
4830        assert_eq_m128i(r, e);
4831    }
4832
4833    #[simd_test(enable = "sse2")]
4834    fn test_mm_cmpord_pd() {
4835        let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(5.0, 3.0));
4836        let e = _mm_setr_epi64x(0, !0);
4837        let r = _mm_castpd_si128(_mm_cmpord_pd(a, b));
4838        assert_eq_m128i(r, e);
4839    }
4840
4841    #[simd_test(enable = "sse2")]
4842    fn test_mm_cmpunord_pd() {
4843        let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(5.0, 3.0));
4844        let e = _mm_setr_epi64x(!0, 0);
4845        let r = _mm_castpd_si128(_mm_cmpunord_pd(a, b));
4846        assert_eq_m128i(r, e);
4847    }
4848
4849    #[simd_test(enable = "sse2")]
4850    fn test_mm_cmpneq_pd() {
4851        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(5.0, 3.0));
4852        let e = _mm_setr_epi64x(!0, !0);
4853        let r = _mm_castpd_si128(_mm_cmpneq_pd(a, b));
4854        assert_eq_m128i(r, e);
4855    }
4856
4857    #[simd_test(enable = "sse2")]
4858    fn test_mm_cmpnlt_pd() {
4859        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(5.0, 3.0));
4860        let e = _mm_setr_epi64x(0, 0);
4861        let r = _mm_castpd_si128(_mm_cmpnlt_pd(a, b));
4862        assert_eq_m128i(r, e);
4863    }
4864
4865    #[simd_test(enable = "sse2")]
4866    fn test_mm_cmpnle_pd() {
4867        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4868        let e = _mm_setr_epi64x(0, 0);
4869        let r = _mm_castpd_si128(_mm_cmpnle_pd(a, b));
4870        assert_eq_m128i(r, e);
4871    }
4872
4873    #[simd_test(enable = "sse2")]
4874    fn test_mm_cmpngt_pd() {
4875        let (a, b) = (_mm_setr_pd(5.0, 2.0), _mm_setr_pd(1.0, 3.0));
4876        let e = _mm_setr_epi64x(0, !0);
4877        let r = _mm_castpd_si128(_mm_cmpngt_pd(a, b));
4878        assert_eq_m128i(r, e);
4879    }
4880
4881    #[simd_test(enable = "sse2")]
4882    fn test_mm_cmpnge_pd() {
4883        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4884        let e = _mm_setr_epi64x(0, !0);
4885        let r = _mm_castpd_si128(_mm_cmpnge_pd(a, b));
4886        assert_eq_m128i(r, e);
4887    }
4888
4889    #[simd_test(enable = "sse2")]
4890    fn test_mm_comieq_sd() {
4891        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4892        assert!(_mm_comieq_sd(a, b) != 0);
4893
4894        let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(1.0, 3.0));
4895        assert!(_mm_comieq_sd(a, b) == 0);
4896    }
4897
4898    #[simd_test(enable = "sse2")]
4899    fn test_mm_comilt_sd() {
4900        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4901        assert!(_mm_comilt_sd(a, b) == 0);
4902    }
4903
4904    #[simd_test(enable = "sse2")]
4905    fn test_mm_comile_sd() {
4906        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4907        assert!(_mm_comile_sd(a, b) != 0);
4908    }
4909
4910    #[simd_test(enable = "sse2")]
4911    fn test_mm_comigt_sd() {
4912        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4913        assert!(_mm_comigt_sd(a, b) == 0);
4914    }
4915
4916    #[simd_test(enable = "sse2")]
4917    fn test_mm_comige_sd() {
4918        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4919        assert!(_mm_comige_sd(a, b) != 0);
4920    }
4921
4922    #[simd_test(enable = "sse2")]
4923    fn test_mm_comineq_sd() {
4924        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4925        assert!(_mm_comineq_sd(a, b) == 0);
4926    }
4927
4928    #[simd_test(enable = "sse2")]
4929    fn test_mm_ucomieq_sd() {
4930        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4931        assert!(_mm_ucomieq_sd(a, b) != 0);
4932
4933        let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(NAN, 3.0));
4934        assert!(_mm_ucomieq_sd(a, b) == 0);
4935    }
4936
4937    #[simd_test(enable = "sse2")]
4938    fn test_mm_ucomilt_sd() {
4939        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4940        assert!(_mm_ucomilt_sd(a, b) == 0);
4941    }
4942
4943    #[simd_test(enable = "sse2")]
4944    fn test_mm_ucomile_sd() {
4945        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4946        assert!(_mm_ucomile_sd(a, b) != 0);
4947    }
4948
4949    #[simd_test(enable = "sse2")]
4950    fn test_mm_ucomigt_sd() {
4951        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4952        assert!(_mm_ucomigt_sd(a, b) == 0);
4953    }
4954
4955    #[simd_test(enable = "sse2")]
4956    fn test_mm_ucomige_sd() {
4957        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4958        assert!(_mm_ucomige_sd(a, b) != 0);
4959    }
4960
4961    #[simd_test(enable = "sse2")]
4962    fn test_mm_ucomineq_sd() {
4963        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
4964        assert!(_mm_ucomineq_sd(a, b) == 0);
4965    }
4966
4967    #[simd_test(enable = "sse2")]
4968    const fn test_mm_movemask_pd() {
4969        let r = _mm_movemask_pd(_mm_setr_pd(-1.0, 5.0));
4970        assert_eq!(r, 0b01);
4971
4972        let r = _mm_movemask_pd(_mm_setr_pd(-1.0, -5.0));
4973        assert_eq!(r, 0b11);
4974    }
4975
4976    #[repr(align(16))]
4977    struct Memory {
4978        data: [f64; 4],
4979    }
4980
4981    #[simd_test(enable = "sse2")]
4982    const fn test_mm_load_pd() {
4983        let mem = Memory {
4984            data: [1.0f64, 2.0, 3.0, 4.0],
4985        };
4986        let vals = &mem.data;
4987        let d = vals.as_ptr();
4988
4989        let r = unsafe { _mm_load_pd(d) };
4990        assert_eq_m128d(r, _mm_setr_pd(1.0, 2.0));
4991    }
4992
4993    #[simd_test(enable = "sse2")]
4994    const fn test_mm_load_sd() {
4995        let a = 1.;
4996        let expected = _mm_setr_pd(a, 0.);
4997        let r = unsafe { _mm_load_sd(&a) };
4998        assert_eq_m128d(r, expected);
4999    }
5000
5001    #[simd_test(enable = "sse2")]
5002    const fn test_mm_loadh_pd() {
5003        let a = _mm_setr_pd(1., 2.);
5004        let b = 3.;
5005        let expected = _mm_setr_pd(_mm_cvtsd_f64(a), 3.);
5006        let r = unsafe { _mm_loadh_pd(a, &b) };
5007        assert_eq_m128d(r, expected);
5008    }
5009
5010    #[simd_test(enable = "sse2")]
5011    const fn test_mm_loadl_pd() {
5012        let a = _mm_setr_pd(1., 2.);
5013        let b = 3.;
5014        let expected = _mm_setr_pd(3., get_m128d(a, 1));
5015        let r = unsafe { _mm_loadl_pd(a, &b) };
5016        assert_eq_m128d(r, expected);
5017    }
5018
5019    #[simd_test(enable = "sse2")]
5020    // Miri cannot support this until it is clear how it fits in the Rust memory model
5021    // (non-temporal store)
5022    #[cfg_attr(miri, ignore)]
5023    fn test_mm_stream_pd() {
5024        #[repr(align(128))]
5025        struct Memory {
5026            pub data: [f64; 2],
5027        }
5028        let a = _mm_set1_pd(7.0);
5029        let mut mem = Memory { data: [-1.0; 2] };
5030
5031        unsafe {
5032            _mm_stream_pd(ptr::addr_of_mut!(mem.data[0]), a);
5033        }
5034        _mm_sfence();
5035        for i in 0..2 {
5036            assert_eq!(mem.data[i], get_m128d(a, i));
5037        }
5038    }
5039
5040    #[simd_test(enable = "sse2")]
5041    const fn test_mm_store_sd() {
5042        let mut dest = 0.;
5043        let a = _mm_setr_pd(1., 2.);
5044        unsafe {
5045            _mm_store_sd(&mut dest, a);
5046        }
5047        assert_eq!(dest, _mm_cvtsd_f64(a));
5048    }
5049
5050    #[simd_test(enable = "sse2")]
5051    const fn test_mm_store_pd() {
5052        let mut mem = Memory { data: [0.0f64; 4] };
5053        let vals = &mut mem.data;
5054        let a = _mm_setr_pd(1.0, 2.0);
5055        let d = vals.as_mut_ptr();
5056
5057        unsafe {
5058            _mm_store_pd(d, *black_box(&a));
5059        }
5060        assert_eq!(vals[0], 1.0);
5061        assert_eq!(vals[1], 2.0);
5062    }
5063
5064    #[simd_test(enable = "sse2")]
5065    const fn test_mm_storeu_pd() {
5066        // guaranteed to be aligned to 16 bytes
5067        let mut mem = Memory { data: [0.0f64; 4] };
5068        let vals = &mut mem.data;
5069        let a = _mm_setr_pd(1.0, 2.0);
5070
5071        // so p is *not* aligned to 16 bytes
5072        unsafe {
5073            let p = vals.as_mut_ptr().offset(1);
5074            _mm_storeu_pd(p, *black_box(&a));
5075        }
5076
5077        assert_eq!(*vals, [0.0, 1.0, 2.0, 0.0]);
5078    }
5079
5080    #[simd_test(enable = "sse2")]
5081    const fn test_mm_storeu_si16() {
5082        let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8);
5083        let mut r = _mm_setr_epi16(9, 10, 11, 12, 13, 14, 15, 16);
5084        unsafe {
5085            _mm_storeu_si16(ptr::addr_of_mut!(r).cast(), a);
5086        }
5087        let e = _mm_setr_epi16(1, 10, 11, 12, 13, 14, 15, 16);
5088        assert_eq_m128i(r, e);
5089    }
5090
5091    #[simd_test(enable = "sse2")]
5092    const fn test_mm_storeu_si32() {
5093        let a = _mm_setr_epi32(1, 2, 3, 4);
5094        let mut r = _mm_setr_epi32(5, 6, 7, 8);
5095        unsafe {
5096            _mm_storeu_si32(ptr::addr_of_mut!(r).cast(), a);
5097        }
5098        let e = _mm_setr_epi32(1, 6, 7, 8);
5099        assert_eq_m128i(r, e);
5100    }
5101
5102    #[simd_test(enable = "sse2")]
5103    const fn test_mm_storeu_si64() {
5104        let a = _mm_setr_epi64x(1, 2);
5105        let mut r = _mm_setr_epi64x(3, 4);
5106        unsafe {
5107            _mm_storeu_si64(ptr::addr_of_mut!(r).cast(), a);
5108        }
5109        let e = _mm_setr_epi64x(1, 4);
5110        assert_eq_m128i(r, e);
5111    }
5112
5113    #[simd_test(enable = "sse2")]
5114    const fn test_mm_store1_pd() {
5115        let mut mem = Memory { data: [0.0f64; 4] };
5116        let vals = &mut mem.data;
5117        let a = _mm_setr_pd(1.0, 2.0);
5118        let d = vals.as_mut_ptr();
5119
5120        unsafe {
5121            _mm_store1_pd(d, *black_box(&a));
5122        }
5123        assert_eq!(vals[0], 1.0);
5124        assert_eq!(vals[1], 1.0);
5125    }
5126
5127    #[simd_test(enable = "sse2")]
5128    const fn test_mm_store_pd1() {
5129        let mut mem = Memory { data: [0.0f64; 4] };
5130        let vals = &mut mem.data;
5131        let a = _mm_setr_pd(1.0, 2.0);
5132        let d = vals.as_mut_ptr();
5133
5134        unsafe {
5135            _mm_store_pd1(d, *black_box(&a));
5136        }
5137        assert_eq!(vals[0], 1.0);
5138        assert_eq!(vals[1], 1.0);
5139    }
5140
5141    #[simd_test(enable = "sse2")]
5142    const fn test_mm_storer_pd() {
5143        let mut mem = Memory { data: [0.0f64; 4] };
5144        let vals = &mut mem.data;
5145        let a = _mm_setr_pd(1.0, 2.0);
5146        let d = vals.as_mut_ptr();
5147
5148        unsafe {
5149            _mm_storer_pd(d, *black_box(&a));
5150        }
5151        assert_eq!(vals[0], 2.0);
5152        assert_eq!(vals[1], 1.0);
5153    }
5154
5155    #[simd_test(enable = "sse2")]
5156    const fn test_mm_storeh_pd() {
5157        let mut dest = 0.;
5158        let a = _mm_setr_pd(1., 2.);
5159        unsafe {
5160            _mm_storeh_pd(&mut dest, a);
5161        }
5162        assert_eq!(dest, get_m128d(a, 1));
5163    }
5164
5165    #[simd_test(enable = "sse2")]
5166    const fn test_mm_storel_pd() {
5167        let mut dest = 0.;
5168        let a = _mm_setr_pd(1., 2.);
5169        unsafe {
5170            _mm_storel_pd(&mut dest, a);
5171        }
5172        assert_eq!(dest, _mm_cvtsd_f64(a));
5173    }
5174
5175    #[simd_test(enable = "sse2")]
5176    const fn test_mm_loadr_pd() {
5177        let mut mem = Memory {
5178            data: [1.0f64, 2.0, 3.0, 4.0],
5179        };
5180        let vals = &mut mem.data;
5181        let d = vals.as_ptr();
5182
5183        let r = unsafe { _mm_loadr_pd(d) };
5184        assert_eq_m128d(r, _mm_setr_pd(2.0, 1.0));
5185    }
5186
5187    #[simd_test(enable = "sse2")]
5188    const fn test_mm_loadu_pd() {
5189        // guaranteed to be aligned to 16 bytes
5190        let mut mem = Memory {
5191            data: [1.0f64, 2.0, 3.0, 4.0],
5192        };
5193        let vals = &mut mem.data;
5194
5195        // so this will *not* be aligned to 16 bytes
5196        let d = unsafe { vals.as_ptr().offset(1) };
5197
5198        let r = unsafe { _mm_loadu_pd(d) };
5199        let e = _mm_setr_pd(2.0, 3.0);
5200        assert_eq_m128d(r, e);
5201    }
5202
5203    #[simd_test(enable = "sse2")]
5204    const fn test_mm_loadu_si16() {
5205        let a = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8);
5206        let r = unsafe { _mm_loadu_si16(ptr::addr_of!(a) as *const _) };
5207        assert_eq_m128i(r, _mm_setr_epi16(1, 0, 0, 0, 0, 0, 0, 0));
5208    }
5209
5210    #[simd_test(enable = "sse2")]
5211    const fn test_mm_loadu_si32() {
5212        let a = _mm_setr_epi32(1, 2, 3, 4);
5213        let r = unsafe { _mm_loadu_si32(ptr::addr_of!(a) as *const _) };
5214        assert_eq_m128i(r, _mm_setr_epi32(1, 0, 0, 0));
5215    }
5216
5217    #[simd_test(enable = "sse2")]
5218    const fn test_mm_loadu_si64() {
5219        let a = _mm_setr_epi64x(5, 6);
5220        let r = unsafe { _mm_loadu_si64(ptr::addr_of!(a) as *const _) };
5221        assert_eq_m128i(r, _mm_setr_epi64x(5, 0));
5222    }
5223
5224    #[simd_test(enable = "sse2")]
5225    const fn test_mm_cvtpd_ps() {
5226        let r = _mm_cvtpd_ps(_mm_setr_pd(-1.0, 5.0));
5227        assert_eq_m128(r, _mm_setr_ps(-1.0, 5.0, 0.0, 0.0));
5228
5229        let r = _mm_cvtpd_ps(_mm_setr_pd(-1.0, -5.0));
5230        assert_eq_m128(r, _mm_setr_ps(-1.0, -5.0, 0.0, 0.0));
5231
5232        let r = _mm_cvtpd_ps(_mm_setr_pd(f64::MAX, f64::MIN));
5233        assert_eq_m128(r, _mm_setr_ps(f32::INFINITY, f32::NEG_INFINITY, 0.0, 0.0));
5234
5235        let r = _mm_cvtpd_ps(_mm_setr_pd(f32::MAX as f64, f32::MIN as f64));
5236        assert_eq_m128(r, _mm_setr_ps(f32::MAX, f32::MIN, 0.0, 0.0));
5237    }
5238
5239    #[simd_test(enable = "sse2")]
5240    const fn test_mm_cvtps_pd() {
5241        let r = _mm_cvtps_pd(_mm_setr_ps(-1.0, 2.0, -3.0, 5.0));
5242        assert_eq_m128d(r, _mm_setr_pd(-1.0, 2.0));
5243
5244        let r = _mm_cvtps_pd(_mm_setr_ps(
5245            f32::MAX,
5246            f32::INFINITY,
5247            f32::NEG_INFINITY,
5248            f32::MIN,
5249        ));
5250        assert_eq_m128d(r, _mm_setr_pd(f32::MAX as f64, f64::INFINITY));
5251    }
5252
5253    #[simd_test(enable = "sse2")]
5254    fn test_mm_cvtpd_epi32() {
5255        let r = _mm_cvtpd_epi32(_mm_setr_pd(-1.0, 5.0));
5256        assert_eq_m128i(r, _mm_setr_epi32(-1, 5, 0, 0));
5257
5258        let r = _mm_cvtpd_epi32(_mm_setr_pd(-1.0, -5.0));
5259        assert_eq_m128i(r, _mm_setr_epi32(-1, -5, 0, 0));
5260
5261        let r = _mm_cvtpd_epi32(_mm_setr_pd(f64::MAX, f64::MIN));
5262        assert_eq_m128i(r, _mm_setr_epi32(i32::MIN, i32::MIN, 0, 0));
5263
5264        let r = _mm_cvtpd_epi32(_mm_setr_pd(f64::INFINITY, f64::NEG_INFINITY));
5265        assert_eq_m128i(r, _mm_setr_epi32(i32::MIN, i32::MIN, 0, 0));
5266
5267        let r = _mm_cvtpd_epi32(_mm_setr_pd(f64::NAN, f64::NAN));
5268        assert_eq_m128i(r, _mm_setr_epi32(i32::MIN, i32::MIN, 0, 0));
5269    }
5270
5271    #[simd_test(enable = "sse2")]
5272    fn test_mm_cvtsd_si32() {
5273        let r = _mm_cvtsd_si32(_mm_setr_pd(-2.0, 5.0));
5274        assert_eq!(r, -2);
5275
5276        let r = _mm_cvtsd_si32(_mm_setr_pd(f64::MAX, f64::MIN));
5277        assert_eq!(r, i32::MIN);
5278
5279        let r = _mm_cvtsd_si32(_mm_setr_pd(f64::NAN, f64::NAN));
5280        assert_eq!(r, i32::MIN);
5281    }
5282
5283    #[simd_test(enable = "sse2")]
5284    fn test_mm_cvtsd_ss() {
5285        let a = _mm_setr_ps(-1.1, -2.2, 3.3, 4.4);
5286        let b = _mm_setr_pd(2.0, -5.0);
5287
5288        let r = _mm_cvtsd_ss(a, b);
5289
5290        assert_eq_m128(r, _mm_setr_ps(2.0, -2.2, 3.3, 4.4));
5291
5292        let a = _mm_setr_ps(-1.1, f32::NEG_INFINITY, f32::MAX, f32::NEG_INFINITY);
5293        let b = _mm_setr_pd(f64::INFINITY, -5.0);
5294
5295        let r = _mm_cvtsd_ss(a, b);
5296
5297        assert_eq_m128(
5298            r,
5299            _mm_setr_ps(
5300                f32::INFINITY,
5301                f32::NEG_INFINITY,
5302                f32::MAX,
5303                f32::NEG_INFINITY,
5304            ),
5305        );
5306    }
5307
5308    #[simd_test(enable = "sse2")]
5309    const fn test_mm_cvtsd_f64() {
5310        let r = _mm_cvtsd_f64(_mm_setr_pd(-1.1, 2.2));
5311        assert_eq!(r, -1.1);
5312    }
5313
5314    #[simd_test(enable = "sse2")]
5315    const fn test_mm_cvtss_sd() {
5316        let a = _mm_setr_pd(-1.1, 2.2);
5317        let b = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
5318
5319        let r = _mm_cvtss_sd(a, b);
5320        assert_eq_m128d(r, _mm_setr_pd(1.0, 2.2));
5321
5322        let a = _mm_setr_pd(-1.1, f64::INFINITY);
5323        let b = _mm_setr_ps(f32::NEG_INFINITY, 2.0, 3.0, 4.0);
5324
5325        let r = _mm_cvtss_sd(a, b);
5326        assert_eq_m128d(r, _mm_setr_pd(f64::NEG_INFINITY, f64::INFINITY));
5327    }
5328
5329    #[simd_test(enable = "sse2")]
5330    fn test_mm_cvttpd_epi32() {
5331        let a = _mm_setr_pd(-1.1, 2.2);
5332        let r = _mm_cvttpd_epi32(a);
5333        assert_eq_m128i(r, _mm_setr_epi32(-1, 2, 0, 0));
5334
5335        let a = _mm_setr_pd(f64::NEG_INFINITY, f64::NAN);
5336        let r = _mm_cvttpd_epi32(a);
5337        assert_eq_m128i(r, _mm_setr_epi32(i32::MIN, i32::MIN, 0, 0));
5338    }
5339
5340    #[simd_test(enable = "sse2")]
5341    fn test_mm_cvttsd_si32() {
5342        let a = _mm_setr_pd(-1.1, 2.2);
5343        let r = _mm_cvttsd_si32(a);
5344        assert_eq!(r, -1);
5345
5346        let a = _mm_setr_pd(f64::NEG_INFINITY, f64::NAN);
5347        let r = _mm_cvttsd_si32(a);
5348        assert_eq!(r, i32::MIN);
5349    }
5350
5351    #[simd_test(enable = "sse2")]
5352    fn test_mm_cvttps_epi32() {
5353        let a = _mm_setr_ps(-1.1, 2.2, -3.3, 6.6);
5354        let r = _mm_cvttps_epi32(a);
5355        assert_eq_m128i(r, _mm_setr_epi32(-1, 2, -3, 6));
5356
5357        let a = _mm_setr_ps(f32::NEG_INFINITY, f32::INFINITY, f32::MIN, f32::MAX);
5358        let r = _mm_cvttps_epi32(a);
5359        assert_eq_m128i(r, _mm_setr_epi32(i32::MIN, i32::MIN, i32::MIN, i32::MIN));
5360    }
5361
5362    #[simd_test(enable = "sse2")]
5363    const fn test_mm_set_sd() {
5364        let r = _mm_set_sd(-1.0_f64);
5365        assert_eq_m128d(r, _mm_setr_pd(-1.0_f64, 0_f64));
5366    }
5367
5368    #[simd_test(enable = "sse2")]
5369    const fn test_mm_set1_pd() {
5370        let r = _mm_set1_pd(-1.0_f64);
5371        assert_eq_m128d(r, _mm_setr_pd(-1.0_f64, -1.0_f64));
5372    }
5373
5374    #[simd_test(enable = "sse2")]
5375    const fn test_mm_set_pd1() {
5376        let r = _mm_set_pd1(-2.0_f64);
5377        assert_eq_m128d(r, _mm_setr_pd(-2.0_f64, -2.0_f64));
5378    }
5379
5380    #[simd_test(enable = "sse2")]
5381    const fn test_mm_set_pd() {
5382        let r = _mm_set_pd(1.0_f64, 5.0_f64);
5383        assert_eq_m128d(r, _mm_setr_pd(5.0_f64, 1.0_f64));
5384    }
5385
5386    #[simd_test(enable = "sse2")]
5387    const fn test_mm_setr_pd() {
5388        let r = _mm_setr_pd(1.0_f64, -5.0_f64);
5389        assert_eq_m128d(r, _mm_setr_pd(1.0_f64, -5.0_f64));
5390    }
5391
5392    #[simd_test(enable = "sse2")]
5393    const fn test_mm_setzero_pd() {
5394        let r = _mm_setzero_pd();
5395        assert_eq_m128d(r, _mm_setr_pd(0_f64, 0_f64));
5396    }
5397
5398    #[simd_test(enable = "sse2")]
5399    const fn test_mm_load1_pd() {
5400        let d = -5.0;
5401        let r = unsafe { _mm_load1_pd(&d) };
5402        assert_eq_m128d(r, _mm_setr_pd(d, d));
5403    }
5404
5405    #[simd_test(enable = "sse2")]
5406    const fn test_mm_load_pd1() {
5407        let d = -5.0;
5408        let r = unsafe { _mm_load_pd1(&d) };
5409        assert_eq_m128d(r, _mm_setr_pd(d, d));
5410    }
5411
5412    #[simd_test(enable = "sse2")]
5413    const fn test_mm_unpackhi_pd() {
5414        let a = _mm_setr_pd(1.0, 2.0);
5415        let b = _mm_setr_pd(3.0, 4.0);
5416        let r = _mm_unpackhi_pd(a, b);
5417        assert_eq_m128d(r, _mm_setr_pd(2.0, 4.0));
5418    }
5419
5420    #[simd_test(enable = "sse2")]
5421    const fn test_mm_unpacklo_pd() {
5422        let a = _mm_setr_pd(1.0, 2.0);
5423        let b = _mm_setr_pd(3.0, 4.0);
5424        let r = _mm_unpacklo_pd(a, b);
5425        assert_eq_m128d(r, _mm_setr_pd(1.0, 3.0));
5426    }
5427
5428    #[simd_test(enable = "sse2")]
5429    const fn test_mm_shuffle_pd() {
5430        let a = _mm_setr_pd(1., 2.);
5431        let b = _mm_setr_pd(3., 4.);
5432        let expected = _mm_setr_pd(1., 3.);
5433        let r = _mm_shuffle_pd::<0b00_00_00_00>(a, b);
5434        assert_eq_m128d(r, expected);
5435    }
5436
5437    #[simd_test(enable = "sse2")]
5438    const fn test_mm_move_sd() {
5439        let a = _mm_setr_pd(1., 2.);
5440        let b = _mm_setr_pd(3., 4.);
5441        let expected = _mm_setr_pd(3., 2.);
5442        let r = _mm_move_sd(a, b);
5443        assert_eq_m128d(r, expected);
5444    }
5445
5446    #[simd_test(enable = "sse2")]
5447    const fn test_mm_castpd_ps() {
5448        let a = _mm_set1_pd(0.);
5449        let expected = _mm_set1_ps(0.);
5450        let r = _mm_castpd_ps(a);
5451        assert_eq_m128(r, expected);
5452    }
5453
5454    #[simd_test(enable = "sse2")]
5455    const fn test_mm_castpd_si128() {
5456        let a = _mm_set1_pd(0.);
5457        let expected = _mm_set1_epi64x(0);
5458        let r = _mm_castpd_si128(a);
5459        assert_eq_m128i(r, expected);
5460    }
5461
5462    #[simd_test(enable = "sse2")]
5463    const fn test_mm_castps_pd() {
5464        let a = _mm_set1_ps(0.);
5465        let expected = _mm_set1_pd(0.);
5466        let r = _mm_castps_pd(a);
5467        assert_eq_m128d(r, expected);
5468    }
5469
5470    #[simd_test(enable = "sse2")]
5471    const fn test_mm_castps_si128() {
5472        let a = _mm_set1_ps(0.);
5473        let expected = _mm_set1_epi32(0);
5474        let r = _mm_castps_si128(a);
5475        assert_eq_m128i(r, expected);
5476    }
5477
5478    #[simd_test(enable = "sse2")]
5479    const fn test_mm_castsi128_pd() {
5480        let a = _mm_set1_epi64x(0);
5481        let expected = _mm_set1_pd(0.);
5482        let r = _mm_castsi128_pd(a);
5483        assert_eq_m128d(r, expected);
5484    }
5485
5486    #[simd_test(enable = "sse2")]
5487    const fn test_mm_castsi128_ps() {
5488        let a = _mm_set1_epi32(0);
5489        let expected = _mm_set1_ps(0.);
5490        let r = _mm_castsi128_ps(a);
5491        assert_eq_m128(r, expected);
5492    }
5493}