Skip to main content

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

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