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