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