Skip to main content

fearless_simd/generated/
sse2.rs

1// Copyright 2025 the Fearless_SIMD Authors
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3
4// This file is autogenerated by fearless_simd_gen
5
6#[cfg(all(feature = "libm", not(feature = "std")))]
7#[allow(
8    unused_imports,
9    reason = "Generated backends use different subsets of these helpers"
10)]
11use crate::math::FloatExt as _;
12use crate::{Level, arch_types::ArchTypes, prelude::*, seal::Seal};
13use crate::{
14    f32x4, f32x8, f32x16, f64x2, f64x4, f64x8, i8x16, i8x32, i8x64, i16x8, i16x16, i16x32, i32x4,
15    i32x8, i32x16, i64x2, i64x4, i64x8, mask8x16, mask8x32, mask8x64, mask16x8, mask16x16,
16    mask16x32, mask32x4, mask32x8, mask32x16, mask64x2, mask64x4, mask64x8, u8x16, u8x32, u8x64,
17    u16x8, u16x16, u16x32, u32x4, u32x8, u32x16, u64x2, u64x4, u64x8,
18};
19#[cfg(target_arch = "x86")]
20use core::arch::x86::*;
21#[cfg(target_arch = "x86_64")]
22use core::arch::x86_64::*;
23use core::ops::*;
24#[doc = "A token for SSE2 intrinsics on `x86` and `x86_64`, representing the x86-64 baseline."]
25#[doc = "# Browsing the documentation"]
26#[doc = "The method list on this struct is very verbose."]
27#[doc = "A better way to browse the docs is by looking at vector types such as [`u32x4`], [`f32x4`] or [`mask32x4`]."]
28#[doc = "They include all the operations listed here, and also provide some additional convenience methods."]
29#[derive(Clone, Copy, Debug)]
30pub struct Sse2 {
31    _private: (),
32}
33impl Sse2 {
34    #[doc = "Create a SIMD token proving that SSE2 is available.\n\nThis is the baseline on x86-64 and i686 targets. On i586 it needs runtime detection."]
35    #[doc = r""]
36    #[doc = r" Most users should safely obtain the token from [`Level::new`] instead of calling this function."]
37    #[doc = r""]
38    #[doc = r" This function can be called without an `unsafe` block from a function"]
39    #[doc = r" with all the required target features enabled via the `#[target_feature]` annotation."]
40    #[doc = r""]
41    #[doc = r" # Safety"]
42    #[doc = r""]
43    #[doc = "When invoking this function through an `unsafe` block, the caller must ensure that the current CPU supports `fxsr`, `sse`, `sse2`."]
44    #[inline]
45    #[target_feature(enable = "fxsr,sse,sse2")]
46    pub const fn assume_supported() -> Self {
47        Self { _private: () }
48    }
49}
50impl Seal for Sse2 {}
51impl ExtractToken for Sse2 {
52    type S = Self;
53    #[inline]
54    fn token(&self) -> Self {
55        *self
56    }
57}
58impl ArchTypes for Sse2 {
59    type f32x4 = crate::support::Aligned128<__m128>;
60    type i8x16 = crate::support::Aligned128<__m128i>;
61    type u8x16 = crate::support::Aligned128<__m128i>;
62    type mask8x16 = crate::support::Aligned128<__m128i>;
63    type i16x8 = crate::support::Aligned128<__m128i>;
64    type u16x8 = crate::support::Aligned128<__m128i>;
65    type mask16x8 = crate::support::Aligned128<__m128i>;
66    type i32x4 = crate::support::Aligned128<__m128i>;
67    type u32x4 = crate::support::Aligned128<__m128i>;
68    type mask32x4 = crate::support::Aligned128<__m128i>;
69    type f64x2 = crate::support::Aligned128<__m128d>;
70    type i64x2 = crate::support::Aligned128<__m128i>;
71    type u64x2 = crate::support::Aligned128<__m128i>;
72    type mask64x2 = crate::support::Aligned128<__m128i>;
73    type f32x8 = crate::support::Aligned256<[__m128; 2usize]>;
74    type i8x32 = crate::support::Aligned256<[__m128i; 2usize]>;
75    type u8x32 = crate::support::Aligned256<[__m128i; 2usize]>;
76    type mask8x32 = crate::support::Aligned256<[__m128i; 2usize]>;
77    type i16x16 = crate::support::Aligned256<[__m128i; 2usize]>;
78    type u16x16 = crate::support::Aligned256<[__m128i; 2usize]>;
79    type mask16x16 = crate::support::Aligned256<[__m128i; 2usize]>;
80    type i32x8 = crate::support::Aligned256<[__m128i; 2usize]>;
81    type u32x8 = crate::support::Aligned256<[__m128i; 2usize]>;
82    type mask32x8 = crate::support::Aligned256<[__m128i; 2usize]>;
83    type f64x4 = crate::support::Aligned256<[__m128d; 2usize]>;
84    type i64x4 = crate::support::Aligned256<[__m128i; 2usize]>;
85    type u64x4 = crate::support::Aligned256<[__m128i; 2usize]>;
86    type mask64x4 = crate::support::Aligned256<[__m128i; 2usize]>;
87    type f32x16 = crate::support::Aligned512<[__m128; 4usize]>;
88    type i8x64 = crate::support::Aligned512<[__m128i; 4usize]>;
89    type u8x64 = crate::support::Aligned512<[__m128i; 4usize]>;
90    type mask8x64 = crate::support::Aligned512<[__m128i; 4usize]>;
91    type i16x32 = crate::support::Aligned512<[__m128i; 4usize]>;
92    type u16x32 = crate::support::Aligned512<[__m128i; 4usize]>;
93    type mask16x32 = crate::support::Aligned512<[__m128i; 4usize]>;
94    type i32x16 = crate::support::Aligned512<[__m128i; 4usize]>;
95    type u32x16 = crate::support::Aligned512<[__m128i; 4usize]>;
96    type mask32x16 = crate::support::Aligned512<[__m128i; 4usize]>;
97    type f64x8 = crate::support::Aligned512<[__m128d; 4usize]>;
98    type i64x8 = crate::support::Aligned512<[__m128i; 4usize]>;
99    type u64x8 = crate::support::Aligned512<[__m128i; 4usize]>;
100    type mask64x8 = crate::support::Aligned512<[__m128i; 4usize]>;
101}
102impl Simd for Sse2 {
103    type f32s = f32x4<Self>;
104    type f64s = f64x2<Self>;
105    type u8s = u8x16<Self>;
106    type i8s = i8x16<Self>;
107    type u16s = u16x8<Self>;
108    type i16s = i16x8<Self>;
109    type u32s = u32x4<Self>;
110    type i32s = i32x4<Self>;
111    type u64s = u64x2<Self>;
112    type i64s = i64x2<Self>;
113    type mask8s = mask8x16<Self>;
114    type mask16s = mask16x8<Self>;
115    type mask32s = mask32x4<Self>;
116    type mask64s = mask64x2<Self>;
117    #[inline(always)]
118    fn level(self) -> Level {
119        Level::Sse2(self)
120    }
121    #[inline]
122    fn vectorize<F: FnOnce() -> R, R>(self, f: F) -> R {
123        #[inline]
124        #[target_feature(enable = "fxsr,sse,sse2")]
125        fn vectorize_sse2<F: FnOnce() -> R, R>(f: F) -> R {
126            f()
127        }
128        unsafe { vectorize_sse2(f) }
129    }
130    #[inline(always)]
131    fn abs_f32x4(self, a: f32x4<Self>) -> f32x4<Self> {
132        crate::kernel!(
133            #[inline(always)]
134            fn kernel(token: Sse2, a: f32x4<Sse2>) -> f32x4<Sse2> {
135                _mm_andnot_ps(_mm_set1_ps(-0.0), a.into()).simd_into(token)
136            }
137        );
138        kernel(self, a)
139    }
140    #[inline(always)]
141    fn splat_f32x4(self, val: f32) -> f32x4<Self> {
142        crate::kernel!(
143            #[inline(always)]
144            fn kernel(token: Sse2, val: f32) -> f32x4<Sse2> {
145                _mm_set1_ps(val).simd_into(token)
146            }
147        );
148        kernel(self, val)
149    }
150    #[inline(always)]
151    fn reverse_f32x4(self, a: f32x4<Self>) -> f32x4<Self> {
152        [a[3usize], a[2usize], a[1usize], a[0usize]].simd_into(self)
153    }
154    #[inline(always)]
155    fn slide_f32x4<const SHIFT: usize>(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self> {
156        if SHIFT >= 4usize {
157            return b;
158        }
159        let result = dyn_alignr_128(
160            self,
161            Bytes::to_bytes(b).val.0,
162            Bytes::to_bytes(a).val.0,
163            SHIFT * 4usize,
164        );
165        Bytes::from_bytes(u8x16 {
166            val: crate::support::Aligned128(result),
167            simd: self,
168        })
169    }
170    #[inline(always)]
171    fn compress_f32x4(self, values: f32x4<Self>, mask: mask32x4<Self>) -> f32x4<Self> {
172        let mask = mask8x16 {
173            val: crate::transmute::checked_transmute_copy(&mask.val),
174            simd: self,
175        };
176        Bytes::from_bytes(self.compress_u8x16(Bytes::to_bytes(values), mask))
177    }
178    #[inline(always)]
179    fn compress_merge_f32x4(
180        self,
181        values: f32x4<Self>,
182        mask: mask32x4<Self>,
183        merge: f32x4<Self>,
184    ) -> f32x4<Self> {
185        let mask = mask8x16 {
186            val: crate::transmute::checked_transmute_copy(&mask.val),
187            simd: self,
188        };
189        Bytes::from_bytes(self.compress_merge_u8x16(
190            Bytes::to_bytes(values),
191            mask,
192            Bytes::to_bytes(merge),
193        ))
194    }
195    #[inline(always)]
196    fn expand_f32x4(self, values: f32x4<Self>, mask: mask32x4<Self>) -> f32x4<Self> {
197        let mask = mask8x16 {
198            val: crate::transmute::checked_transmute_copy(&mask.val),
199            simd: self,
200        };
201        Bytes::from_bytes(self.expand_u8x16(Bytes::to_bytes(values), mask))
202    }
203    #[inline(always)]
204    fn expand_merge_f32x4(
205        self,
206        values: f32x4<Self>,
207        mask: mask32x4<Self>,
208        merge: f32x4<Self>,
209    ) -> f32x4<Self> {
210        let mask = mask8x16 {
211            val: crate::transmute::checked_transmute_copy(&mask.val),
212            simd: self,
213        };
214        Bytes::from_bytes(self.expand_merge_u8x16(
215            Bytes::to_bytes(values),
216            mask,
217            Bytes::to_bytes(merge),
218        ))
219    }
220    #[inline(always)]
221    fn neg_f32x4(self, a: f32x4<Self>) -> f32x4<Self> {
222        crate::kernel!(
223            #[inline(always)]
224            fn kernel(token: Sse2, a: f32x4<Sse2>) -> f32x4<Sse2> {
225                _mm_xor_ps(a.into(), _mm_set1_ps(-0.0)).simd_into(token)
226            }
227        );
228        kernel(self, a)
229    }
230    #[inline(always)]
231    fn sqrt_f32x4(self, a: f32x4<Self>) -> f32x4<Self> {
232        crate::kernel!(
233            #[inline(always)]
234            fn kernel(token: Sse2, a: f32x4<Sse2>) -> f32x4<Sse2> {
235                _mm_sqrt_ps(a.into()).simd_into(token)
236            }
237        );
238        kernel(self, a)
239    }
240    #[inline(always)]
241    fn approximate_recip_f32x4(self, a: f32x4<Self>) -> f32x4<Self> {
242        crate::kernel!(
243            #[inline(always)]
244            fn kernel(token: Sse2, a: f32x4<Sse2>) -> f32x4<Sse2> {
245                _mm_rcp_ps(a.into()).simd_into(token)
246            }
247        );
248        kernel(self, a)
249    }
250    #[inline(always)]
251    fn add_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self> {
252        crate::kernel!(
253            #[inline(always)]
254            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> f32x4<Sse2> {
255                _mm_add_ps(a.into(), b.into()).simd_into(token)
256            }
257        );
258        kernel(self, a, b)
259    }
260    #[inline(always)]
261    fn sub_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self> {
262        crate::kernel!(
263            #[inline(always)]
264            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> f32x4<Sse2> {
265                _mm_sub_ps(a.into(), b.into()).simd_into(token)
266            }
267        );
268        kernel(self, a, b)
269    }
270    #[inline(always)]
271    fn mul_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self> {
272        crate::kernel!(
273            #[inline(always)]
274            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> f32x4<Sse2> {
275                _mm_mul_ps(a.into(), b.into()).simd_into(token)
276            }
277        );
278        kernel(self, a, b)
279    }
280    #[inline(always)]
281    fn div_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self> {
282        crate::kernel!(
283            #[inline(always)]
284            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> f32x4<Sse2> {
285                _mm_div_ps(a.into(), b.into()).simd_into(token)
286            }
287        );
288        kernel(self, a, b)
289    }
290    #[inline(always)]
291    fn copysign_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self> {
292        crate::kernel!(
293            #[inline(always)]
294            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> f32x4<Sse2> {
295                let mask = _mm_set1_ps(-0.0);
296                _mm_or_ps(_mm_and_ps(mask, b.into()), _mm_andnot_ps(mask, a.into()))
297                    .simd_into(token)
298            }
299        );
300        kernel(self, a, b)
301    }
302    #[inline(always)]
303    fn reduce_max_f32x4(self, a: f32x4<Self>) -> f32 {
304        crate::kernel!(
305            #[inline(always)]
306            fn kernel(token: Sse2, a: f32x4<Sse2>) -> f32 {
307                let reduced: __m128 = a.into();
308                let shifted = _mm_castsi128_ps(_mm_srli_si128::<8>(_mm_castps_si128(reduced)));
309                let reduced = { _mm_max_ps(reduced, shifted) };
310                let shifted = _mm_castsi128_ps(_mm_srli_si128::<4>(_mm_castps_si128(reduced)));
311                let reduced = { _mm_max_ps(reduced, shifted) };
312                _mm_cvtss_f32(reduced)
313            }
314        );
315        kernel(self, a)
316    }
317    #[inline(always)]
318    fn reduce_min_f32x4(self, a: f32x4<Self>) -> f32 {
319        crate::kernel!(
320            #[inline(always)]
321            fn kernel(token: Sse2, a: f32x4<Sse2>) -> f32 {
322                let reduced: __m128 = a.into();
323                let shifted = _mm_castsi128_ps(_mm_srli_si128::<8>(_mm_castps_si128(reduced)));
324                let reduced = { _mm_min_ps(reduced, shifted) };
325                let shifted = _mm_castsi128_ps(_mm_srli_si128::<4>(_mm_castps_si128(reduced)));
326                let reduced = { _mm_min_ps(reduced, shifted) };
327                _mm_cvtss_f32(reduced)
328            }
329        );
330        kernel(self, a)
331    }
332    #[inline(always)]
333    fn reduce_max_precise_f32x4(self, a: f32x4<Self>) -> f32 {
334        crate::kernel!(
335            #[inline(always)]
336            fn kernel(token: Sse2, a: f32x4<Sse2>) -> f32 {
337                let reduced: __m128 = a.into();
338                let shifted = _mm_castsi128_ps(_mm_srli_si128::<8>(_mm_castps_si128(reduced)));
339                let reduced = {
340                    let intermediate = _mm_max_ps(reduced, shifted);
341                    let shifted_is_nan = _mm_cmpunord_ps(shifted, shifted);
342                    _mm_or_ps(
343                        _mm_and_ps(shifted_is_nan, reduced),
344                        _mm_andnot_ps(shifted_is_nan, intermediate),
345                    )
346                };
347                let shifted = _mm_castsi128_ps(_mm_srli_si128::<4>(_mm_castps_si128(reduced)));
348                let reduced = {
349                    let intermediate = _mm_max_ps(reduced, shifted);
350                    let shifted_is_nan = _mm_cmpunord_ps(shifted, shifted);
351                    _mm_or_ps(
352                        _mm_and_ps(shifted_is_nan, reduced),
353                        _mm_andnot_ps(shifted_is_nan, intermediate),
354                    )
355                };
356                _mm_cvtss_f32(reduced)
357            }
358        );
359        kernel(self, a)
360    }
361    #[inline(always)]
362    fn reduce_min_precise_f32x4(self, a: f32x4<Self>) -> f32 {
363        crate::kernel!(
364            #[inline(always)]
365            fn kernel(token: Sse2, a: f32x4<Sse2>) -> f32 {
366                let reduced: __m128 = a.into();
367                let shifted = _mm_castsi128_ps(_mm_srli_si128::<8>(_mm_castps_si128(reduced)));
368                let reduced = {
369                    let intermediate = _mm_min_ps(reduced, shifted);
370                    let shifted_is_nan = _mm_cmpunord_ps(shifted, shifted);
371                    _mm_or_ps(
372                        _mm_and_ps(shifted_is_nan, reduced),
373                        _mm_andnot_ps(shifted_is_nan, intermediate),
374                    )
375                };
376                let shifted = _mm_castsi128_ps(_mm_srli_si128::<4>(_mm_castps_si128(reduced)));
377                let reduced = {
378                    let intermediate = _mm_min_ps(reduced, shifted);
379                    let shifted_is_nan = _mm_cmpunord_ps(shifted, shifted);
380                    _mm_or_ps(
381                        _mm_and_ps(shifted_is_nan, reduced),
382                        _mm_andnot_ps(shifted_is_nan, intermediate),
383                    )
384                };
385                _mm_cvtss_f32(reduced)
386            }
387        );
388        kernel(self, a)
389    }
390    #[inline(always)]
391    fn reduce_sum_f32x4(self, a: f32x4<Self>) -> f32 {
392        crate::kernel!(
393            #[inline(always)]
394            fn kernel(token: Sse2, a: f32x4<Sse2>) -> f32 {
395                let a: __m128 = a.into();
396                let adjacent = _mm_add_ps(a, _mm_shuffle_ps::<0b10_11_00_01>(a, a));
397                _mm_cvtss_f32(_mm_add_ss(adjacent, _mm_movehl_ps(adjacent, adjacent)))
398            }
399        );
400        kernel(self, a)
401    }
402    #[inline(always)]
403    fn reduce_product_f32x4(self, a: f32x4<Self>) -> f32 {
404        crate::kernel!(
405            #[inline(always)]
406            fn kernel(token: Sse2, a: f32x4<Sse2>) -> f32 {
407                let a: __m128 = a.into();
408                let adjacent = _mm_mul_ps(a, _mm_shuffle_ps::<0b10_11_00_01>(a, a));
409                _mm_cvtss_f32(_mm_mul_ss(adjacent, _mm_movehl_ps(adjacent, adjacent)))
410            }
411        );
412        kernel(self, a)
413    }
414    #[inline(always)]
415    fn max_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self> {
416        crate::kernel!(
417            #[inline(always)]
418            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> f32x4<Sse2> {
419                _mm_max_ps(a.into(), b.into()).simd_into(token)
420            }
421        );
422        kernel(self, a, b)
423    }
424    #[inline(always)]
425    fn min_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self> {
426        crate::kernel!(
427            #[inline(always)]
428            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> f32x4<Sse2> {
429                _mm_min_ps(a.into(), b.into()).simd_into(token)
430            }
431        );
432        kernel(self, a, b)
433    }
434    #[inline(always)]
435    fn max_precise_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self> {
436        crate::kernel!(
437            #[inline(always)]
438            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> f32x4<Sse2> {
439                let a = a.into();
440                let b = b.into();
441                let intermediate = _mm_max_ps(a, b);
442                let b_is_nan = _mm_cmpunord_ps(b, b);
443                _mm_or_ps(
444                    _mm_and_ps(b_is_nan, a),
445                    _mm_andnot_ps(b_is_nan, intermediate),
446                )
447                .simd_into(token)
448            }
449        );
450        kernel(self, a, b)
451    }
452    #[inline(always)]
453    fn min_precise_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self> {
454        crate::kernel!(
455            #[inline(always)]
456            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> f32x4<Sse2> {
457                let a = a.into();
458                let b = b.into();
459                let intermediate = _mm_min_ps(a, b);
460                let b_is_nan = _mm_cmpunord_ps(b, b);
461                _mm_or_ps(
462                    _mm_and_ps(b_is_nan, a),
463                    _mm_andnot_ps(b_is_nan, intermediate),
464                )
465                .simd_into(token)
466            }
467        );
468        kernel(self, a, b)
469    }
470    #[inline(always)]
471    fn clamp_f32x4(self, a: f32x4<Self>, b: f32x4<Self>, c: f32x4<Self>) -> f32x4<Self> {
472        crate::kernel!(
473            #[inline(always)]
474            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>, c: f32x4<Sse2>) -> f32x4<Sse2> {
475                debug_assert!(
476                    b.simd_le(c).all_true(),
477                    "clamp requires min <= max for all elements"
478                );
479                _mm_min_ps(c.into(), _mm_max_ps(b.into(), a.into())).simd_into(token)
480            }
481        );
482        kernel(self, a, b, c)
483    }
484    #[inline(always)]
485    fn simd_eq_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> mask32x4<Self> {
486        crate::kernel!(
487            #[inline(always)]
488            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> mask32x4<Sse2> {
489                _mm_castps_si128(_mm_cmpeq_ps(a.into(), b.into())).simd_into(token)
490            }
491        );
492        kernel(self, a, b)
493    }
494    #[inline(always)]
495    fn simd_ne_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> mask32x4<Self> {
496        crate::kernel!(
497            #[inline(always)]
498            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> mask32x4<Sse2> {
499                _mm_castps_si128(_mm_cmpneq_ps(a.into(), b.into())).simd_into(token)
500            }
501        );
502        kernel(self, a, b)
503    }
504    #[inline(always)]
505    fn simd_lt_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> mask32x4<Self> {
506        crate::kernel!(
507            #[inline(always)]
508            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> mask32x4<Sse2> {
509                _mm_castps_si128(_mm_cmplt_ps(a.into(), b.into())).simd_into(token)
510            }
511        );
512        kernel(self, a, b)
513    }
514    #[inline(always)]
515    fn simd_le_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> mask32x4<Self> {
516        crate::kernel!(
517            #[inline(always)]
518            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> mask32x4<Sse2> {
519                _mm_castps_si128(_mm_cmple_ps(a.into(), b.into())).simd_into(token)
520            }
521        );
522        kernel(self, a, b)
523    }
524    #[inline(always)]
525    fn zip_low_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self> {
526        crate::kernel!(
527            #[inline(always)]
528            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> f32x4<Sse2> {
529                _mm_unpacklo_ps(a.into(), b.into()).simd_into(token)
530            }
531        );
532        kernel(self, a, b)
533    }
534    #[inline(always)]
535    fn zip_high_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self> {
536        crate::kernel!(
537            #[inline(always)]
538            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> f32x4<Sse2> {
539                _mm_unpackhi_ps(a.into(), b.into()).simd_into(token)
540            }
541        );
542        kernel(self, a, b)
543    }
544    #[inline(always)]
545    fn unzip_low_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self> {
546        crate::kernel!(
547            #[inline(always)]
548            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> f32x4<Sse2> {
549                _mm_shuffle_ps::<0b10_00_10_00>(a.into(), b.into()).simd_into(token)
550            }
551        );
552        kernel(self, a, b)
553    }
554    #[inline(always)]
555    fn unzip_high_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self> {
556        crate::kernel!(
557            #[inline(always)]
558            fn kernel(token: Sse2, a: f32x4<Sse2>, b: f32x4<Sse2>) -> f32x4<Sse2> {
559                _mm_shuffle_ps::<0b11_01_11_01>(a.into(), b.into()).simd_into(token)
560            }
561        );
562        kernel(self, a, b)
563    }
564    #[inline(always)]
565    fn interleave_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> (f32x4<Self>, f32x4<Self>) {
566        (self.zip_low_f32x4(a, b), self.zip_high_f32x4(a, b))
567    }
568    #[inline(always)]
569    fn deinterleave_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> (f32x4<Self>, f32x4<Self>) {
570        (self.unzip_low_f32x4(a, b), self.unzip_high_f32x4(a, b))
571    }
572    #[inline(always)]
573    fn mul_add_f32x4(self, a: f32x4<Self>, b: f32x4<Self>, c: f32x4<Self>) -> f32x4<Self> {
574        a * b + c
575    }
576    #[inline(always)]
577    fn mul_add_precise_f32x4(self, a: f32x4<Self>, b: f32x4<Self>, c: f32x4<Self>) -> f32x4<Self> {
578        crate::math::mul_add_precise_f32x4(self, a, b, c)
579    }
580    #[inline(always)]
581    fn mul_sub_f32x4(self, a: f32x4<Self>, b: f32x4<Self>, c: f32x4<Self>) -> f32x4<Self> {
582        a * b - c
583    }
584    #[inline(always)]
585    fn mul_sub_precise_f32x4(self, a: f32x4<Self>, b: f32x4<Self>, c: f32x4<Self>) -> f32x4<Self> {
586        self.mul_add_precise_f32x4(a, b, -c)
587    }
588    #[inline(always)]
589    fn floor_f32x4(self, a: f32x4<Self>) -> f32x4<Self> {
590        [
591            f32::floor(a[0usize]),
592            f32::floor(a[1usize]),
593            f32::floor(a[2usize]),
594            f32::floor(a[3usize]),
595        ]
596        .simd_into(self)
597    }
598    #[inline(always)]
599    fn ceil_f32x4(self, a: f32x4<Self>) -> f32x4<Self> {
600        [
601            f32::ceil(a[0usize]),
602            f32::ceil(a[1usize]),
603            f32::ceil(a[2usize]),
604            f32::ceil(a[3usize]),
605        ]
606        .simd_into(self)
607    }
608    #[inline(always)]
609    fn round_ties_even_f32x4(self, a: f32x4<Self>) -> f32x4<Self> {
610        [
611            f32::round_ties_even(a[0usize]),
612            f32::round_ties_even(a[1usize]),
613            f32::round_ties_even(a[2usize]),
614            f32::round_ties_even(a[3usize]),
615        ]
616        .simd_into(self)
617    }
618    #[inline(always)]
619    fn round_f32x4(self, a: f32x4<Self>) -> f32x4<Self> {
620        let bias = self.splat_f32x4(const { f32::next_down(0.5) });
621        (a + self.copysign_f32x4(bias, a)).trunc()
622    }
623    #[inline(always)]
624    fn fract_f32x4(self, a: f32x4<Self>) -> f32x4<Self> {
625        a - self.trunc_f32x4(a)
626    }
627    #[inline(always)]
628    fn trunc_f32x4(self, a: f32x4<Self>) -> f32x4<Self> {
629        [
630            f32::trunc(a[0usize]),
631            f32::trunc(a[1usize]),
632            f32::trunc(a[2usize]),
633            f32::trunc(a[3usize]),
634        ]
635        .simd_into(self)
636    }
637    #[inline(always)]
638    fn to_degrees_f32x4(self, a: f32x4<Self>) -> f32x4<Self> {
639        a * const { f32::to_degrees(1.0) }
640    }
641    #[inline(always)]
642    fn to_radians_f32x4(self, a: f32x4<Self>) -> f32x4<Self> {
643        a * const { f32::to_radians(1.0) }
644    }
645    #[inline(always)]
646    fn is_nan_f32x4(self, a: f32x4<Self>) -> mask32x4<Self> {
647        a.simd_ne(a)
648    }
649    #[inline(always)]
650    fn is_infinite_f32x4(self, a: f32x4<Self>) -> mask32x4<Self> {
651        a.abs().simd_eq(f32::INFINITY)
652    }
653    #[inline(always)]
654    fn is_finite_f32x4(self, a: f32x4<Self>) -> mask32x4<Self> {
655        a.abs().simd_lt(f32::INFINITY)
656    }
657    #[inline(always)]
658    fn is_subnormal_f32x4(self, a: f32x4<Self>) -> mask32x4<Self> {
659        let i: i32x4<Self> = a.bitcast();
660        (i & 0x7F80_0000_i32).simd_eq(0) & (i & 0x007F_FFFF_i32).simd_ne(0)
661    }
662    #[inline(always)]
663    fn is_normal_f32x4(self, a: f32x4<Self>) -> mask32x4<Self> {
664        let i: i32x4<Self> = a.bitcast();
665        let exp = i & 0x7F80_0000_i32;
666        exp.simd_ne(0) & exp.simd_ne(0x7F80_0000_i32)
667    }
668    #[inline(always)]
669    fn is_sign_positive_f32x4(self, a: f32x4<Self>) -> mask32x4<Self> {
670        let i: i32x4<Self> = a.bitcast();
671        (i & i32::MIN).simd_eq(0)
672    }
673    #[inline(always)]
674    fn is_sign_negative_f32x4(self, a: f32x4<Self>) -> mask32x4<Self> {
675        !a.is_sign_positive()
676    }
677    #[inline(always)]
678    fn select_f32x4(self, a: mask32x4<Self>, b: f32x4<Self>, c: f32x4<Self>) -> f32x4<Self> {
679        crate::kernel!(
680            #[inline(always)]
681            fn kernel(
682                token: Sse2,
683                a: mask32x4<Sse2>,
684                b: f32x4<Sse2>,
685                c: f32x4<Sse2>,
686            ) -> f32x4<Sse2> {
687                _mm_or_ps(
688                    _mm_and_ps(_mm_castsi128_ps(a.into()), b.into()),
689                    _mm_andnot_ps(_mm_castsi128_ps(a.into()), c.into()),
690                )
691                .simd_into(token)
692            }
693        );
694        kernel(self, a, b, c)
695    }
696    #[inline(always)]
697    fn combine_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x8<Self> {
698        f32x8 {
699            val: crate::support::Aligned256([a.val.0, b.val.0]),
700            simd: self,
701        }
702    }
703    #[inline(always)]
704    fn load_four_interleaved_f32x4(self, src: &[f32; 16usize]) -> [f32x4<Self>; 4usize] {
705        crate::kernel!(
706            #[inline(always)]
707            fn kernel(token: Sse2, src: &[f32; 16usize]) -> [f32x4<Sse2>; 4usize] {
708                let (chunks, []) = src.as_chunks::<4usize>() else {
709                    unreachable!()
710                };
711                let v0: __m128 =
712                    crate::transmute::checked_transmute_copy::<[f32; 4usize], __m128>(&chunks[0]);
713                let v1: __m128 =
714                    crate::transmute::checked_transmute_copy::<[f32; 4usize], __m128>(&chunks[1]);
715                let v2: __m128 =
716                    crate::transmute::checked_transmute_copy::<[f32; 4usize], __m128>(&chunks[2]);
717                let v3: __m128 =
718                    crate::transmute::checked_transmute_copy::<[f32; 4usize], __m128>(&chunks[3]);
719                let tmp0 = _mm_unpacklo_ps(v0, v1);
720                let tmp1 = _mm_unpackhi_ps(v0, v1);
721                let tmp2 = _mm_unpacklo_ps(v2, v3);
722                let tmp3 = _mm_unpackhi_ps(v2, v3);
723                let out0 = _mm_castpd_ps(_mm_unpacklo_pd(_mm_castps_pd(tmp0), _mm_castps_pd(tmp2)));
724                let out1 = _mm_castpd_ps(_mm_unpackhi_pd(_mm_castps_pd(tmp0), _mm_castps_pd(tmp2)));
725                let out2 = _mm_castpd_ps(_mm_unpacklo_pd(_mm_castps_pd(tmp1), _mm_castps_pd(tmp3)));
726                let out3 = _mm_castpd_ps(_mm_unpackhi_pd(_mm_castps_pd(tmp1), _mm_castps_pd(tmp3)));
727                [
728                    out0.simd_into(token),
729                    out1.simd_into(token),
730                    out2.simd_into(token),
731                    out3.simd_into(token),
732                ]
733            }
734        );
735        kernel(self, src)
736    }
737    #[inline(always)]
738    fn store_four_interleaved_f32x4(
739        self,
740        vectors: [f32x4<Self>; 4usize],
741        dest: &mut [f32; 16usize],
742    ) -> () {
743        crate::kernel!(
744            #[inline(always)]
745            fn kernel(
746                token: Sse2,
747                vectors: [f32x4<Sse2>; 4usize],
748                dest: &mut [f32; 16usize],
749            ) -> () {
750                let _ = token;
751                let v0: __m128 = vectors[0].into();
752                let v1: __m128 = vectors[1].into();
753                let v2: __m128 = vectors[2].into();
754                let v3: __m128 = vectors[3].into();
755                let tmp0 = _mm_unpacklo_ps(v0, v1);
756                let tmp1 = _mm_unpackhi_ps(v0, v1);
757                let tmp2 = _mm_unpacklo_ps(v2, v3);
758                let tmp3 = _mm_unpackhi_ps(v2, v3);
759                let out0 = _mm_castpd_ps(_mm_unpacklo_pd(_mm_castps_pd(tmp0), _mm_castps_pd(tmp2)));
760                let out1 = _mm_castpd_ps(_mm_unpackhi_pd(_mm_castps_pd(tmp0), _mm_castps_pd(tmp2)));
761                let out2 = _mm_castpd_ps(_mm_unpacklo_pd(_mm_castps_pd(tmp1), _mm_castps_pd(tmp3)));
762                let out3 = _mm_castpd_ps(_mm_unpackhi_pd(_mm_castps_pd(tmp1), _mm_castps_pd(tmp3)));
763                let (chunks, []) = dest.as_chunks_mut::<4usize>() else {
764                    unreachable!()
765                };
766                crate::transmute::checked_transmute_store::<__m128, [f32; 4usize]>(
767                    out0,
768                    &mut chunks[0],
769                );
770                crate::transmute::checked_transmute_store::<__m128, [f32; 4usize]>(
771                    out1,
772                    &mut chunks[1],
773                );
774                crate::transmute::checked_transmute_store::<__m128, [f32; 4usize]>(
775                    out2,
776                    &mut chunks[2],
777                );
778                crate::transmute::checked_transmute_store::<__m128, [f32; 4usize]>(
779                    out3,
780                    &mut chunks[3],
781                );
782            }
783        );
784        kernel(self, vectors, dest);
785    }
786    #[inline(always)]
787    fn widen_f32x4(self, a: f32x4<Self>) -> (f64x2<Self>, f64x2<Self>) {
788        crate::kernel!(
789            #[inline(always)]
790            fn kernel(token: Sse2, a: f32x4<Sse2>) -> (f64x2<Sse2>, f64x2<Sse2>) {
791                let raw = a.into();
792                (
793                    _mm_cvtps_pd(raw).simd_into(token),
794                    _mm_cvtps_pd(_mm_movehl_ps(raw, raw)).simd_into(token),
795                )
796            }
797        );
798        kernel(self, a)
799    }
800    #[inline(always)]
801    fn cvt_u32_f32x4(self, a: f32x4<Self>) -> u32x4<Self> {
802        crate::kernel!(
803            #[inline(always)]
804            fn kernel(token: Sse2, a: f32x4<Sse2>) -> u32x4<Sse2> {
805                let mut converted = _mm_cvttps_epi32(a.into());
806                let in_range = _mm_cmplt_ps(a.into(), _mm_set1_ps(2147483648.0));
807                let all_in_range = _mm_movemask_ps(in_range) == 0b1111;
808                if !all_in_range {
809                    let excess = _mm_sub_ps(a.into(), _mm_set1_ps(2147483648.0));
810                    let excess_converted = _mm_cvttps_epi32(_mm_andnot_ps(in_range, excess));
811                    converted = _mm_add_epi32(converted, excess_converted);
812                }
813                converted.simd_into(token)
814            }
815        );
816        kernel(self, a)
817    }
818    #[inline(always)]
819    fn cvt_u32_precise_f32x4(self, a: f32x4<Self>) -> u32x4<Self> {
820        crate::kernel!(
821            #[inline(always)]
822            fn kernel(token: Sse2, a: f32x4<Sse2>) -> u32x4<Sse2> {
823                let a = _mm_max_ps(a.into(), _mm_setzero_ps());
824                let mut converted = _mm_cvttps_epi32(a);
825                let in_range = _mm_cmplt_ps(a, _mm_set1_ps(2147483648.0));
826                let all_in_range = _mm_movemask_ps(in_range) == 0b1111;
827                if !all_in_range {
828                    let exceeds_unsigned_range =
829                        _mm_castps_si128(_mm_cmplt_ps(_mm_set1_ps(4294967040.0), a));
830                    let excess = _mm_sub_ps(a, _mm_set1_ps(2147483648.0));
831                    let excess_converted = _mm_cvttps_epi32(_mm_andnot_ps(in_range, excess));
832                    converted = _mm_add_epi32(converted, excess_converted);
833                    converted = _mm_or_si128(converted, exceeds_unsigned_range);
834                }
835                converted.simd_into(token)
836            }
837        );
838        kernel(self, a)
839    }
840    #[inline(always)]
841    fn cvt_i32_f32x4(self, a: f32x4<Self>) -> i32x4<Self> {
842        crate::kernel!(
843            #[inline(always)]
844            fn kernel(token: Sse2, a: f32x4<Sse2>) -> i32x4<Sse2> {
845                _mm_cvttps_epi32(a.into()).simd_into(token)
846            }
847        );
848        kernel(self, a)
849    }
850    #[inline(always)]
851    fn cvt_i32_precise_f32x4(self, a: f32x4<Self>) -> i32x4<Self> {
852        crate::kernel!(
853            #[inline(always)]
854            fn kernel(token: Sse2, a: f32x4<Sse2>) -> i32x4<Sse2> {
855                let a = a.into();
856                let converted = _mm_cvttps_epi32(a);
857                let positive_overflow =
858                    _mm_castps_si128(_mm_cmple_ps(_mm_set1_ps(2147483648.0), a));
859                let converted = _mm_xor_si128(converted, positive_overflow);
860                let is_not_nan = _mm_castps_si128(_mm_cmpord_ps(a, a));
861                _mm_and_si128(converted, is_not_nan).simd_into(token)
862            }
863        );
864        kernel(self, a)
865    }
866    #[inline(always)]
867    fn abs_i8x16(self, a: i8x16<Self>) -> i8x16<Self> {
868        [
869            i8::wrapping_abs(a[0usize]),
870            i8::wrapping_abs(a[1usize]),
871            i8::wrapping_abs(a[2usize]),
872            i8::wrapping_abs(a[3usize]),
873            i8::wrapping_abs(a[4usize]),
874            i8::wrapping_abs(a[5usize]),
875            i8::wrapping_abs(a[6usize]),
876            i8::wrapping_abs(a[7usize]),
877            i8::wrapping_abs(a[8usize]),
878            i8::wrapping_abs(a[9usize]),
879            i8::wrapping_abs(a[10usize]),
880            i8::wrapping_abs(a[11usize]),
881            i8::wrapping_abs(a[12usize]),
882            i8::wrapping_abs(a[13usize]),
883            i8::wrapping_abs(a[14usize]),
884            i8::wrapping_abs(a[15usize]),
885        ]
886        .simd_into(self)
887    }
888    #[inline(always)]
889    fn splat_i8x16(self, val: i8) -> i8x16<Self> {
890        crate::kernel!(
891            #[inline(always)]
892            fn kernel(token: Sse2, val: i8) -> i8x16<Sse2> {
893                _mm_set1_epi8(val).simd_into(token)
894            }
895        );
896        kernel(self, val)
897    }
898    #[inline(always)]
899    fn reverse_i8x16(self, a: i8x16<Self>) -> i8x16<Self> {
900        [
901            a[15usize], a[14usize], a[13usize], a[12usize], a[11usize], a[10usize], a[9usize],
902            a[8usize], a[7usize], a[6usize], a[5usize], a[4usize], a[3usize], a[2usize], a[1usize],
903            a[0usize],
904        ]
905        .simd_into(self)
906    }
907    #[inline(always)]
908    fn slide_i8x16<const SHIFT: usize>(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
909        if SHIFT >= 16usize {
910            return b;
911        }
912        let result = dyn_alignr_128(
913            self,
914            Bytes::to_bytes(b).val.0,
915            Bytes::to_bytes(a).val.0,
916            SHIFT,
917        );
918        Bytes::from_bytes(u8x16 {
919            val: crate::support::Aligned128(result),
920            simd: self,
921        })
922    }
923    #[inline(always)]
924    fn compress_i8x16(self, values: i8x16<Self>, mask: mask8x16<Self>) -> i8x16<Self> {
925        let mask = mask8x16 {
926            val: crate::transmute::checked_transmute_copy(&mask.val),
927            simd: self,
928        };
929        Bytes::from_bytes(self.compress_u8x16(Bytes::to_bytes(values), mask))
930    }
931    #[inline(always)]
932    fn compress_merge_i8x16(
933        self,
934        values: i8x16<Self>,
935        mask: mask8x16<Self>,
936        merge: i8x16<Self>,
937    ) -> i8x16<Self> {
938        let mask = mask8x16 {
939            val: crate::transmute::checked_transmute_copy(&mask.val),
940            simd: self,
941        };
942        Bytes::from_bytes(self.compress_merge_u8x16(
943            Bytes::to_bytes(values),
944            mask,
945            Bytes::to_bytes(merge),
946        ))
947    }
948    #[inline(always)]
949    fn expand_i8x16(self, values: i8x16<Self>, mask: mask8x16<Self>) -> i8x16<Self> {
950        let mask = mask8x16 {
951            val: crate::transmute::checked_transmute_copy(&mask.val),
952            simd: self,
953        };
954        Bytes::from_bytes(self.expand_u8x16(Bytes::to_bytes(values), mask))
955    }
956    #[inline(always)]
957    fn expand_merge_i8x16(
958        self,
959        values: i8x16<Self>,
960        mask: mask8x16<Self>,
961        merge: i8x16<Self>,
962    ) -> i8x16<Self> {
963        let mask = mask8x16 {
964            val: crate::transmute::checked_transmute_copy(&mask.val),
965            simd: self,
966        };
967        Bytes::from_bytes(self.expand_merge_u8x16(
968            Bytes::to_bytes(values),
969            mask,
970            Bytes::to_bytes(merge),
971        ))
972    }
973    #[inline(always)]
974    fn count_ones_i8x16(self, a: i8x16<Self>) -> i8x16<Self> {
975        [
976            i8::try_from(a[0usize].count_ones()).unwrap(),
977            i8::try_from(a[1usize].count_ones()).unwrap(),
978            i8::try_from(a[2usize].count_ones()).unwrap(),
979            i8::try_from(a[3usize].count_ones()).unwrap(),
980            i8::try_from(a[4usize].count_ones()).unwrap(),
981            i8::try_from(a[5usize].count_ones()).unwrap(),
982            i8::try_from(a[6usize].count_ones()).unwrap(),
983            i8::try_from(a[7usize].count_ones()).unwrap(),
984            i8::try_from(a[8usize].count_ones()).unwrap(),
985            i8::try_from(a[9usize].count_ones()).unwrap(),
986            i8::try_from(a[10usize].count_ones()).unwrap(),
987            i8::try_from(a[11usize].count_ones()).unwrap(),
988            i8::try_from(a[12usize].count_ones()).unwrap(),
989            i8::try_from(a[13usize].count_ones()).unwrap(),
990            i8::try_from(a[14usize].count_ones()).unwrap(),
991            i8::try_from(a[15usize].count_ones()).unwrap(),
992        ]
993        .simd_into(self)
994    }
995    #[inline(always)]
996    fn count_zeros_i8x16(self, a: i8x16<Self>) -> i8x16<Self> {
997        [
998            i8::try_from(a[0usize].count_zeros()).unwrap(),
999            i8::try_from(a[1usize].count_zeros()).unwrap(),
1000            i8::try_from(a[2usize].count_zeros()).unwrap(),
1001            i8::try_from(a[3usize].count_zeros()).unwrap(),
1002            i8::try_from(a[4usize].count_zeros()).unwrap(),
1003            i8::try_from(a[5usize].count_zeros()).unwrap(),
1004            i8::try_from(a[6usize].count_zeros()).unwrap(),
1005            i8::try_from(a[7usize].count_zeros()).unwrap(),
1006            i8::try_from(a[8usize].count_zeros()).unwrap(),
1007            i8::try_from(a[9usize].count_zeros()).unwrap(),
1008            i8::try_from(a[10usize].count_zeros()).unwrap(),
1009            i8::try_from(a[11usize].count_zeros()).unwrap(),
1010            i8::try_from(a[12usize].count_zeros()).unwrap(),
1011            i8::try_from(a[13usize].count_zeros()).unwrap(),
1012            i8::try_from(a[14usize].count_zeros()).unwrap(),
1013            i8::try_from(a[15usize].count_zeros()).unwrap(),
1014        ]
1015        .simd_into(self)
1016    }
1017    #[inline(always)]
1018    fn add_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
1019        crate::kernel!(
1020            #[inline(always)]
1021            fn kernel(token: Sse2, a: i8x16<Sse2>, b: i8x16<Sse2>) -> i8x16<Sse2> {
1022                _mm_add_epi8(a.into(), b.into()).simd_into(token)
1023            }
1024        );
1025        kernel(self, a, b)
1026    }
1027    #[inline(always)]
1028    fn saturating_add_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
1029        crate::kernel!(
1030            #[inline(always)]
1031            fn kernel(token: Sse2, a: i8x16<Sse2>, b: i8x16<Sse2>) -> i8x16<Sse2> {
1032                _mm_adds_epi8(a.into(), b.into()).simd_into(token)
1033            }
1034        );
1035        kernel(self, a, b)
1036    }
1037    #[inline(always)]
1038    fn sub_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
1039        crate::kernel!(
1040            #[inline(always)]
1041            fn kernel(token: Sse2, a: i8x16<Sse2>, b: i8x16<Sse2>) -> i8x16<Sse2> {
1042                _mm_sub_epi8(a.into(), b.into()).simd_into(token)
1043            }
1044        );
1045        kernel(self, a, b)
1046    }
1047    #[inline(always)]
1048    fn saturating_sub_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
1049        crate::kernel!(
1050            #[inline(always)]
1051            fn kernel(token: Sse2, a: i8x16<Sse2>, b: i8x16<Sse2>) -> i8x16<Sse2> {
1052                _mm_subs_epi8(a.into(), b.into()).simd_into(token)
1053            }
1054        );
1055        kernel(self, a, b)
1056    }
1057    #[inline(always)]
1058    fn mul_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
1059        crate::kernel!(
1060            #[inline(always)]
1061            fn kernel(token: Sse2, a: i8x16<Sse2>, b: i8x16<Sse2>) -> i8x16<Sse2> {
1062                let dst_even = _mm_mullo_epi16(a.into(), b.into());
1063                let dst_odd =
1064                    _mm_mullo_epi16(_mm_srli_epi16::<8>(a.into()), _mm_srli_epi16::<8>(b.into()));
1065                _mm_or_si128(
1066                    _mm_slli_epi16(dst_odd, 8),
1067                    _mm_and_si128(dst_even, _mm_set1_epi16(0xFF)),
1068                )
1069                .simd_into(token)
1070            }
1071        );
1072        kernel(self, a, b)
1073    }
1074    #[inline(always)]
1075    fn and_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
1076        crate::kernel!(
1077            #[inline(always)]
1078            fn kernel(token: Sse2, a: i8x16<Sse2>, b: i8x16<Sse2>) -> i8x16<Sse2> {
1079                _mm_and_si128(a.into(), b.into()).simd_into(token)
1080            }
1081        );
1082        kernel(self, a, b)
1083    }
1084    #[inline(always)]
1085    fn or_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
1086        crate::kernel!(
1087            #[inline(always)]
1088            fn kernel(token: Sse2, a: i8x16<Sse2>, b: i8x16<Sse2>) -> i8x16<Sse2> {
1089                _mm_or_si128(a.into(), b.into()).simd_into(token)
1090            }
1091        );
1092        kernel(self, a, b)
1093    }
1094    #[inline(always)]
1095    fn xor_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
1096        crate::kernel!(
1097            #[inline(always)]
1098            fn kernel(token: Sse2, a: i8x16<Sse2>, b: i8x16<Sse2>) -> i8x16<Sse2> {
1099                _mm_xor_si128(a.into(), b.into()).simd_into(token)
1100            }
1101        );
1102        kernel(self, a, b)
1103    }
1104    #[inline(always)]
1105    fn not_i8x16(self, a: i8x16<Self>) -> i8x16<Self> {
1106        a ^ !0
1107    }
1108    #[inline(always)]
1109    fn shl_i8x16(self, a: i8x16<Self>, shift: u32) -> i8x16<Self> {
1110        crate::kernel!(
1111            #[inline(always)]
1112            fn kernel(token: Sse2, a: i8x16<Sse2>, shift: u32) -> i8x16<Sse2> {
1113                let val = a.into();
1114                let shift_count = _mm_cvtsi32_si128(shift.cast_signed());
1115                let mask_byte = 0xff_u32.wrapping_shr(shift) as i8;
1116                let byte_mask = _mm_set1_epi8(mask_byte);
1117                _mm_sll_epi16(_mm_and_si128(val, byte_mask), shift_count).simd_into(token)
1118            }
1119        );
1120        kernel(self, a, shift)
1121    }
1122    #[inline(always)]
1123    fn shlv_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
1124        [
1125            i8::wrapping_shl(a[0usize], b[0usize] as u32),
1126            i8::wrapping_shl(a[1usize], b[1usize] as u32),
1127            i8::wrapping_shl(a[2usize], b[2usize] as u32),
1128            i8::wrapping_shl(a[3usize], b[3usize] as u32),
1129            i8::wrapping_shl(a[4usize], b[4usize] as u32),
1130            i8::wrapping_shl(a[5usize], b[5usize] as u32),
1131            i8::wrapping_shl(a[6usize], b[6usize] as u32),
1132            i8::wrapping_shl(a[7usize], b[7usize] as u32),
1133            i8::wrapping_shl(a[8usize], b[8usize] as u32),
1134            i8::wrapping_shl(a[9usize], b[9usize] as u32),
1135            i8::wrapping_shl(a[10usize], b[10usize] as u32),
1136            i8::wrapping_shl(a[11usize], b[11usize] as u32),
1137            i8::wrapping_shl(a[12usize], b[12usize] as u32),
1138            i8::wrapping_shl(a[13usize], b[13usize] as u32),
1139            i8::wrapping_shl(a[14usize], b[14usize] as u32),
1140            i8::wrapping_shl(a[15usize], b[15usize] as u32),
1141        ]
1142        .simd_into(self)
1143    }
1144    #[inline(always)]
1145    fn shr_i8x16(self, a: i8x16<Self>, shift: u32) -> i8x16<Self> {
1146        crate::kernel!(
1147            #[inline(always)]
1148            fn kernel(token: Sse2, a: i8x16<Sse2>, shift: u32) -> i8x16<Sse2> {
1149                let val = a.into();
1150                let shift_count = _mm_cvtsi32_si128(shift.cast_signed());
1151                let mask_byte = 0xff_u32.wrapping_shr(shift) as i8;
1152                let byte_mask = _mm_set1_epi8(mask_byte);
1153                let shifted = _mm_srl_epi16(val, shift_count);
1154                let result = {
1155                    let sign = _mm_cmpgt_epi8(_mm_setzero_si128(), val);
1156                    _mm_or_si128(
1157                        _mm_and_si128(shifted, byte_mask),
1158                        _mm_andnot_si128(byte_mask, sign),
1159                    )
1160                };
1161                result.simd_into(token)
1162            }
1163        );
1164        kernel(self, a, shift)
1165    }
1166    #[inline(always)]
1167    fn shrv_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
1168        [
1169            i8::wrapping_shr(a[0usize], b[0usize] as u32),
1170            i8::wrapping_shr(a[1usize], b[1usize] as u32),
1171            i8::wrapping_shr(a[2usize], b[2usize] as u32),
1172            i8::wrapping_shr(a[3usize], b[3usize] as u32),
1173            i8::wrapping_shr(a[4usize], b[4usize] as u32),
1174            i8::wrapping_shr(a[5usize], b[5usize] as u32),
1175            i8::wrapping_shr(a[6usize], b[6usize] as u32),
1176            i8::wrapping_shr(a[7usize], b[7usize] as u32),
1177            i8::wrapping_shr(a[8usize], b[8usize] as u32),
1178            i8::wrapping_shr(a[9usize], b[9usize] as u32),
1179            i8::wrapping_shr(a[10usize], b[10usize] as u32),
1180            i8::wrapping_shr(a[11usize], b[11usize] as u32),
1181            i8::wrapping_shr(a[12usize], b[12usize] as u32),
1182            i8::wrapping_shr(a[13usize], b[13usize] as u32),
1183            i8::wrapping_shr(a[14usize], b[14usize] as u32),
1184            i8::wrapping_shr(a[15usize], b[15usize] as u32),
1185        ]
1186        .simd_into(self)
1187    }
1188    #[inline(always)]
1189    fn reduce_max_i8x16(self, a: i8x16<Self>) -> i8 {
1190        crate::kernel!(
1191            #[inline(always)]
1192            fn kernel(token: Sse2, a: i8x16<Sse2>) -> i8 {
1193                let reduced: __m128i = a.into();
1194                let shifted = _mm_srli_si128::<8>(reduced);
1195                let reduced = {
1196                    {
1197                        let a = reduced;
1198                        let b = shifted;
1199                        let gt = _mm_cmpgt_epi8(a, b);
1200                        _mm_or_si128(_mm_and_si128(gt, a), _mm_andnot_si128(gt, b))
1201                    }
1202                };
1203                let shifted = _mm_srli_si128::<4>(reduced);
1204                let reduced = {
1205                    {
1206                        let a = reduced;
1207                        let b = shifted;
1208                        let gt = _mm_cmpgt_epi8(a, b);
1209                        _mm_or_si128(_mm_and_si128(gt, a), _mm_andnot_si128(gt, b))
1210                    }
1211                };
1212                let shifted = _mm_srli_si128::<2>(reduced);
1213                let reduced = {
1214                    {
1215                        let a = reduced;
1216                        let b = shifted;
1217                        let gt = _mm_cmpgt_epi8(a, b);
1218                        _mm_or_si128(_mm_and_si128(gt, a), _mm_andnot_si128(gt, b))
1219                    }
1220                };
1221                let shifted = _mm_srli_si128::<1>(reduced);
1222                let reduced = {
1223                    {
1224                        let a = reduced;
1225                        let b = shifted;
1226                        let gt = _mm_cmpgt_epi8(a, b);
1227                        _mm_or_si128(_mm_and_si128(gt, a), _mm_andnot_si128(gt, b))
1228                    }
1229                };
1230                {
1231                    let lanes: [i8; 16usize] = crate::transmute::checked_transmute_copy(&reduced);
1232                    lanes[0]
1233                }
1234            }
1235        );
1236        kernel(self, a)
1237    }
1238    #[inline(always)]
1239    fn reduce_min_i8x16(self, a: i8x16<Self>) -> i8 {
1240        crate::kernel!(
1241            #[inline(always)]
1242            fn kernel(token: Sse2, a: i8x16<Sse2>) -> i8 {
1243                let reduced: __m128i = a.into();
1244                let shifted = _mm_srli_si128::<8>(reduced);
1245                let reduced = {
1246                    {
1247                        let a = reduced;
1248                        let b = shifted;
1249                        let gt = _mm_cmpgt_epi8(a, b);
1250                        _mm_or_si128(_mm_and_si128(gt, b), _mm_andnot_si128(gt, a))
1251                    }
1252                };
1253                let shifted = _mm_srli_si128::<4>(reduced);
1254                let reduced = {
1255                    {
1256                        let a = reduced;
1257                        let b = shifted;
1258                        let gt = _mm_cmpgt_epi8(a, b);
1259                        _mm_or_si128(_mm_and_si128(gt, b), _mm_andnot_si128(gt, a))
1260                    }
1261                };
1262                let shifted = _mm_srli_si128::<2>(reduced);
1263                let reduced = {
1264                    {
1265                        let a = reduced;
1266                        let b = shifted;
1267                        let gt = _mm_cmpgt_epi8(a, b);
1268                        _mm_or_si128(_mm_and_si128(gt, b), _mm_andnot_si128(gt, a))
1269                    }
1270                };
1271                let shifted = _mm_srli_si128::<1>(reduced);
1272                let reduced = {
1273                    {
1274                        let a = reduced;
1275                        let b = shifted;
1276                        let gt = _mm_cmpgt_epi8(a, b);
1277                        _mm_or_si128(_mm_and_si128(gt, b), _mm_andnot_si128(gt, a))
1278                    }
1279                };
1280                {
1281                    let lanes: [i8; 16usize] = crate::transmute::checked_transmute_copy(&reduced);
1282                    lanes[0]
1283                }
1284            }
1285        );
1286        kernel(self, a)
1287    }
1288    #[inline(always)]
1289    fn reduce_sum_i8x16(self, a: i8x16<Self>) -> i8 {
1290        crate::kernel!(
1291            #[inline(always)]
1292            fn kernel(token: Sse2, a: i8x16<Sse2>) -> i8 {
1293                let sum: __m128i = a.into();
1294                let sum = _mm_add_epi8(sum, _mm_srli_si128::<8>(sum));
1295                let sum = _mm_add_epi8(sum, _mm_srli_si128::<4>(sum));
1296                let sum = _mm_add_epi8(sum, _mm_srli_si128::<2>(sum));
1297                let sum = _mm_add_epi8(sum, _mm_srli_si128::<1>(sum));
1298                let lanes: [i8; 16usize] = crate::transmute::checked_transmute_copy(&sum);
1299                lanes[0]
1300            }
1301        );
1302        kernel(self, a)
1303    }
1304    #[inline(always)]
1305    fn reduce_product_i8x16(self, a: i8x16<Self>) -> i8 {
1306        crate::kernel!(
1307            #[inline(always)]
1308            fn kernel(token: Sse2, a: i8x16<Sse2>) -> i8 {
1309                let value: __m128i = a.into();
1310                let product = _mm_mullo_epi16(
1311                    _mm_unpacklo_epi8(value, value),
1312                    _mm_unpackhi_epi8(value, value),
1313                );
1314                let product = _mm_mullo_epi16(product, _mm_shuffle_epi32::<0b11_10_11_10>(product));
1315                let product = _mm_mullo_epi16(product, _mm_shuffle_epi32::<0b01_01_01_01>(product));
1316                let product = _mm_mullo_epi16(product, _mm_srli_epi32::<16>(product));
1317                let lanes: [i8; 16usize] = crate::transmute::checked_transmute_copy(&product);
1318                lanes[0]
1319            }
1320        );
1321        kernel(self, a)
1322    }
1323    #[inline(always)]
1324    fn max_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
1325        crate::kernel!(
1326            #[inline(always)]
1327            fn kernel(token: Sse2, a: i8x16<Sse2>, b: i8x16<Sse2>) -> i8x16<Sse2> {
1328                {
1329                    let a = a.into();
1330                    let b = b.into();
1331                    let gt = _mm_cmpgt_epi8(a, b);
1332                    _mm_or_si128(_mm_and_si128(gt, a), _mm_andnot_si128(gt, b))
1333                }
1334                .simd_into(token)
1335            }
1336        );
1337        kernel(self, a, b)
1338    }
1339    #[inline(always)]
1340    fn min_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
1341        crate::kernel!(
1342            #[inline(always)]
1343            fn kernel(token: Sse2, a: i8x16<Sse2>, b: i8x16<Sse2>) -> i8x16<Sse2> {
1344                {
1345                    let a = a.into();
1346                    let b = b.into();
1347                    let gt = _mm_cmpgt_epi8(a, b);
1348                    _mm_or_si128(_mm_and_si128(gt, b), _mm_andnot_si128(gt, a))
1349                }
1350                .simd_into(token)
1351            }
1352        );
1353        kernel(self, a, b)
1354    }
1355    #[inline(always)]
1356    fn clamp_i8x16(self, a: i8x16<Self>, b: i8x16<Self>, c: i8x16<Self>) -> i8x16<Self> {
1357        debug_assert!(
1358            b.simd_le(c).all_true(),
1359            "clamp requires min <= max for all elements"
1360        );
1361        a.max(b).min(c)
1362    }
1363    #[inline(always)]
1364    fn simd_eq_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> mask8x16<Self> {
1365        crate::kernel!(
1366            #[inline(always)]
1367            fn kernel(token: Sse2, a: i8x16<Sse2>, b: i8x16<Sse2>) -> mask8x16<Sse2> {
1368                _mm_cmpeq_epi8(a.into(), b.into()).simd_into(token)
1369            }
1370        );
1371        kernel(self, a, b)
1372    }
1373    #[inline(always)]
1374    fn simd_lt_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> mask8x16<Self> {
1375        crate::kernel!(
1376            #[inline(always)]
1377            fn kernel(token: Sse2, a: i8x16<Sse2>, b: i8x16<Sse2>) -> mask8x16<Sse2> {
1378                _mm_cmpgt_epi8(b.into(), a.into()).simd_into(token)
1379            }
1380        );
1381        kernel(self, a, b)
1382    }
1383    #[inline(always)]
1384    fn simd_le_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> mask8x16<Self> {
1385        crate::kernel!(
1386            #[inline(always)]
1387            fn kernel(token: Sse2, a: i8x16<Sse2>, b: i8x16<Sse2>) -> mask8x16<Sse2> {
1388                {
1389                    let all_ones = _mm_set1_epi8(-1);
1390                    _mm_xor_si128(_mm_cmpgt_epi8(a.into(), b.into()), all_ones)
1391                }
1392                .simd_into(token)
1393            }
1394        );
1395        kernel(self, a, b)
1396    }
1397    #[inline(always)]
1398    fn zip_low_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
1399        crate::kernel!(
1400            #[inline(always)]
1401            fn kernel(token: Sse2, a: i8x16<Sse2>, b: i8x16<Sse2>) -> i8x16<Sse2> {
1402                _mm_unpacklo_epi8(a.into(), b.into()).simd_into(token)
1403            }
1404        );
1405        kernel(self, a, b)
1406    }
1407    #[inline(always)]
1408    fn zip_high_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
1409        crate::kernel!(
1410            #[inline(always)]
1411            fn kernel(token: Sse2, a: i8x16<Sse2>, b: i8x16<Sse2>) -> i8x16<Sse2> {
1412                _mm_unpackhi_epi8(a.into(), b.into()).simd_into(token)
1413            }
1414        );
1415        kernel(self, a, b)
1416    }
1417    #[inline(always)]
1418    fn unzip_low_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
1419        [
1420            a[0usize], a[2usize], a[4usize], a[6usize], a[8usize], a[10usize], a[12usize],
1421            a[14usize], b[0usize], b[2usize], b[4usize], b[6usize], b[8usize], b[10usize],
1422            b[12usize], b[14usize],
1423        ]
1424        .simd_into(self)
1425    }
1426    #[inline(always)]
1427    fn unzip_high_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self> {
1428        [
1429            a[1usize], a[3usize], a[5usize], a[7usize], a[9usize], a[11usize], a[13usize],
1430            a[15usize], b[1usize], b[3usize], b[5usize], b[7usize], b[9usize], b[11usize],
1431            b[13usize], b[15usize],
1432        ]
1433        .simd_into(self)
1434    }
1435    #[inline(always)]
1436    fn interleave_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> (i8x16<Self>, i8x16<Self>) {
1437        (self.zip_low_i8x16(a, b), self.zip_high_i8x16(a, b))
1438    }
1439    #[inline(always)]
1440    fn deinterleave_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> (i8x16<Self>, i8x16<Self>) {
1441        (self.unzip_low_i8x16(a, b), self.unzip_high_i8x16(a, b))
1442    }
1443    #[inline(always)]
1444    fn select_i8x16(self, a: mask8x16<Self>, b: i8x16<Self>, c: i8x16<Self>) -> i8x16<Self> {
1445        crate::kernel!(
1446            #[inline(always)]
1447            fn kernel(
1448                token: Sse2,
1449                a: mask8x16<Sse2>,
1450                b: i8x16<Sse2>,
1451                c: i8x16<Sse2>,
1452            ) -> i8x16<Sse2> {
1453                _mm_or_si128(
1454                    _mm_and_si128(a.into(), b.into()),
1455                    _mm_andnot_si128(a.into(), c.into()),
1456                )
1457                .simd_into(token)
1458            }
1459        );
1460        kernel(self, a, b, c)
1461    }
1462    #[inline(always)]
1463    fn combine_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x32<Self> {
1464        i8x32 {
1465            val: crate::support::Aligned256([a.val.0, b.val.0]),
1466            simd: self,
1467        }
1468    }
1469    #[inline(always)]
1470    fn neg_i8x16(self, a: i8x16<Self>) -> i8x16<Self> {
1471        crate::kernel!(
1472            #[inline(always)]
1473            fn kernel(token: Sse2, a: i8x16<Sse2>) -> i8x16<Sse2> {
1474                _mm_sub_epi8(_mm_setzero_si128(), a.into()).simd_into(token)
1475            }
1476        );
1477        kernel(self, a)
1478    }
1479    #[inline(always)]
1480    fn load_four_interleaved_i8x16(self, src: &[i8; 64usize]) -> [i8x16<Self>; 4usize] {
1481        [
1482            [
1483                src[0usize],
1484                src[4usize],
1485                src[8usize],
1486                src[12usize],
1487                src[16usize],
1488                src[20usize],
1489                src[24usize],
1490                src[28usize],
1491                src[32usize],
1492                src[36usize],
1493                src[40usize],
1494                src[44usize],
1495                src[48usize],
1496                src[52usize],
1497                src[56usize],
1498                src[60usize],
1499            ]
1500            .simd_into(self),
1501            [
1502                src[1usize],
1503                src[5usize],
1504                src[9usize],
1505                src[13usize],
1506                src[17usize],
1507                src[21usize],
1508                src[25usize],
1509                src[29usize],
1510                src[33usize],
1511                src[37usize],
1512                src[41usize],
1513                src[45usize],
1514                src[49usize],
1515                src[53usize],
1516                src[57usize],
1517                src[61usize],
1518            ]
1519            .simd_into(self),
1520            [
1521                src[2usize],
1522                src[6usize],
1523                src[10usize],
1524                src[14usize],
1525                src[18usize],
1526                src[22usize],
1527                src[26usize],
1528                src[30usize],
1529                src[34usize],
1530                src[38usize],
1531                src[42usize],
1532                src[46usize],
1533                src[50usize],
1534                src[54usize],
1535                src[58usize],
1536                src[62usize],
1537            ]
1538            .simd_into(self),
1539            [
1540                src[3usize],
1541                src[7usize],
1542                src[11usize],
1543                src[15usize],
1544                src[19usize],
1545                src[23usize],
1546                src[27usize],
1547                src[31usize],
1548                src[35usize],
1549                src[39usize],
1550                src[43usize],
1551                src[47usize],
1552                src[51usize],
1553                src[55usize],
1554                src[59usize],
1555                src[63usize],
1556            ]
1557            .simd_into(self),
1558        ]
1559    }
1560    #[inline(always)]
1561    fn store_four_interleaved_i8x16(
1562        self,
1563        vectors: [i8x16<Self>; 4usize],
1564        dest: &mut [i8; 64usize],
1565    ) -> () {
1566        *dest = [
1567            vectors[0usize][0usize],
1568            vectors[1usize][0usize],
1569            vectors[2usize][0usize],
1570            vectors[3usize][0usize],
1571            vectors[0usize][1usize],
1572            vectors[1usize][1usize],
1573            vectors[2usize][1usize],
1574            vectors[3usize][1usize],
1575            vectors[0usize][2usize],
1576            vectors[1usize][2usize],
1577            vectors[2usize][2usize],
1578            vectors[3usize][2usize],
1579            vectors[0usize][3usize],
1580            vectors[1usize][3usize],
1581            vectors[2usize][3usize],
1582            vectors[3usize][3usize],
1583            vectors[0usize][4usize],
1584            vectors[1usize][4usize],
1585            vectors[2usize][4usize],
1586            vectors[3usize][4usize],
1587            vectors[0usize][5usize],
1588            vectors[1usize][5usize],
1589            vectors[2usize][5usize],
1590            vectors[3usize][5usize],
1591            vectors[0usize][6usize],
1592            vectors[1usize][6usize],
1593            vectors[2usize][6usize],
1594            vectors[3usize][6usize],
1595            vectors[0usize][7usize],
1596            vectors[1usize][7usize],
1597            vectors[2usize][7usize],
1598            vectors[3usize][7usize],
1599            vectors[0usize][8usize],
1600            vectors[1usize][8usize],
1601            vectors[2usize][8usize],
1602            vectors[3usize][8usize],
1603            vectors[0usize][9usize],
1604            vectors[1usize][9usize],
1605            vectors[2usize][9usize],
1606            vectors[3usize][9usize],
1607            vectors[0usize][10usize],
1608            vectors[1usize][10usize],
1609            vectors[2usize][10usize],
1610            vectors[3usize][10usize],
1611            vectors[0usize][11usize],
1612            vectors[1usize][11usize],
1613            vectors[2usize][11usize],
1614            vectors[3usize][11usize],
1615            vectors[0usize][12usize],
1616            vectors[1usize][12usize],
1617            vectors[2usize][12usize],
1618            vectors[3usize][12usize],
1619            vectors[0usize][13usize],
1620            vectors[1usize][13usize],
1621            vectors[2usize][13usize],
1622            vectors[3usize][13usize],
1623            vectors[0usize][14usize],
1624            vectors[1usize][14usize],
1625            vectors[2usize][14usize],
1626            vectors[3usize][14usize],
1627            vectors[0usize][15usize],
1628            vectors[1usize][15usize],
1629            vectors[2usize][15usize],
1630            vectors[3usize][15usize],
1631        ];
1632    }
1633    #[inline(always)]
1634    fn widen_i8x16(self, a: i8x16<Self>) -> (i16x8<Self>, i16x8<Self>) {
1635        crate::kernel!(
1636            #[inline(always)]
1637            fn kernel(token: Sse2, a: i8x16<Sse2>) -> (i16x8<Sse2>, i16x8<Sse2>) {
1638                let raw = a.into();
1639                let sign = _mm_cmpgt_epi8(_mm_setzero_si128(), raw);
1640                (
1641                    _mm_unpacklo_epi8(raw, sign).simd_into(token),
1642                    _mm_unpackhi_epi8(raw, sign).simd_into(token),
1643                )
1644            }
1645        );
1646        kernel(self, a)
1647    }
1648    #[inline(always)]
1649    fn widening_mul_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> (i16x8<Self>, i16x8<Self>) {
1650        let (a0, a1) = self.widen_i8x16(a);
1651        let (b0, b1) = self.widen_i8x16(b);
1652        (self.mul_i16x8(a0, b0), self.mul_i16x8(a1, b1))
1653    }
1654    #[inline(always)]
1655    fn widening_add_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> (i16x8<Self>, i16x8<Self>) {
1656        let (a0, a1) = self.widen_i8x16(a);
1657        let (b0, b1) = self.widen_i8x16(b);
1658        (self.add_i16x8(a0, b0), self.add_i16x8(a1, b1))
1659    }
1660    #[inline(always)]
1661    fn pairwise_widening_add_i8x16(self, a: i8x16<Self>) -> i16x8<Self> {
1662        [
1663            (a[0usize] as i16) + (a[1usize] as i16),
1664            (a[2usize] as i16) + (a[3usize] as i16),
1665            (a[4usize] as i16) + (a[5usize] as i16),
1666            (a[6usize] as i16) + (a[7usize] as i16),
1667            (a[8usize] as i16) + (a[9usize] as i16),
1668            (a[10usize] as i16) + (a[11usize] as i16),
1669            (a[12usize] as i16) + (a[13usize] as i16),
1670            (a[14usize] as i16) + (a[15usize] as i16),
1671        ]
1672        .simd_into(self)
1673    }
1674    #[inline(always)]
1675    fn pairwise_dot_product_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i16x8<Self> {
1676        let (low, high) = self.widening_mul_i8x16(a, b);
1677        let (even, odd) = self.deinterleave_i16x8(low, high);
1678        self.add_i16x8(even, odd)
1679    }
1680    #[inline(always)]
1681    fn splat_u8x16(self, val: u8) -> u8x16<Self> {
1682        crate::kernel!(
1683            #[inline(always)]
1684            fn kernel(token: Sse2, val: u8) -> u8x16<Sse2> {
1685                _mm_set1_epi8(val.cast_signed()).simd_into(token)
1686            }
1687        );
1688        kernel(self, val)
1689    }
1690    #[inline(always)]
1691    fn reverse_u8x16(self, a: u8x16<Self>) -> u8x16<Self> {
1692        [
1693            a[15usize], a[14usize], a[13usize], a[12usize], a[11usize], a[10usize], a[9usize],
1694            a[8usize], a[7usize], a[6usize], a[5usize], a[4usize], a[3usize], a[2usize], a[1usize],
1695            a[0usize],
1696        ]
1697        .simd_into(self)
1698    }
1699    #[inline(always)]
1700    fn slide_u8x16<const SHIFT: usize>(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
1701        if SHIFT >= 16usize {
1702            return b;
1703        }
1704        let result = dyn_alignr_128(
1705            self,
1706            Bytes::to_bytes(b).val.0,
1707            Bytes::to_bytes(a).val.0,
1708            SHIFT,
1709        );
1710        Bytes::from_bytes(u8x16 {
1711            val: crate::support::Aligned128(result),
1712            simd: self,
1713        })
1714    }
1715    #[inline(always)]
1716    fn swizzle_dyn_within_blocks_u8x16(self, a: u8x16<Self>, indices: u8x16<Self>) -> u8x16<Self> {
1717        let bytes = Bytes::to_bytes(a);
1718        let result: u8x16<Self> = [
1719            {
1720                let index = indices[0usize] as usize;
1721                bytes[index % 16usize]
1722            },
1723            {
1724                let index = indices[1usize] as usize;
1725                bytes[index % 16usize]
1726            },
1727            {
1728                let index = indices[2usize] as usize;
1729                bytes[index % 16usize]
1730            },
1731            {
1732                let index = indices[3usize] as usize;
1733                bytes[index % 16usize]
1734            },
1735            {
1736                let index = indices[4usize] as usize;
1737                bytes[index % 16usize]
1738            },
1739            {
1740                let index = indices[5usize] as usize;
1741                bytes[index % 16usize]
1742            },
1743            {
1744                let index = indices[6usize] as usize;
1745                bytes[index % 16usize]
1746            },
1747            {
1748                let index = indices[7usize] as usize;
1749                bytes[index % 16usize]
1750            },
1751            {
1752                let index = indices[8usize] as usize;
1753                bytes[index % 16usize]
1754            },
1755            {
1756                let index = indices[9usize] as usize;
1757                bytes[index % 16usize]
1758            },
1759            {
1760                let index = indices[10usize] as usize;
1761                bytes[index % 16usize]
1762            },
1763            {
1764                let index = indices[11usize] as usize;
1765                bytes[index % 16usize]
1766            },
1767            {
1768                let index = indices[12usize] as usize;
1769                bytes[index % 16usize]
1770            },
1771            {
1772                let index = indices[13usize] as usize;
1773                bytes[index % 16usize]
1774            },
1775            {
1776                let index = indices[14usize] as usize;
1777                bytes[index % 16usize]
1778            },
1779            {
1780                let index = indices[15usize] as usize;
1781                bytes[index % 16usize]
1782            },
1783        ]
1784        .simd_into(self);
1785        Bytes::from_bytes(result)
1786    }
1787    #[inline(always)]
1788    fn swizzle_dyn_u8x16(self, a: u8x16<Self>, indices: u8x16<Self>) -> u8x16<Self> {
1789        let bytes = Bytes::to_bytes(a);
1790        let mut output = [0u8; 16usize];
1791        for lane in 0..16usize {
1792            let index = indices[lane] as usize;
1793            output[lane] = bytes[index % 16usize];
1794        }
1795        let result: u8x16<Self> = output.simd_into(self);
1796        Bytes::from_bytes(result)
1797    }
1798    #[inline(always)]
1799    fn swizzle_dyn_precise_u8x16(self, a: u8x16<Self>, indices: u8x16<Self>) -> u8x16<Self> {
1800        let bytes = Bytes::to_bytes(a);
1801        let mut output = [0u8; 16usize];
1802        for lane in 0..16usize {
1803            let index = indices[lane] as usize;
1804            let value = bytes[index % 16usize];
1805            output[lane] = core::hint::select_unpredictable(index < 16usize, value, 0u8);
1806        }
1807        let result: u8x16<Self> = output.simd_into(self);
1808        Bytes::from_bytes(result)
1809    }
1810    #[inline(always)]
1811    fn concat_swizzle_dyn_u8x16(
1812        self,
1813        a: u8x16<Self>,
1814        b: u8x16<Self>,
1815        indices: u8x16<Self>,
1816    ) -> u8x16<Self> {
1817        let first_table = Bytes::to_bytes(a);
1818        let second_table = Bytes::to_bytes(b);
1819        let mut output = [0u8; 16usize];
1820        for lane in 0..16usize {
1821            let index = indices[lane] as usize % 32usize;
1822            output[lane] = if index < 16usize {
1823                first_table[index]
1824            } else {
1825                second_table[index - 16usize]
1826            };
1827        }
1828        let result: u8x16<Self> = output.simd_into(self);
1829        Bytes::from_bytes(result)
1830    }
1831    #[inline(always)]
1832    fn concat_swizzle_dyn_precise_u8x16(
1833        self,
1834        a: u8x16<Self>,
1835        b: u8x16<Self>,
1836        indices: u8x16<Self>,
1837    ) -> u8x16<Self> {
1838        let first_table = Bytes::to_bytes(a);
1839        let second_table = Bytes::to_bytes(b);
1840        let mut output = [0u8; 16usize];
1841        for lane in 0..16usize {
1842            let index = indices[lane] as usize;
1843            let table_index = index % 16usize;
1844            let value = if index < 16usize {
1845                first_table[table_index]
1846            } else {
1847                second_table[table_index]
1848            };
1849            output[lane] = if index < 32usize { value } else { 0 };
1850        }
1851        let result: u8x16<Self> = output.simd_into(self);
1852        Bytes::from_bytes(result)
1853    }
1854    #[inline(always)]
1855    fn compress_u8x16(self, values: u8x16<Self>, mask: mask8x16<Self>) -> u8x16<Self> {
1856        self.compress_merge_u8x16(values, mask, u8x16::splat(self, 0))
1857    }
1858    #[inline(always)]
1859    fn compress_merge_u8x16(
1860        self,
1861        values: u8x16<Self>,
1862        mask: mask8x16<Self>,
1863        merge: u8x16<Self>,
1864    ) -> u8x16<Self> {
1865        let mask = self.to_bitmask_mask8x16(mask);
1866        let mut merge_padded = [0u8; 16 + 1];
1867        merge_padded[..16].copy_from_slice(&*merge);
1868        let mut compacted = merge_padded;
1869        let mut output_lane = 0;
1870        for input_lane in 0..16 {
1871            compacted[output_lane] = values[input_lane];
1872            output_lane += ((mask >> input_lane) & 1) as usize;
1873        }
1874        compacted[output_lane] = merge_padded[output_lane];
1875        let mut result = merge;
1876        result.copy_from_slice(&compacted[..16]);
1877        result
1878    }
1879    #[inline(always)]
1880    fn expand_u8x16(self, values: u8x16<Self>, mask: mask8x16<Self>) -> u8x16<Self> {
1881        self.expand_merge_u8x16(values, mask, u8x16::splat(self, 0))
1882    }
1883    #[inline(always)]
1884    fn expand_merge_u8x16(
1885        self,
1886        values: u8x16<Self>,
1887        mask: mask8x16<Self>,
1888        merge: u8x16<Self>,
1889    ) -> u8x16<Self> {
1890        let mask = self.to_bitmask_mask8x16(mask);
1891        let mut result = merge;
1892        let mut input_lane = 0;
1893        for output_lane in 0..16 {
1894            let bit = ((mask >> output_lane) & 1) as u8;
1895            let keep = 0u8.wrapping_sub(bit);
1896            result[output_lane] = (values[input_lane] & keep) | (result[output_lane] & !keep);
1897            input_lane += usize::from(bit);
1898        }
1899        result
1900    }
1901    #[inline(always)]
1902    fn count_ones_u8x16(self, a: u8x16<Self>) -> u8x16<Self> {
1903        [
1904            u8::try_from(a[0usize].count_ones()).unwrap(),
1905            u8::try_from(a[1usize].count_ones()).unwrap(),
1906            u8::try_from(a[2usize].count_ones()).unwrap(),
1907            u8::try_from(a[3usize].count_ones()).unwrap(),
1908            u8::try_from(a[4usize].count_ones()).unwrap(),
1909            u8::try_from(a[5usize].count_ones()).unwrap(),
1910            u8::try_from(a[6usize].count_ones()).unwrap(),
1911            u8::try_from(a[7usize].count_ones()).unwrap(),
1912            u8::try_from(a[8usize].count_ones()).unwrap(),
1913            u8::try_from(a[9usize].count_ones()).unwrap(),
1914            u8::try_from(a[10usize].count_ones()).unwrap(),
1915            u8::try_from(a[11usize].count_ones()).unwrap(),
1916            u8::try_from(a[12usize].count_ones()).unwrap(),
1917            u8::try_from(a[13usize].count_ones()).unwrap(),
1918            u8::try_from(a[14usize].count_ones()).unwrap(),
1919            u8::try_from(a[15usize].count_ones()).unwrap(),
1920        ]
1921        .simd_into(self)
1922    }
1923    #[inline(always)]
1924    fn count_zeros_u8x16(self, a: u8x16<Self>) -> u8x16<Self> {
1925        [
1926            u8::try_from(a[0usize].count_zeros()).unwrap(),
1927            u8::try_from(a[1usize].count_zeros()).unwrap(),
1928            u8::try_from(a[2usize].count_zeros()).unwrap(),
1929            u8::try_from(a[3usize].count_zeros()).unwrap(),
1930            u8::try_from(a[4usize].count_zeros()).unwrap(),
1931            u8::try_from(a[5usize].count_zeros()).unwrap(),
1932            u8::try_from(a[6usize].count_zeros()).unwrap(),
1933            u8::try_from(a[7usize].count_zeros()).unwrap(),
1934            u8::try_from(a[8usize].count_zeros()).unwrap(),
1935            u8::try_from(a[9usize].count_zeros()).unwrap(),
1936            u8::try_from(a[10usize].count_zeros()).unwrap(),
1937            u8::try_from(a[11usize].count_zeros()).unwrap(),
1938            u8::try_from(a[12usize].count_zeros()).unwrap(),
1939            u8::try_from(a[13usize].count_zeros()).unwrap(),
1940            u8::try_from(a[14usize].count_zeros()).unwrap(),
1941            u8::try_from(a[15usize].count_zeros()).unwrap(),
1942        ]
1943        .simd_into(self)
1944    }
1945    #[inline(always)]
1946    fn add_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
1947        crate::kernel!(
1948            #[inline(always)]
1949            fn kernel(token: Sse2, a: u8x16<Sse2>, b: u8x16<Sse2>) -> u8x16<Sse2> {
1950                _mm_add_epi8(a.into(), b.into()).simd_into(token)
1951            }
1952        );
1953        kernel(self, a, b)
1954    }
1955    #[inline(always)]
1956    fn saturating_add_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
1957        crate::kernel!(
1958            #[inline(always)]
1959            fn kernel(token: Sse2, a: u8x16<Sse2>, b: u8x16<Sse2>) -> u8x16<Sse2> {
1960                _mm_adds_epu8(a.into(), b.into()).simd_into(token)
1961            }
1962        );
1963        kernel(self, a, b)
1964    }
1965    #[inline(always)]
1966    fn sub_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
1967        crate::kernel!(
1968            #[inline(always)]
1969            fn kernel(token: Sse2, a: u8x16<Sse2>, b: u8x16<Sse2>) -> u8x16<Sse2> {
1970                _mm_sub_epi8(a.into(), b.into()).simd_into(token)
1971            }
1972        );
1973        kernel(self, a, b)
1974    }
1975    #[inline(always)]
1976    fn saturating_sub_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
1977        crate::kernel!(
1978            #[inline(always)]
1979            fn kernel(token: Sse2, a: u8x16<Sse2>, b: u8x16<Sse2>) -> u8x16<Sse2> {
1980                _mm_subs_epu8(a.into(), b.into()).simd_into(token)
1981            }
1982        );
1983        kernel(self, a, b)
1984    }
1985    #[inline(always)]
1986    fn mul_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
1987        crate::kernel!(
1988            #[inline(always)]
1989            fn kernel(token: Sse2, a: u8x16<Sse2>, b: u8x16<Sse2>) -> u8x16<Sse2> {
1990                let dst_even = _mm_mullo_epi16(a.into(), b.into());
1991                let dst_odd =
1992                    _mm_mullo_epi16(_mm_srli_epi16::<8>(a.into()), _mm_srli_epi16::<8>(b.into()));
1993                _mm_or_si128(
1994                    _mm_slli_epi16(dst_odd, 8),
1995                    _mm_and_si128(dst_even, _mm_set1_epi16(0xFF)),
1996                )
1997                .simd_into(token)
1998            }
1999        );
2000        kernel(self, a, b)
2001    }
2002    #[inline(always)]
2003    fn and_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
2004        crate::kernel!(
2005            #[inline(always)]
2006            fn kernel(token: Sse2, a: u8x16<Sse2>, b: u8x16<Sse2>) -> u8x16<Sse2> {
2007                _mm_and_si128(a.into(), b.into()).simd_into(token)
2008            }
2009        );
2010        kernel(self, a, b)
2011    }
2012    #[inline(always)]
2013    fn or_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
2014        crate::kernel!(
2015            #[inline(always)]
2016            fn kernel(token: Sse2, a: u8x16<Sse2>, b: u8x16<Sse2>) -> u8x16<Sse2> {
2017                _mm_or_si128(a.into(), b.into()).simd_into(token)
2018            }
2019        );
2020        kernel(self, a, b)
2021    }
2022    #[inline(always)]
2023    fn xor_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
2024        crate::kernel!(
2025            #[inline(always)]
2026            fn kernel(token: Sse2, a: u8x16<Sse2>, b: u8x16<Sse2>) -> u8x16<Sse2> {
2027                _mm_xor_si128(a.into(), b.into()).simd_into(token)
2028            }
2029        );
2030        kernel(self, a, b)
2031    }
2032    #[inline(always)]
2033    fn not_u8x16(self, a: u8x16<Self>) -> u8x16<Self> {
2034        a ^ !0
2035    }
2036    #[inline(always)]
2037    fn shl_u8x16(self, a: u8x16<Self>, shift: u32) -> u8x16<Self> {
2038        crate::kernel!(
2039            #[inline(always)]
2040            fn kernel(token: Sse2, a: u8x16<Sse2>, shift: u32) -> u8x16<Sse2> {
2041                let val = a.into();
2042                let shift_count = _mm_cvtsi32_si128(shift.cast_signed());
2043                let mask_byte = 0xff_u32.wrapping_shr(shift) as i8;
2044                let byte_mask = _mm_set1_epi8(mask_byte);
2045                _mm_sll_epi16(_mm_and_si128(val, byte_mask), shift_count).simd_into(token)
2046            }
2047        );
2048        kernel(self, a, shift)
2049    }
2050    #[inline(always)]
2051    fn shlv_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
2052        [
2053            u8::wrapping_shl(a[0usize], b[0usize] as u32),
2054            u8::wrapping_shl(a[1usize], b[1usize] as u32),
2055            u8::wrapping_shl(a[2usize], b[2usize] as u32),
2056            u8::wrapping_shl(a[3usize], b[3usize] as u32),
2057            u8::wrapping_shl(a[4usize], b[4usize] as u32),
2058            u8::wrapping_shl(a[5usize], b[5usize] as u32),
2059            u8::wrapping_shl(a[6usize], b[6usize] as u32),
2060            u8::wrapping_shl(a[7usize], b[7usize] as u32),
2061            u8::wrapping_shl(a[8usize], b[8usize] as u32),
2062            u8::wrapping_shl(a[9usize], b[9usize] as u32),
2063            u8::wrapping_shl(a[10usize], b[10usize] as u32),
2064            u8::wrapping_shl(a[11usize], b[11usize] as u32),
2065            u8::wrapping_shl(a[12usize], b[12usize] as u32),
2066            u8::wrapping_shl(a[13usize], b[13usize] as u32),
2067            u8::wrapping_shl(a[14usize], b[14usize] as u32),
2068            u8::wrapping_shl(a[15usize], b[15usize] as u32),
2069        ]
2070        .simd_into(self)
2071    }
2072    #[inline(always)]
2073    fn shr_u8x16(self, a: u8x16<Self>, shift: u32) -> u8x16<Self> {
2074        crate::kernel!(
2075            #[inline(always)]
2076            fn kernel(token: Sse2, a: u8x16<Sse2>, shift: u32) -> u8x16<Sse2> {
2077                let val = a.into();
2078                let shift_count = _mm_cvtsi32_si128(shift.cast_signed());
2079                let mask_byte = 0xff_u32.wrapping_shr(shift) as i8;
2080                let byte_mask = _mm_set1_epi8(mask_byte);
2081                let shifted = _mm_srl_epi16(val, shift_count);
2082                let result = { _mm_and_si128(shifted, byte_mask) };
2083                result.simd_into(token)
2084            }
2085        );
2086        kernel(self, a, shift)
2087    }
2088    #[inline(always)]
2089    fn shrv_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
2090        [
2091            u8::wrapping_shr(a[0usize], b[0usize] as u32),
2092            u8::wrapping_shr(a[1usize], b[1usize] as u32),
2093            u8::wrapping_shr(a[2usize], b[2usize] as u32),
2094            u8::wrapping_shr(a[3usize], b[3usize] as u32),
2095            u8::wrapping_shr(a[4usize], b[4usize] as u32),
2096            u8::wrapping_shr(a[5usize], b[5usize] as u32),
2097            u8::wrapping_shr(a[6usize], b[6usize] as u32),
2098            u8::wrapping_shr(a[7usize], b[7usize] as u32),
2099            u8::wrapping_shr(a[8usize], b[8usize] as u32),
2100            u8::wrapping_shr(a[9usize], b[9usize] as u32),
2101            u8::wrapping_shr(a[10usize], b[10usize] as u32),
2102            u8::wrapping_shr(a[11usize], b[11usize] as u32),
2103            u8::wrapping_shr(a[12usize], b[12usize] as u32),
2104            u8::wrapping_shr(a[13usize], b[13usize] as u32),
2105            u8::wrapping_shr(a[14usize], b[14usize] as u32),
2106            u8::wrapping_shr(a[15usize], b[15usize] as u32),
2107        ]
2108        .simd_into(self)
2109    }
2110    #[inline(always)]
2111    fn reduce_max_u8x16(self, a: u8x16<Self>) -> u8 {
2112        crate::kernel!(
2113            #[inline(always)]
2114            fn kernel(token: Sse2, a: u8x16<Sse2>) -> u8 {
2115                let reduced: __m128i = a.into();
2116                let shifted = _mm_srli_si128::<8>(reduced);
2117                let reduced = { _mm_max_epu8(reduced, shifted) };
2118                let shifted = _mm_srli_si128::<4>(reduced);
2119                let reduced = { _mm_max_epu8(reduced, shifted) };
2120                let shifted = _mm_srli_si128::<2>(reduced);
2121                let reduced = { _mm_max_epu8(reduced, shifted) };
2122                let shifted = _mm_srli_si128::<1>(reduced);
2123                let reduced = { _mm_max_epu8(reduced, shifted) };
2124                {
2125                    let lanes: [u8; 16usize] = crate::transmute::checked_transmute_copy(&reduced);
2126                    lanes[0]
2127                }
2128            }
2129        );
2130        kernel(self, a)
2131    }
2132    #[inline(always)]
2133    fn reduce_min_u8x16(self, a: u8x16<Self>) -> u8 {
2134        crate::kernel!(
2135            #[inline(always)]
2136            fn kernel(token: Sse2, a: u8x16<Sse2>) -> u8 {
2137                let reduced: __m128i = a.into();
2138                let shifted = _mm_srli_si128::<8>(reduced);
2139                let reduced = { _mm_min_epu8(reduced, shifted) };
2140                let shifted = _mm_srli_si128::<4>(reduced);
2141                let reduced = { _mm_min_epu8(reduced, shifted) };
2142                let shifted = _mm_srli_si128::<2>(reduced);
2143                let reduced = { _mm_min_epu8(reduced, shifted) };
2144                let shifted = _mm_srli_si128::<1>(reduced);
2145                let reduced = { _mm_min_epu8(reduced, shifted) };
2146                {
2147                    let lanes: [u8; 16usize] = crate::transmute::checked_transmute_copy(&reduced);
2148                    lanes[0]
2149                }
2150            }
2151        );
2152        kernel(self, a)
2153    }
2154    #[inline(always)]
2155    fn reduce_sum_u8x16(self, a: u8x16<Self>) -> u8 {
2156        crate::kernel!(
2157            #[inline(always)]
2158            fn kernel(token: Sse2, a: u8x16<Sse2>) -> u8 {
2159                let sum: __m128i = a.into();
2160                let sum = _mm_add_epi8(sum, _mm_srli_si128::<8>(sum));
2161                let sum = _mm_add_epi8(sum, _mm_srli_si128::<4>(sum));
2162                let sum = _mm_add_epi8(sum, _mm_srli_si128::<2>(sum));
2163                let sum = _mm_add_epi8(sum, _mm_srli_si128::<1>(sum));
2164                let lanes: [u8; 16usize] = crate::transmute::checked_transmute_copy(&sum);
2165                lanes[0]
2166            }
2167        );
2168        kernel(self, a)
2169    }
2170    #[inline(always)]
2171    fn reduce_product_u8x16(self, a: u8x16<Self>) -> u8 {
2172        crate::kernel!(
2173            #[inline(always)]
2174            fn kernel(token: Sse2, a: u8x16<Sse2>) -> u8 {
2175                let value: __m128i = a.into();
2176                let product = _mm_mullo_epi16(
2177                    _mm_unpacklo_epi8(value, value),
2178                    _mm_unpackhi_epi8(value, value),
2179                );
2180                let product = _mm_mullo_epi16(product, _mm_shuffle_epi32::<0b11_10_11_10>(product));
2181                let product = _mm_mullo_epi16(product, _mm_shuffle_epi32::<0b01_01_01_01>(product));
2182                let product = _mm_mullo_epi16(product, _mm_srli_epi32::<16>(product));
2183                let lanes: [u8; 16usize] = crate::transmute::checked_transmute_copy(&product);
2184                lanes[0]
2185            }
2186        );
2187        kernel(self, a)
2188    }
2189    #[inline(always)]
2190    fn max_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
2191        crate::kernel!(
2192            #[inline(always)]
2193            fn kernel(token: Sse2, a: u8x16<Sse2>, b: u8x16<Sse2>) -> u8x16<Sse2> {
2194                _mm_max_epu8(a.into(), b.into()).simd_into(token)
2195            }
2196        );
2197        kernel(self, a, b)
2198    }
2199    #[inline(always)]
2200    fn min_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
2201        crate::kernel!(
2202            #[inline(always)]
2203            fn kernel(token: Sse2, a: u8x16<Sse2>, b: u8x16<Sse2>) -> u8x16<Sse2> {
2204                _mm_min_epu8(a.into(), b.into()).simd_into(token)
2205            }
2206        );
2207        kernel(self, a, b)
2208    }
2209    #[inline(always)]
2210    fn clamp_u8x16(self, a: u8x16<Self>, b: u8x16<Self>, c: u8x16<Self>) -> u8x16<Self> {
2211        debug_assert!(
2212            b.simd_le(c).all_true(),
2213            "clamp requires min <= max for all elements"
2214        );
2215        a.max(b).min(c)
2216    }
2217    #[inline(always)]
2218    fn simd_eq_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> mask8x16<Self> {
2219        crate::kernel!(
2220            #[inline(always)]
2221            fn kernel(token: Sse2, a: u8x16<Sse2>, b: u8x16<Sse2>) -> mask8x16<Sse2> {
2222                _mm_cmpeq_epi8(a.into(), b.into()).simd_into(token)
2223            }
2224        );
2225        kernel(self, a, b)
2226    }
2227    #[inline(always)]
2228    fn simd_lt_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> mask8x16<Self> {
2229        crate::kernel!(
2230            #[inline(always)]
2231            fn kernel(token: Sse2, a: u8x16<Sse2>, b: u8x16<Sse2>) -> mask8x16<Sse2> {
2232                {
2233                    let sign_bit = _mm_set1_epi8(0x80u8.cast_signed());
2234                    let lhs_signed = _mm_xor_si128(b.into(), sign_bit);
2235                    let rhs_signed = _mm_xor_si128(a.into(), sign_bit);
2236                    _mm_cmpgt_epi8(lhs_signed, rhs_signed)
2237                }
2238                .simd_into(token)
2239            }
2240        );
2241        kernel(self, a, b)
2242    }
2243    #[inline(always)]
2244    fn simd_le_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> mask8x16<Self> {
2245        crate::kernel!(
2246            #[inline(always)]
2247            fn kernel(token: Sse2, a: u8x16<Sse2>, b: u8x16<Sse2>) -> mask8x16<Sse2> {
2248                {
2249                    let all_ones = _mm_set1_epi8(-1);
2250                    _mm_xor_si128(
2251                        {
2252                            let sign_bit = _mm_set1_epi8(0x80u8.cast_signed());
2253                            let lhs_signed = _mm_xor_si128(a.into(), sign_bit);
2254                            let rhs_signed = _mm_xor_si128(b.into(), sign_bit);
2255                            _mm_cmpgt_epi8(lhs_signed, rhs_signed)
2256                        },
2257                        all_ones,
2258                    )
2259                }
2260                .simd_into(token)
2261            }
2262        );
2263        kernel(self, a, b)
2264    }
2265    #[inline(always)]
2266    fn zip_low_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
2267        crate::kernel!(
2268            #[inline(always)]
2269            fn kernel(token: Sse2, a: u8x16<Sse2>, b: u8x16<Sse2>) -> u8x16<Sse2> {
2270                _mm_unpacklo_epi8(a.into(), b.into()).simd_into(token)
2271            }
2272        );
2273        kernel(self, a, b)
2274    }
2275    #[inline(always)]
2276    fn zip_high_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
2277        crate::kernel!(
2278            #[inline(always)]
2279            fn kernel(token: Sse2, a: u8x16<Sse2>, b: u8x16<Sse2>) -> u8x16<Sse2> {
2280                _mm_unpackhi_epi8(a.into(), b.into()).simd_into(token)
2281            }
2282        );
2283        kernel(self, a, b)
2284    }
2285    #[inline(always)]
2286    fn unzip_low_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
2287        [
2288            a[0usize], a[2usize], a[4usize], a[6usize], a[8usize], a[10usize], a[12usize],
2289            a[14usize], b[0usize], b[2usize], b[4usize], b[6usize], b[8usize], b[10usize],
2290            b[12usize], b[14usize],
2291        ]
2292        .simd_into(self)
2293    }
2294    #[inline(always)]
2295    fn unzip_high_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self> {
2296        [
2297            a[1usize], a[3usize], a[5usize], a[7usize], a[9usize], a[11usize], a[13usize],
2298            a[15usize], b[1usize], b[3usize], b[5usize], b[7usize], b[9usize], b[11usize],
2299            b[13usize], b[15usize],
2300        ]
2301        .simd_into(self)
2302    }
2303    #[inline(always)]
2304    fn interleave_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> (u8x16<Self>, u8x16<Self>) {
2305        (self.zip_low_u8x16(a, b), self.zip_high_u8x16(a, b))
2306    }
2307    #[inline(always)]
2308    fn deinterleave_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> (u8x16<Self>, u8x16<Self>) {
2309        (self.unzip_low_u8x16(a, b), self.unzip_high_u8x16(a, b))
2310    }
2311    #[inline(always)]
2312    fn select_u8x16(self, a: mask8x16<Self>, b: u8x16<Self>, c: u8x16<Self>) -> u8x16<Self> {
2313        crate::kernel!(
2314            #[inline(always)]
2315            fn kernel(
2316                token: Sse2,
2317                a: mask8x16<Sse2>,
2318                b: u8x16<Sse2>,
2319                c: u8x16<Sse2>,
2320            ) -> u8x16<Sse2> {
2321                _mm_or_si128(
2322                    _mm_and_si128(a.into(), b.into()),
2323                    _mm_andnot_si128(a.into(), c.into()),
2324                )
2325                .simd_into(token)
2326            }
2327        );
2328        kernel(self, a, b, c)
2329    }
2330    #[inline(always)]
2331    fn combine_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x32<Self> {
2332        u8x32 {
2333            val: crate::support::Aligned256([a.val.0, b.val.0]),
2334            simd: self,
2335        }
2336    }
2337    #[inline(always)]
2338    fn load_four_interleaved_u8x16(self, src: &[u8; 64usize]) -> [u8x16<Self>; 4usize] {
2339        [
2340            [
2341                src[0usize],
2342                src[4usize],
2343                src[8usize],
2344                src[12usize],
2345                src[16usize],
2346                src[20usize],
2347                src[24usize],
2348                src[28usize],
2349                src[32usize],
2350                src[36usize],
2351                src[40usize],
2352                src[44usize],
2353                src[48usize],
2354                src[52usize],
2355                src[56usize],
2356                src[60usize],
2357            ]
2358            .simd_into(self),
2359            [
2360                src[1usize],
2361                src[5usize],
2362                src[9usize],
2363                src[13usize],
2364                src[17usize],
2365                src[21usize],
2366                src[25usize],
2367                src[29usize],
2368                src[33usize],
2369                src[37usize],
2370                src[41usize],
2371                src[45usize],
2372                src[49usize],
2373                src[53usize],
2374                src[57usize],
2375                src[61usize],
2376            ]
2377            .simd_into(self),
2378            [
2379                src[2usize],
2380                src[6usize],
2381                src[10usize],
2382                src[14usize],
2383                src[18usize],
2384                src[22usize],
2385                src[26usize],
2386                src[30usize],
2387                src[34usize],
2388                src[38usize],
2389                src[42usize],
2390                src[46usize],
2391                src[50usize],
2392                src[54usize],
2393                src[58usize],
2394                src[62usize],
2395            ]
2396            .simd_into(self),
2397            [
2398                src[3usize],
2399                src[7usize],
2400                src[11usize],
2401                src[15usize],
2402                src[19usize],
2403                src[23usize],
2404                src[27usize],
2405                src[31usize],
2406                src[35usize],
2407                src[39usize],
2408                src[43usize],
2409                src[47usize],
2410                src[51usize],
2411                src[55usize],
2412                src[59usize],
2413                src[63usize],
2414            ]
2415            .simd_into(self),
2416        ]
2417    }
2418    #[inline(always)]
2419    fn store_four_interleaved_u8x16(
2420        self,
2421        vectors: [u8x16<Self>; 4usize],
2422        dest: &mut [u8; 64usize],
2423    ) -> () {
2424        *dest = [
2425            vectors[0usize][0usize],
2426            vectors[1usize][0usize],
2427            vectors[2usize][0usize],
2428            vectors[3usize][0usize],
2429            vectors[0usize][1usize],
2430            vectors[1usize][1usize],
2431            vectors[2usize][1usize],
2432            vectors[3usize][1usize],
2433            vectors[0usize][2usize],
2434            vectors[1usize][2usize],
2435            vectors[2usize][2usize],
2436            vectors[3usize][2usize],
2437            vectors[0usize][3usize],
2438            vectors[1usize][3usize],
2439            vectors[2usize][3usize],
2440            vectors[3usize][3usize],
2441            vectors[0usize][4usize],
2442            vectors[1usize][4usize],
2443            vectors[2usize][4usize],
2444            vectors[3usize][4usize],
2445            vectors[0usize][5usize],
2446            vectors[1usize][5usize],
2447            vectors[2usize][5usize],
2448            vectors[3usize][5usize],
2449            vectors[0usize][6usize],
2450            vectors[1usize][6usize],
2451            vectors[2usize][6usize],
2452            vectors[3usize][6usize],
2453            vectors[0usize][7usize],
2454            vectors[1usize][7usize],
2455            vectors[2usize][7usize],
2456            vectors[3usize][7usize],
2457            vectors[0usize][8usize],
2458            vectors[1usize][8usize],
2459            vectors[2usize][8usize],
2460            vectors[3usize][8usize],
2461            vectors[0usize][9usize],
2462            vectors[1usize][9usize],
2463            vectors[2usize][9usize],
2464            vectors[3usize][9usize],
2465            vectors[0usize][10usize],
2466            vectors[1usize][10usize],
2467            vectors[2usize][10usize],
2468            vectors[3usize][10usize],
2469            vectors[0usize][11usize],
2470            vectors[1usize][11usize],
2471            vectors[2usize][11usize],
2472            vectors[3usize][11usize],
2473            vectors[0usize][12usize],
2474            vectors[1usize][12usize],
2475            vectors[2usize][12usize],
2476            vectors[3usize][12usize],
2477            vectors[0usize][13usize],
2478            vectors[1usize][13usize],
2479            vectors[2usize][13usize],
2480            vectors[3usize][13usize],
2481            vectors[0usize][14usize],
2482            vectors[1usize][14usize],
2483            vectors[2usize][14usize],
2484            vectors[3usize][14usize],
2485            vectors[0usize][15usize],
2486            vectors[1usize][15usize],
2487            vectors[2usize][15usize],
2488            vectors[3usize][15usize],
2489        ];
2490    }
2491    #[inline(always)]
2492    fn widen_u8x16(self, a: u8x16<Self>) -> (u16x8<Self>, u16x8<Self>) {
2493        crate::kernel!(
2494            #[inline(always)]
2495            fn kernel(token: Sse2, a: u8x16<Sse2>) -> (u16x8<Sse2>, u16x8<Sse2>) {
2496                let raw = a.into();
2497                let sign = _mm_setzero_si128();
2498                (
2499                    _mm_unpacklo_epi8(raw, sign).simd_into(token),
2500                    _mm_unpackhi_epi8(raw, sign).simd_into(token),
2501                )
2502            }
2503        );
2504        kernel(self, a)
2505    }
2506    #[inline(always)]
2507    fn widening_mul_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> (u16x8<Self>, u16x8<Self>) {
2508        let (a0, a1) = self.widen_u8x16(a);
2509        let (b0, b1) = self.widen_u8x16(b);
2510        (self.mul_u16x8(a0, b0), self.mul_u16x8(a1, b1))
2511    }
2512    #[inline(always)]
2513    fn widening_add_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> (u16x8<Self>, u16x8<Self>) {
2514        let (a0, a1) = self.widen_u8x16(a);
2515        let (b0, b1) = self.widen_u8x16(b);
2516        (self.add_u16x8(a0, b0), self.add_u16x8(a1, b1))
2517    }
2518    #[inline(always)]
2519    fn pairwise_widening_add_u8x16(self, a: u8x16<Self>) -> u16x8<Self> {
2520        [
2521            (a[0usize] as u16) + (a[1usize] as u16),
2522            (a[2usize] as u16) + (a[3usize] as u16),
2523            (a[4usize] as u16) + (a[5usize] as u16),
2524            (a[6usize] as u16) + (a[7usize] as u16),
2525            (a[8usize] as u16) + (a[9usize] as u16),
2526            (a[10usize] as u16) + (a[11usize] as u16),
2527            (a[12usize] as u16) + (a[13usize] as u16),
2528            (a[14usize] as u16) + (a[15usize] as u16),
2529        ]
2530        .simd_into(self)
2531    }
2532    #[inline(always)]
2533    fn pairwise_dot_product_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u16x8<Self> {
2534        let (low, high) = self.widening_mul_u8x16(a, b);
2535        let (even, odd) = self.deinterleave_u16x8(low, high);
2536        self.add_u16x8(even, odd)
2537    }
2538    #[inline(always)]
2539    fn splat_mask8x16(self, val: bool) -> mask8x16<Self> {
2540        crate::kernel!(
2541            #[inline(always)]
2542            fn kernel(token: Sse2, val: bool) -> mask8x16<Sse2> {
2543                let val: i8 = if val { !0 } else { 0 };
2544                _mm_set1_epi8(val).simd_into(token)
2545            }
2546        );
2547        kernel(self, val)
2548    }
2549    #[inline(always)]
2550    fn from_bitmask_mask8x16(self, bits: u64) -> mask8x16<Self> {
2551        let lanes: [i8; 16usize] = [
2552            if bits & 1 != 0 { !0 } else { 0 },
2553            if (bits >> 1usize) & 1 != 0 { !0 } else { 0 },
2554            if (bits >> 2usize) & 1 != 0 { !0 } else { 0 },
2555            if (bits >> 3usize) & 1 != 0 { !0 } else { 0 },
2556            if (bits >> 4usize) & 1 != 0 { !0 } else { 0 },
2557            if (bits >> 5usize) & 1 != 0 { !0 } else { 0 },
2558            if (bits >> 6usize) & 1 != 0 { !0 } else { 0 },
2559            if (bits >> 7usize) & 1 != 0 { !0 } else { 0 },
2560            if (bits >> 8usize) & 1 != 0 { !0 } else { 0 },
2561            if (bits >> 9usize) & 1 != 0 { !0 } else { 0 },
2562            if (bits >> 10usize) & 1 != 0 { !0 } else { 0 },
2563            if (bits >> 11usize) & 1 != 0 { !0 } else { 0 },
2564            if (bits >> 12usize) & 1 != 0 { !0 } else { 0 },
2565            if (bits >> 13usize) & 1 != 0 { !0 } else { 0 },
2566            if (bits >> 14usize) & 1 != 0 { !0 } else { 0 },
2567            if (bits >> 15usize) & 1 != 0 { !0 } else { 0 },
2568        ];
2569        lanes.simd_into(self)
2570    }
2571    #[inline(always)]
2572    fn to_bitmask_mask8x16(self, a: mask8x16<Self>) -> u64 {
2573        crate::kernel!(
2574            #[inline(always)]
2575            fn kernel(token: Sse2, a: mask8x16<Sse2>) -> u64 {
2576                _mm_movemask_epi8(a.into()) as u32 as u64
2577            }
2578        );
2579        kernel(self, a)
2580    }
2581    #[inline(always)]
2582    fn from_vector_mask8x16(self, vector: i8x16<Self>) -> mask8x16<Self> {
2583        mask8x16 {
2584            val: vector.val,
2585            simd: self,
2586        }
2587    }
2588    #[inline(always)]
2589    fn to_vector_mask8x16(self, a: mask8x16<Self>) -> i8x16<Self> {
2590        i8x16 {
2591            val: a.val,
2592            simd: self,
2593        }
2594    }
2595    #[inline(always)]
2596    fn set_mask8x16(self, a: &mut mask8x16<Self>, index: usize, value: bool) -> () {
2597        assert!(
2598            index < 16usize,
2599            "mask lane index {index} is out of bounds for {} lanes",
2600            16usize
2601        );
2602        let mut lanes: [i8; 16usize] = (*a).into();
2603        lanes[index] = if value { !0 } else { 0 };
2604        *a = lanes.simd_into(self);
2605    }
2606    #[inline(always)]
2607    fn rotate_elements_left_mask8x16<const OFFSET: usize>(
2608        self,
2609        a: mask8x16<Self>,
2610    ) -> mask8x16<Self> {
2611        let int = i8x16 {
2612            val: crate::transmute::checked_transmute_copy(&a.val),
2613            simd: self,
2614        };
2615        let rotated = int.rotate_elements_left::<OFFSET>();
2616        mask8x16 {
2617            val: crate::transmute::checked_transmute_copy(&rotated.val),
2618            simd: self,
2619        }
2620    }
2621    #[inline(always)]
2622    fn rotate_elements_right_mask8x16<const OFFSET: usize>(
2623        self,
2624        a: mask8x16<Self>,
2625    ) -> mask8x16<Self> {
2626        let int = i8x16 {
2627            val: crate::transmute::checked_transmute_copy(&a.val),
2628            simd: self,
2629        };
2630        let rotated = int.rotate_elements_right::<OFFSET>();
2631        mask8x16 {
2632            val: crate::transmute::checked_transmute_copy(&rotated.val),
2633            simd: self,
2634        }
2635    }
2636    #[inline(always)]
2637    fn and_mask8x16(self, a: mask8x16<Self>, b: mask8x16<Self>) -> mask8x16<Self> {
2638        crate::kernel!(
2639            #[inline(always)]
2640            fn kernel(token: Sse2, a: mask8x16<Sse2>, b: mask8x16<Sse2>) -> mask8x16<Sse2> {
2641                _mm_and_si128(a.into(), b.into()).simd_into(token)
2642            }
2643        );
2644        kernel(self, a, b)
2645    }
2646    #[inline(always)]
2647    fn or_mask8x16(self, a: mask8x16<Self>, b: mask8x16<Self>) -> mask8x16<Self> {
2648        crate::kernel!(
2649            #[inline(always)]
2650            fn kernel(token: Sse2, a: mask8x16<Sse2>, b: mask8x16<Sse2>) -> mask8x16<Sse2> {
2651                _mm_or_si128(a.into(), b.into()).simd_into(token)
2652            }
2653        );
2654        kernel(self, a, b)
2655    }
2656    #[inline(always)]
2657    fn xor_mask8x16(self, a: mask8x16<Self>, b: mask8x16<Self>) -> mask8x16<Self> {
2658        crate::kernel!(
2659            #[inline(always)]
2660            fn kernel(token: Sse2, a: mask8x16<Sse2>, b: mask8x16<Sse2>) -> mask8x16<Sse2> {
2661                _mm_xor_si128(a.into(), b.into()).simd_into(token)
2662            }
2663        );
2664        kernel(self, a, b)
2665    }
2666    #[inline(always)]
2667    fn not_mask8x16(self, a: mask8x16<Self>) -> mask8x16<Self> {
2668        self.xor_mask8x16(a, self.splat_mask8x16(true))
2669    }
2670    #[inline(always)]
2671    fn reverse_mask8x16(self, a: mask8x16<Self>) -> mask8x16<Self> {
2672        let lanes = i8x16 {
2673            val: crate::transmute::checked_transmute_copy(&a.val),
2674            simd: self,
2675        };
2676        let reversed = self.reverse_i8x16(lanes);
2677        mask8x16 {
2678            val: crate::transmute::checked_transmute_copy(&reversed.val),
2679            simd: self,
2680        }
2681    }
2682    #[inline(always)]
2683    fn select_mask8x16(
2684        self,
2685        a: mask8x16<Self>,
2686        b: mask8x16<Self>,
2687        c: mask8x16<Self>,
2688    ) -> mask8x16<Self> {
2689        crate::kernel!(
2690            #[inline(always)]
2691            fn kernel(
2692                token: Sse2,
2693                a: mask8x16<Sse2>,
2694                b: mask8x16<Sse2>,
2695                c: mask8x16<Sse2>,
2696            ) -> mask8x16<Sse2> {
2697                _mm_or_si128(
2698                    _mm_and_si128(a.into(), b.into()),
2699                    _mm_andnot_si128(a.into(), c.into()),
2700                )
2701                .simd_into(token)
2702            }
2703        );
2704        kernel(self, a, b, c)
2705    }
2706    #[inline(always)]
2707    fn simd_eq_mask8x16(self, a: mask8x16<Self>, b: mask8x16<Self>) -> mask8x16<Self> {
2708        crate::kernel!(
2709            #[inline(always)]
2710            fn kernel(token: Sse2, a: mask8x16<Sse2>, b: mask8x16<Sse2>) -> mask8x16<Sse2> {
2711                _mm_cmpeq_epi8(a.into(), b.into()).simd_into(token)
2712            }
2713        );
2714        kernel(self, a, b)
2715    }
2716    #[inline(always)]
2717    fn any_true_mask8x16(self, a: mask8x16<Self>) -> bool {
2718        crate::kernel!(
2719            #[inline(always)]
2720            fn kernel(token: Sse2, a: mask8x16<Sse2>) -> bool {
2721                _mm_movemask_epi8(a.into()) as u32 != 0
2722            }
2723        );
2724        kernel(self, a)
2725    }
2726    #[inline(always)]
2727    fn all_true_mask8x16(self, a: mask8x16<Self>) -> bool {
2728        crate::kernel!(
2729            #[inline(always)]
2730            fn kernel(token: Sse2, a: mask8x16<Sse2>) -> bool {
2731                _mm_movemask_epi8(a.into()) as u32 == 0xffff
2732            }
2733        );
2734        kernel(self, a)
2735    }
2736    #[inline(always)]
2737    fn any_false_mask8x16(self, a: mask8x16<Self>) -> bool {
2738        crate::kernel!(
2739            #[inline(always)]
2740            fn kernel(token: Sse2, a: mask8x16<Sse2>) -> bool {
2741                _mm_movemask_epi8(a.into()) as u32 != 0xffff
2742            }
2743        );
2744        kernel(self, a)
2745    }
2746    #[inline(always)]
2747    fn all_false_mask8x16(self, a: mask8x16<Self>) -> bool {
2748        crate::kernel!(
2749            #[inline(always)]
2750            fn kernel(token: Sse2, a: mask8x16<Sse2>) -> bool {
2751                _mm_movemask_epi8(a.into()) as u32 == 0
2752            }
2753        );
2754        kernel(self, a)
2755    }
2756    #[inline(always)]
2757    fn combine_mask8x16(self, a: mask8x16<Self>, b: mask8x16<Self>) -> mask8x32<Self> {
2758        mask8x32 {
2759            val: crate::support::Aligned256([a.val.0, b.val.0]),
2760            simd: self,
2761        }
2762    }
2763    #[inline(always)]
2764    fn widen_mask8x16(self, a: mask8x16<Self>) -> (mask16x8<Self>, mask16x8<Self>) {
2765        crate::kernel!(
2766            #[inline(always)]
2767            fn kernel(token: Sse2, a: mask8x16<Sse2>) -> (mask16x8<Sse2>, mask16x8<Sse2>) {
2768                let raw = a.into();
2769                (
2770                    _mm_unpacklo_epi8(raw, raw).simd_into(token),
2771                    _mm_unpackhi_epi8(raw, raw).simd_into(token),
2772                )
2773            }
2774        );
2775        kernel(self, a)
2776    }
2777    #[inline(always)]
2778    fn abs_i16x8(self, a: i16x8<Self>) -> i16x8<Self> {
2779        [
2780            i16::wrapping_abs(a[0usize]),
2781            i16::wrapping_abs(a[1usize]),
2782            i16::wrapping_abs(a[2usize]),
2783            i16::wrapping_abs(a[3usize]),
2784            i16::wrapping_abs(a[4usize]),
2785            i16::wrapping_abs(a[5usize]),
2786            i16::wrapping_abs(a[6usize]),
2787            i16::wrapping_abs(a[7usize]),
2788        ]
2789        .simd_into(self)
2790    }
2791    #[inline(always)]
2792    fn splat_i16x8(self, val: i16) -> i16x8<Self> {
2793        crate::kernel!(
2794            #[inline(always)]
2795            fn kernel(token: Sse2, val: i16) -> i16x8<Sse2> {
2796                _mm_set1_epi16(val).simd_into(token)
2797            }
2798        );
2799        kernel(self, val)
2800    }
2801    #[inline(always)]
2802    fn reverse_i16x8(self, a: i16x8<Self>) -> i16x8<Self> {
2803        [
2804            a[7usize], a[6usize], a[5usize], a[4usize], a[3usize], a[2usize], a[1usize], a[0usize],
2805        ]
2806        .simd_into(self)
2807    }
2808    #[inline(always)]
2809    fn slide_i16x8<const SHIFT: usize>(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
2810        if SHIFT >= 8usize {
2811            return b;
2812        }
2813        let result = dyn_alignr_128(
2814            self,
2815            Bytes::to_bytes(b).val.0,
2816            Bytes::to_bytes(a).val.0,
2817            SHIFT * 2usize,
2818        );
2819        Bytes::from_bytes(u8x16 {
2820            val: crate::support::Aligned128(result),
2821            simd: self,
2822        })
2823    }
2824    #[inline(always)]
2825    fn compress_i16x8(self, values: i16x8<Self>, mask: mask16x8<Self>) -> i16x8<Self> {
2826        let mask = mask8x16 {
2827            val: crate::transmute::checked_transmute_copy(&mask.val),
2828            simd: self,
2829        };
2830        Bytes::from_bytes(self.compress_u8x16(Bytes::to_bytes(values), mask))
2831    }
2832    #[inline(always)]
2833    fn compress_merge_i16x8(
2834        self,
2835        values: i16x8<Self>,
2836        mask: mask16x8<Self>,
2837        merge: i16x8<Self>,
2838    ) -> i16x8<Self> {
2839        let mask = mask8x16 {
2840            val: crate::transmute::checked_transmute_copy(&mask.val),
2841            simd: self,
2842        };
2843        Bytes::from_bytes(self.compress_merge_u8x16(
2844            Bytes::to_bytes(values),
2845            mask,
2846            Bytes::to_bytes(merge),
2847        ))
2848    }
2849    #[inline(always)]
2850    fn expand_i16x8(self, values: i16x8<Self>, mask: mask16x8<Self>) -> i16x8<Self> {
2851        let mask = mask8x16 {
2852            val: crate::transmute::checked_transmute_copy(&mask.val),
2853            simd: self,
2854        };
2855        Bytes::from_bytes(self.expand_u8x16(Bytes::to_bytes(values), mask))
2856    }
2857    #[inline(always)]
2858    fn expand_merge_i16x8(
2859        self,
2860        values: i16x8<Self>,
2861        mask: mask16x8<Self>,
2862        merge: i16x8<Self>,
2863    ) -> i16x8<Self> {
2864        let mask = mask8x16 {
2865            val: crate::transmute::checked_transmute_copy(&mask.val),
2866            simd: self,
2867        };
2868        Bytes::from_bytes(self.expand_merge_u8x16(
2869            Bytes::to_bytes(values),
2870            mask,
2871            Bytes::to_bytes(merge),
2872        ))
2873    }
2874    #[inline(always)]
2875    fn count_ones_i16x8(self, a: i16x8<Self>) -> i16x8<Self> {
2876        [
2877            i16::try_from(a[0usize].count_ones()).unwrap(),
2878            i16::try_from(a[1usize].count_ones()).unwrap(),
2879            i16::try_from(a[2usize].count_ones()).unwrap(),
2880            i16::try_from(a[3usize].count_ones()).unwrap(),
2881            i16::try_from(a[4usize].count_ones()).unwrap(),
2882            i16::try_from(a[5usize].count_ones()).unwrap(),
2883            i16::try_from(a[6usize].count_ones()).unwrap(),
2884            i16::try_from(a[7usize].count_ones()).unwrap(),
2885        ]
2886        .simd_into(self)
2887    }
2888    #[inline(always)]
2889    fn count_zeros_i16x8(self, a: i16x8<Self>) -> i16x8<Self> {
2890        [
2891            i16::try_from(a[0usize].count_zeros()).unwrap(),
2892            i16::try_from(a[1usize].count_zeros()).unwrap(),
2893            i16::try_from(a[2usize].count_zeros()).unwrap(),
2894            i16::try_from(a[3usize].count_zeros()).unwrap(),
2895            i16::try_from(a[4usize].count_zeros()).unwrap(),
2896            i16::try_from(a[5usize].count_zeros()).unwrap(),
2897            i16::try_from(a[6usize].count_zeros()).unwrap(),
2898            i16::try_from(a[7usize].count_zeros()).unwrap(),
2899        ]
2900        .simd_into(self)
2901    }
2902    #[inline(always)]
2903    fn add_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
2904        crate::kernel!(
2905            #[inline(always)]
2906            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> i16x8<Sse2> {
2907                _mm_add_epi16(a.into(), b.into()).simd_into(token)
2908            }
2909        );
2910        kernel(self, a, b)
2911    }
2912    #[inline(always)]
2913    fn saturating_add_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
2914        crate::kernel!(
2915            #[inline(always)]
2916            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> i16x8<Sse2> {
2917                _mm_adds_epi16(a.into(), b.into()).simd_into(token)
2918            }
2919        );
2920        kernel(self, a, b)
2921    }
2922    #[inline(always)]
2923    fn sub_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
2924        crate::kernel!(
2925            #[inline(always)]
2926            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> i16x8<Sse2> {
2927                _mm_sub_epi16(a.into(), b.into()).simd_into(token)
2928            }
2929        );
2930        kernel(self, a, b)
2931    }
2932    #[inline(always)]
2933    fn saturating_sub_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
2934        crate::kernel!(
2935            #[inline(always)]
2936            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> i16x8<Sse2> {
2937                _mm_subs_epi16(a.into(), b.into()).simd_into(token)
2938            }
2939        );
2940        kernel(self, a, b)
2941    }
2942    #[inline(always)]
2943    fn mul_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
2944        crate::kernel!(
2945            #[inline(always)]
2946            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> i16x8<Sse2> {
2947                _mm_mullo_epi16(a.into(), b.into()).simd_into(token)
2948            }
2949        );
2950        kernel(self, a, b)
2951    }
2952    #[inline(always)]
2953    fn and_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
2954        crate::kernel!(
2955            #[inline(always)]
2956            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> i16x8<Sse2> {
2957                _mm_and_si128(a.into(), b.into()).simd_into(token)
2958            }
2959        );
2960        kernel(self, a, b)
2961    }
2962    #[inline(always)]
2963    fn or_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
2964        crate::kernel!(
2965            #[inline(always)]
2966            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> i16x8<Sse2> {
2967                _mm_or_si128(a.into(), b.into()).simd_into(token)
2968            }
2969        );
2970        kernel(self, a, b)
2971    }
2972    #[inline(always)]
2973    fn xor_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
2974        crate::kernel!(
2975            #[inline(always)]
2976            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> i16x8<Sse2> {
2977                _mm_xor_si128(a.into(), b.into()).simd_into(token)
2978            }
2979        );
2980        kernel(self, a, b)
2981    }
2982    #[inline(always)]
2983    fn not_i16x8(self, a: i16x8<Self>) -> i16x8<Self> {
2984        a ^ !0
2985    }
2986    #[inline(always)]
2987    fn shl_i16x8(self, a: i16x8<Self>, shift: u32) -> i16x8<Self> {
2988        crate::kernel!(
2989            #[inline(always)]
2990            fn kernel(token: Sse2, a: i16x8<Sse2>, shift: u32) -> i16x8<Sse2> {
2991                _mm_sll_epi16(a.into(), _mm_cvtsi32_si128(shift.cast_signed())).simd_into(token)
2992            }
2993        );
2994        kernel(self, a, shift)
2995    }
2996    #[inline(always)]
2997    fn shlv_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
2998        [
2999            i16::wrapping_shl(a[0usize], b[0usize] as u32),
3000            i16::wrapping_shl(a[1usize], b[1usize] as u32),
3001            i16::wrapping_shl(a[2usize], b[2usize] as u32),
3002            i16::wrapping_shl(a[3usize], b[3usize] as u32),
3003            i16::wrapping_shl(a[4usize], b[4usize] as u32),
3004            i16::wrapping_shl(a[5usize], b[5usize] as u32),
3005            i16::wrapping_shl(a[6usize], b[6usize] as u32),
3006            i16::wrapping_shl(a[7usize], b[7usize] as u32),
3007        ]
3008        .simd_into(self)
3009    }
3010    #[inline(always)]
3011    fn shr_i16x8(self, a: i16x8<Self>, shift: u32) -> i16x8<Self> {
3012        crate::kernel!(
3013            #[inline(always)]
3014            fn kernel(token: Sse2, a: i16x8<Sse2>, shift: u32) -> i16x8<Sse2> {
3015                _mm_sra_epi16(a.into(), _mm_cvtsi32_si128(shift.cast_signed())).simd_into(token)
3016            }
3017        );
3018        kernel(self, a, shift)
3019    }
3020    #[inline(always)]
3021    fn shrv_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
3022        [
3023            i16::wrapping_shr(a[0usize], b[0usize] as u32),
3024            i16::wrapping_shr(a[1usize], b[1usize] as u32),
3025            i16::wrapping_shr(a[2usize], b[2usize] as u32),
3026            i16::wrapping_shr(a[3usize], b[3usize] as u32),
3027            i16::wrapping_shr(a[4usize], b[4usize] as u32),
3028            i16::wrapping_shr(a[5usize], b[5usize] as u32),
3029            i16::wrapping_shr(a[6usize], b[6usize] as u32),
3030            i16::wrapping_shr(a[7usize], b[7usize] as u32),
3031        ]
3032        .simd_into(self)
3033    }
3034    #[inline(always)]
3035    fn reduce_max_i16x8(self, a: i16x8<Self>) -> i16 {
3036        crate::kernel!(
3037            #[inline(always)]
3038            fn kernel(token: Sse2, a: i16x8<Sse2>) -> i16 {
3039                let reduced: __m128i = a.into();
3040                let shifted = _mm_srli_si128::<8>(reduced);
3041                let reduced = { _mm_max_epi16(reduced, shifted) };
3042                let shifted = _mm_srli_si128::<4>(reduced);
3043                let reduced = { _mm_max_epi16(reduced, shifted) };
3044                let shifted = _mm_srli_si128::<2>(reduced);
3045                let reduced = { _mm_max_epi16(reduced, shifted) };
3046                {
3047                    let lanes: [i16; 8usize] = crate::transmute::checked_transmute_copy(&reduced);
3048                    lanes[0]
3049                }
3050            }
3051        );
3052        kernel(self, a)
3053    }
3054    #[inline(always)]
3055    fn reduce_min_i16x8(self, a: i16x8<Self>) -> i16 {
3056        crate::kernel!(
3057            #[inline(always)]
3058            fn kernel(token: Sse2, a: i16x8<Sse2>) -> i16 {
3059                let reduced: __m128i = a.into();
3060                let shifted = _mm_srli_si128::<8>(reduced);
3061                let reduced = { _mm_min_epi16(reduced, shifted) };
3062                let shifted = _mm_srli_si128::<4>(reduced);
3063                let reduced = { _mm_min_epi16(reduced, shifted) };
3064                let shifted = _mm_srli_si128::<2>(reduced);
3065                let reduced = { _mm_min_epi16(reduced, shifted) };
3066                {
3067                    let lanes: [i16; 8usize] = crate::transmute::checked_transmute_copy(&reduced);
3068                    lanes[0]
3069                }
3070            }
3071        );
3072        kernel(self, a)
3073    }
3074    #[inline(always)]
3075    fn reduce_sum_i16x8(self, a: i16x8<Self>) -> i16 {
3076        crate::kernel!(
3077            #[inline(always)]
3078            fn kernel(token: Sse2, a: i16x8<Sse2>) -> i16 {
3079                let sum: __m128i = a.into();
3080                let sum = _mm_add_epi16(sum, _mm_srli_si128::<8>(sum));
3081                let sum = _mm_add_epi16(sum, _mm_srli_si128::<4>(sum));
3082                let sum = _mm_add_epi16(sum, _mm_srli_si128::<2>(sum));
3083                let lanes: [i16; 8usize] = crate::transmute::checked_transmute_copy(&sum);
3084                lanes[0]
3085            }
3086        );
3087        kernel(self, a)
3088    }
3089    #[inline(always)]
3090    fn reduce_product_i16x8(self, a: i16x8<Self>) -> i16 {
3091        crate::kernel!(
3092            #[inline(always)]
3093            fn kernel(token: Sse2, a: i16x8<Sse2>) -> i16 {
3094                let product: __m128i = a.into();
3095                let product = _mm_mullo_epi16(product, _mm_shuffle_epi32::<0b11_10_11_10>(product));
3096                let product = _mm_mullo_epi16(product, _mm_shuffle_epi32::<0b01_01_01_01>(product));
3097                let product = _mm_mullo_epi16(product, _mm_srli_epi32::<16>(product));
3098                let lanes: [i16; 8usize] = crate::transmute::checked_transmute_copy(&product);
3099                lanes[0]
3100            }
3101        );
3102        kernel(self, a)
3103    }
3104    #[inline(always)]
3105    fn max_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
3106        crate::kernel!(
3107            #[inline(always)]
3108            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> i16x8<Sse2> {
3109                _mm_max_epi16(a.into(), b.into()).simd_into(token)
3110            }
3111        );
3112        kernel(self, a, b)
3113    }
3114    #[inline(always)]
3115    fn min_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
3116        crate::kernel!(
3117            #[inline(always)]
3118            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> i16x8<Sse2> {
3119                _mm_min_epi16(a.into(), b.into()).simd_into(token)
3120            }
3121        );
3122        kernel(self, a, b)
3123    }
3124    #[inline(always)]
3125    fn clamp_i16x8(self, a: i16x8<Self>, b: i16x8<Self>, c: i16x8<Self>) -> i16x8<Self> {
3126        debug_assert!(
3127            b.simd_le(c).all_true(),
3128            "clamp requires min <= max for all elements"
3129        );
3130        a.max(b).min(c)
3131    }
3132    #[inline(always)]
3133    fn simd_eq_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> mask16x8<Self> {
3134        crate::kernel!(
3135            #[inline(always)]
3136            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> mask16x8<Sse2> {
3137                _mm_cmpeq_epi16(a.into(), b.into()).simd_into(token)
3138            }
3139        );
3140        kernel(self, a, b)
3141    }
3142    #[inline(always)]
3143    fn simd_lt_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> mask16x8<Self> {
3144        crate::kernel!(
3145            #[inline(always)]
3146            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> mask16x8<Sse2> {
3147                _mm_cmpgt_epi16(b.into(), a.into()).simd_into(token)
3148            }
3149        );
3150        kernel(self, a, b)
3151    }
3152    #[inline(always)]
3153    fn simd_le_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> mask16x8<Self> {
3154        crate::kernel!(
3155            #[inline(always)]
3156            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> mask16x8<Sse2> {
3157                {
3158                    let all_ones = _mm_set1_epi8(-1);
3159                    _mm_xor_si128(_mm_cmpgt_epi16(a.into(), b.into()), all_ones)
3160                }
3161                .simd_into(token)
3162            }
3163        );
3164        kernel(self, a, b)
3165    }
3166    #[inline(always)]
3167    fn zip_low_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
3168        crate::kernel!(
3169            #[inline(always)]
3170            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> i16x8<Sse2> {
3171                _mm_unpacklo_epi16(a.into(), b.into()).simd_into(token)
3172            }
3173        );
3174        kernel(self, a, b)
3175    }
3176    #[inline(always)]
3177    fn zip_high_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
3178        crate::kernel!(
3179            #[inline(always)]
3180            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> i16x8<Sse2> {
3181                _mm_unpackhi_epi16(a.into(), b.into()).simd_into(token)
3182            }
3183        );
3184        kernel(self, a, b)
3185    }
3186    #[inline(always)]
3187    fn unzip_low_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
3188        [
3189            a[0usize], a[2usize], a[4usize], a[6usize], b[0usize], b[2usize], b[4usize], b[6usize],
3190        ]
3191        .simd_into(self)
3192    }
3193    #[inline(always)]
3194    fn unzip_high_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self> {
3195        [
3196            a[1usize], a[3usize], a[5usize], a[7usize], b[1usize], b[3usize], b[5usize], b[7usize],
3197        ]
3198        .simd_into(self)
3199    }
3200    #[inline(always)]
3201    fn interleave_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> (i16x8<Self>, i16x8<Self>) {
3202        (self.zip_low_i16x8(a, b), self.zip_high_i16x8(a, b))
3203    }
3204    #[inline(always)]
3205    fn deinterleave_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> (i16x8<Self>, i16x8<Self>) {
3206        (self.unzip_low_i16x8(a, b), self.unzip_high_i16x8(a, b))
3207    }
3208    #[inline(always)]
3209    fn select_i16x8(self, a: mask16x8<Self>, b: i16x8<Self>, c: i16x8<Self>) -> i16x8<Self> {
3210        crate::kernel!(
3211            #[inline(always)]
3212            fn kernel(
3213                token: Sse2,
3214                a: mask16x8<Sse2>,
3215                b: i16x8<Sse2>,
3216                c: i16x8<Sse2>,
3217            ) -> i16x8<Sse2> {
3218                _mm_or_si128(
3219                    _mm_and_si128(a.into(), b.into()),
3220                    _mm_andnot_si128(a.into(), c.into()),
3221                )
3222                .simd_into(token)
3223            }
3224        );
3225        kernel(self, a, b, c)
3226    }
3227    #[inline(always)]
3228    fn combine_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x16<Self> {
3229        i16x16 {
3230            val: crate::support::Aligned256([a.val.0, b.val.0]),
3231            simd: self,
3232        }
3233    }
3234    #[inline(always)]
3235    fn neg_i16x8(self, a: i16x8<Self>) -> i16x8<Self> {
3236        crate::kernel!(
3237            #[inline(always)]
3238            fn kernel(token: Sse2, a: i16x8<Sse2>) -> i16x8<Sse2> {
3239                _mm_sub_epi16(_mm_setzero_si128(), a.into()).simd_into(token)
3240            }
3241        );
3242        kernel(self, a)
3243    }
3244    #[inline(always)]
3245    fn load_four_interleaved_i16x8(self, src: &[i16; 32usize]) -> [i16x8<Self>; 4usize] {
3246        [
3247            [
3248                src[0usize],
3249                src[4usize],
3250                src[8usize],
3251                src[12usize],
3252                src[16usize],
3253                src[20usize],
3254                src[24usize],
3255                src[28usize],
3256            ]
3257            .simd_into(self),
3258            [
3259                src[1usize],
3260                src[5usize],
3261                src[9usize],
3262                src[13usize],
3263                src[17usize],
3264                src[21usize],
3265                src[25usize],
3266                src[29usize],
3267            ]
3268            .simd_into(self),
3269            [
3270                src[2usize],
3271                src[6usize],
3272                src[10usize],
3273                src[14usize],
3274                src[18usize],
3275                src[22usize],
3276                src[26usize],
3277                src[30usize],
3278            ]
3279            .simd_into(self),
3280            [
3281                src[3usize],
3282                src[7usize],
3283                src[11usize],
3284                src[15usize],
3285                src[19usize],
3286                src[23usize],
3287                src[27usize],
3288                src[31usize],
3289            ]
3290            .simd_into(self),
3291        ]
3292    }
3293    #[inline(always)]
3294    fn store_four_interleaved_i16x8(
3295        self,
3296        vectors: [i16x8<Self>; 4usize],
3297        dest: &mut [i16; 32usize],
3298    ) -> () {
3299        *dest = [
3300            vectors[0usize][0usize],
3301            vectors[1usize][0usize],
3302            vectors[2usize][0usize],
3303            vectors[3usize][0usize],
3304            vectors[0usize][1usize],
3305            vectors[1usize][1usize],
3306            vectors[2usize][1usize],
3307            vectors[3usize][1usize],
3308            vectors[0usize][2usize],
3309            vectors[1usize][2usize],
3310            vectors[2usize][2usize],
3311            vectors[3usize][2usize],
3312            vectors[0usize][3usize],
3313            vectors[1usize][3usize],
3314            vectors[2usize][3usize],
3315            vectors[3usize][3usize],
3316            vectors[0usize][4usize],
3317            vectors[1usize][4usize],
3318            vectors[2usize][4usize],
3319            vectors[3usize][4usize],
3320            vectors[0usize][5usize],
3321            vectors[1usize][5usize],
3322            vectors[2usize][5usize],
3323            vectors[3usize][5usize],
3324            vectors[0usize][6usize],
3325            vectors[1usize][6usize],
3326            vectors[2usize][6usize],
3327            vectors[3usize][6usize],
3328            vectors[0usize][7usize],
3329            vectors[1usize][7usize],
3330            vectors[2usize][7usize],
3331            vectors[3usize][7usize],
3332        ];
3333    }
3334    #[inline(always)]
3335    fn widen_i16x8(self, a: i16x8<Self>) -> (i32x4<Self>, i32x4<Self>) {
3336        crate::kernel!(
3337            #[inline(always)]
3338            fn kernel(token: Sse2, a: i16x8<Sse2>) -> (i32x4<Sse2>, i32x4<Sse2>) {
3339                let raw = a.into();
3340                let sign = _mm_srai_epi16::<15>(raw);
3341                (
3342                    _mm_unpacklo_epi16(raw, sign).simd_into(token),
3343                    _mm_unpackhi_epi16(raw, sign).simd_into(token),
3344                )
3345            }
3346        );
3347        kernel(self, a)
3348    }
3349    #[inline(always)]
3350    fn widening_mul_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> (i32x4<Self>, i32x4<Self>) {
3351        crate::kernel!(
3352            #[inline(always)]
3353            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> (i32x4<Sse2>, i32x4<Sse2>) {
3354                let a = a.into();
3355                let b = b.into();
3356                let low = _mm_mullo_epi16(a, b);
3357                let high = _mm_mulhi_epi16(a, b);
3358                let result_low = _mm_unpacklo_epi16(low, high);
3359                let result_high = _mm_unpackhi_epi16(low, high);
3360                (result_low.simd_into(token), result_high.simd_into(token))
3361            }
3362        );
3363        kernel(self, a, b)
3364    }
3365    #[inline(always)]
3366    fn widening_add_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> (i32x4<Self>, i32x4<Self>) {
3367        let (a0, a1) = self.widen_i16x8(a);
3368        let (b0, b1) = self.widen_i16x8(b);
3369        (self.add_i32x4(a0, b0), self.add_i32x4(a1, b1))
3370    }
3371    #[inline(always)]
3372    fn pairwise_widening_add_i16x8(self, a: i16x8<Self>) -> i32x4<Self> {
3373        crate::kernel!(
3374            #[inline(always)]
3375            fn kernel(token: Sse2, a: i16x8<Sse2>) -> i32x4<Sse2> {
3376                ({ _mm_madd_epi16(a.into(), _mm_set1_epi16(1)) }).simd_into(token)
3377            }
3378        );
3379        kernel(self, a)
3380    }
3381    #[inline(always)]
3382    fn pairwise_dot_product_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i32x4<Self> {
3383        crate::kernel!(
3384            #[inline(always)]
3385            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> i32x4<Sse2> {
3386                _mm_madd_epi16(a.into(), b.into()).simd_into(token)
3387            }
3388        );
3389        kernel(self, a, b)
3390    }
3391    #[inline(always)]
3392    fn narrow_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i8x16<Self> {
3393        crate::kernel!(
3394            #[inline(always)]
3395            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> i8x16<Sse2> {
3396                let mask = _mm_set1_epi16(0xff);
3397                _mm_packus_epi16(_mm_and_si128(a.into(), mask), _mm_and_si128(b.into(), mask))
3398                    .simd_into(token)
3399            }
3400        );
3401        kernel(self, a, b)
3402    }
3403    #[inline(always)]
3404    fn saturating_narrow_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i8x16<Self> {
3405        crate::kernel!(
3406            #[inline(always)]
3407            fn kernel(token: Sse2, a: i16x8<Sse2>, b: i16x8<Sse2>) -> i8x16<Sse2> {
3408                _mm_packs_epi16(a.into(), b.into()).simd_into(token)
3409            }
3410        );
3411        kernel(self, a, b)
3412    }
3413    #[inline(always)]
3414    fn relaxed_narrow_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i8x16<Self> {
3415        debug_assert!(
3416            a.as_slice()
3417                .iter()
3418                .chain(b.as_slice())
3419                .all(|&value| { value >= i8::MIN as i16 && value <= i8::MAX as i16 }),
3420            "relaxed_narrow inputs must fit in the destination type",
3421        );
3422        self.saturating_narrow_i16x8(a, b)
3423    }
3424    #[inline(always)]
3425    fn splat_u16x8(self, val: u16) -> u16x8<Self> {
3426        crate::kernel!(
3427            #[inline(always)]
3428            fn kernel(token: Sse2, val: u16) -> u16x8<Sse2> {
3429                _mm_set1_epi16(val.cast_signed()).simd_into(token)
3430            }
3431        );
3432        kernel(self, val)
3433    }
3434    #[inline(always)]
3435    fn reverse_u16x8(self, a: u16x8<Self>) -> u16x8<Self> {
3436        [
3437            a[7usize], a[6usize], a[5usize], a[4usize], a[3usize], a[2usize], a[1usize], a[0usize],
3438        ]
3439        .simd_into(self)
3440    }
3441    #[inline(always)]
3442    fn slide_u16x8<const SHIFT: usize>(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3443        if SHIFT >= 8usize {
3444            return b;
3445        }
3446        let result = dyn_alignr_128(
3447            self,
3448            Bytes::to_bytes(b).val.0,
3449            Bytes::to_bytes(a).val.0,
3450            SHIFT * 2usize,
3451        );
3452        Bytes::from_bytes(u8x16 {
3453            val: crate::support::Aligned128(result),
3454            simd: self,
3455        })
3456    }
3457    #[inline(always)]
3458    fn compress_u16x8(self, values: u16x8<Self>, mask: mask16x8<Self>) -> u16x8<Self> {
3459        let mask = mask8x16 {
3460            val: crate::transmute::checked_transmute_copy(&mask.val),
3461            simd: self,
3462        };
3463        Bytes::from_bytes(self.compress_u8x16(Bytes::to_bytes(values), mask))
3464    }
3465    #[inline(always)]
3466    fn compress_merge_u16x8(
3467        self,
3468        values: u16x8<Self>,
3469        mask: mask16x8<Self>,
3470        merge: u16x8<Self>,
3471    ) -> u16x8<Self> {
3472        let mask = mask8x16 {
3473            val: crate::transmute::checked_transmute_copy(&mask.val),
3474            simd: self,
3475        };
3476        Bytes::from_bytes(self.compress_merge_u8x16(
3477            Bytes::to_bytes(values),
3478            mask,
3479            Bytes::to_bytes(merge),
3480        ))
3481    }
3482    #[inline(always)]
3483    fn expand_u16x8(self, values: u16x8<Self>, mask: mask16x8<Self>) -> u16x8<Self> {
3484        let mask = mask8x16 {
3485            val: crate::transmute::checked_transmute_copy(&mask.val),
3486            simd: self,
3487        };
3488        Bytes::from_bytes(self.expand_u8x16(Bytes::to_bytes(values), mask))
3489    }
3490    #[inline(always)]
3491    fn expand_merge_u16x8(
3492        self,
3493        values: u16x8<Self>,
3494        mask: mask16x8<Self>,
3495        merge: u16x8<Self>,
3496    ) -> u16x8<Self> {
3497        let mask = mask8x16 {
3498            val: crate::transmute::checked_transmute_copy(&mask.val),
3499            simd: self,
3500        };
3501        Bytes::from_bytes(self.expand_merge_u8x16(
3502            Bytes::to_bytes(values),
3503            mask,
3504            Bytes::to_bytes(merge),
3505        ))
3506    }
3507    #[inline(always)]
3508    fn count_ones_u16x8(self, a: u16x8<Self>) -> u16x8<Self> {
3509        [
3510            u16::try_from(a[0usize].count_ones()).unwrap(),
3511            u16::try_from(a[1usize].count_ones()).unwrap(),
3512            u16::try_from(a[2usize].count_ones()).unwrap(),
3513            u16::try_from(a[3usize].count_ones()).unwrap(),
3514            u16::try_from(a[4usize].count_ones()).unwrap(),
3515            u16::try_from(a[5usize].count_ones()).unwrap(),
3516            u16::try_from(a[6usize].count_ones()).unwrap(),
3517            u16::try_from(a[7usize].count_ones()).unwrap(),
3518        ]
3519        .simd_into(self)
3520    }
3521    #[inline(always)]
3522    fn count_zeros_u16x8(self, a: u16x8<Self>) -> u16x8<Self> {
3523        [
3524            u16::try_from(a[0usize].count_zeros()).unwrap(),
3525            u16::try_from(a[1usize].count_zeros()).unwrap(),
3526            u16::try_from(a[2usize].count_zeros()).unwrap(),
3527            u16::try_from(a[3usize].count_zeros()).unwrap(),
3528            u16::try_from(a[4usize].count_zeros()).unwrap(),
3529            u16::try_from(a[5usize].count_zeros()).unwrap(),
3530            u16::try_from(a[6usize].count_zeros()).unwrap(),
3531            u16::try_from(a[7usize].count_zeros()).unwrap(),
3532        ]
3533        .simd_into(self)
3534    }
3535    #[inline(always)]
3536    fn add_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3537        crate::kernel!(
3538            #[inline(always)]
3539            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> u16x8<Sse2> {
3540                _mm_add_epi16(a.into(), b.into()).simd_into(token)
3541            }
3542        );
3543        kernel(self, a, b)
3544    }
3545    #[inline(always)]
3546    fn saturating_add_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3547        crate::kernel!(
3548            #[inline(always)]
3549            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> u16x8<Sse2> {
3550                _mm_adds_epu16(a.into(), b.into()).simd_into(token)
3551            }
3552        );
3553        kernel(self, a, b)
3554    }
3555    #[inline(always)]
3556    fn sub_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3557        crate::kernel!(
3558            #[inline(always)]
3559            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> u16x8<Sse2> {
3560                _mm_sub_epi16(a.into(), b.into()).simd_into(token)
3561            }
3562        );
3563        kernel(self, a, b)
3564    }
3565    #[inline(always)]
3566    fn saturating_sub_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3567        crate::kernel!(
3568            #[inline(always)]
3569            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> u16x8<Sse2> {
3570                _mm_subs_epu16(a.into(), b.into()).simd_into(token)
3571            }
3572        );
3573        kernel(self, a, b)
3574    }
3575    #[inline(always)]
3576    fn mul_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3577        crate::kernel!(
3578            #[inline(always)]
3579            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> u16x8<Sse2> {
3580                _mm_mullo_epi16(a.into(), b.into()).simd_into(token)
3581            }
3582        );
3583        kernel(self, a, b)
3584    }
3585    #[inline(always)]
3586    fn and_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3587        crate::kernel!(
3588            #[inline(always)]
3589            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> u16x8<Sse2> {
3590                _mm_and_si128(a.into(), b.into()).simd_into(token)
3591            }
3592        );
3593        kernel(self, a, b)
3594    }
3595    #[inline(always)]
3596    fn or_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3597        crate::kernel!(
3598            #[inline(always)]
3599            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> u16x8<Sse2> {
3600                _mm_or_si128(a.into(), b.into()).simd_into(token)
3601            }
3602        );
3603        kernel(self, a, b)
3604    }
3605    #[inline(always)]
3606    fn xor_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3607        crate::kernel!(
3608            #[inline(always)]
3609            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> u16x8<Sse2> {
3610                _mm_xor_si128(a.into(), b.into()).simd_into(token)
3611            }
3612        );
3613        kernel(self, a, b)
3614    }
3615    #[inline(always)]
3616    fn not_u16x8(self, a: u16x8<Self>) -> u16x8<Self> {
3617        a ^ !0
3618    }
3619    #[inline(always)]
3620    fn shl_u16x8(self, a: u16x8<Self>, shift: u32) -> u16x8<Self> {
3621        crate::kernel!(
3622            #[inline(always)]
3623            fn kernel(token: Sse2, a: u16x8<Sse2>, shift: u32) -> u16x8<Sse2> {
3624                _mm_sll_epi16(a.into(), _mm_cvtsi32_si128(shift.cast_signed())).simd_into(token)
3625            }
3626        );
3627        kernel(self, a, shift)
3628    }
3629    #[inline(always)]
3630    fn shlv_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3631        [
3632            u16::wrapping_shl(a[0usize], b[0usize] as u32),
3633            u16::wrapping_shl(a[1usize], b[1usize] as u32),
3634            u16::wrapping_shl(a[2usize], b[2usize] as u32),
3635            u16::wrapping_shl(a[3usize], b[3usize] as u32),
3636            u16::wrapping_shl(a[4usize], b[4usize] as u32),
3637            u16::wrapping_shl(a[5usize], b[5usize] as u32),
3638            u16::wrapping_shl(a[6usize], b[6usize] as u32),
3639            u16::wrapping_shl(a[7usize], b[7usize] as u32),
3640        ]
3641        .simd_into(self)
3642    }
3643    #[inline(always)]
3644    fn shr_u16x8(self, a: u16x8<Self>, shift: u32) -> u16x8<Self> {
3645        crate::kernel!(
3646            #[inline(always)]
3647            fn kernel(token: Sse2, a: u16x8<Sse2>, shift: u32) -> u16x8<Sse2> {
3648                _mm_srl_epi16(a.into(), _mm_cvtsi32_si128(shift.cast_signed())).simd_into(token)
3649            }
3650        );
3651        kernel(self, a, shift)
3652    }
3653    #[inline(always)]
3654    fn shrv_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3655        [
3656            u16::wrapping_shr(a[0usize], b[0usize] as u32),
3657            u16::wrapping_shr(a[1usize], b[1usize] as u32),
3658            u16::wrapping_shr(a[2usize], b[2usize] as u32),
3659            u16::wrapping_shr(a[3usize], b[3usize] as u32),
3660            u16::wrapping_shr(a[4usize], b[4usize] as u32),
3661            u16::wrapping_shr(a[5usize], b[5usize] as u32),
3662            u16::wrapping_shr(a[6usize], b[6usize] as u32),
3663            u16::wrapping_shr(a[7usize], b[7usize] as u32),
3664        ]
3665        .simd_into(self)
3666    }
3667    #[inline(always)]
3668    fn reduce_max_u16x8(self, a: u16x8<Self>) -> u16 {
3669        crate::kernel!(
3670            #[inline(always)]
3671            fn kernel(token: Sse2, a: u16x8<Sse2>) -> u16 {
3672                let reduced: __m128i = a.into();
3673                let shifted = _mm_srli_si128::<8>(reduced);
3674                let reduced = {
3675                    {
3676                        let a = reduced;
3677                        let b = shifted;
3678                        let gt = {
3679                            let sign_bit = _mm_set1_epi16(0x8000u16.cast_signed());
3680                            let lhs_signed = _mm_xor_si128(a, sign_bit);
3681                            let rhs_signed = _mm_xor_si128(b, sign_bit);
3682                            _mm_cmpgt_epi16(lhs_signed, rhs_signed)
3683                        };
3684                        _mm_or_si128(_mm_and_si128(gt, a), _mm_andnot_si128(gt, b))
3685                    }
3686                };
3687                let shifted = _mm_srli_si128::<4>(reduced);
3688                let reduced = {
3689                    {
3690                        let a = reduced;
3691                        let b = shifted;
3692                        let gt = {
3693                            let sign_bit = _mm_set1_epi16(0x8000u16.cast_signed());
3694                            let lhs_signed = _mm_xor_si128(a, sign_bit);
3695                            let rhs_signed = _mm_xor_si128(b, sign_bit);
3696                            _mm_cmpgt_epi16(lhs_signed, rhs_signed)
3697                        };
3698                        _mm_or_si128(_mm_and_si128(gt, a), _mm_andnot_si128(gt, b))
3699                    }
3700                };
3701                let shifted = _mm_srli_si128::<2>(reduced);
3702                let reduced = {
3703                    {
3704                        let a = reduced;
3705                        let b = shifted;
3706                        let gt = {
3707                            let sign_bit = _mm_set1_epi16(0x8000u16.cast_signed());
3708                            let lhs_signed = _mm_xor_si128(a, sign_bit);
3709                            let rhs_signed = _mm_xor_si128(b, sign_bit);
3710                            _mm_cmpgt_epi16(lhs_signed, rhs_signed)
3711                        };
3712                        _mm_or_si128(_mm_and_si128(gt, a), _mm_andnot_si128(gt, b))
3713                    }
3714                };
3715                {
3716                    let lanes: [u16; 8usize] = crate::transmute::checked_transmute_copy(&reduced);
3717                    lanes[0]
3718                }
3719            }
3720        );
3721        kernel(self, a)
3722    }
3723    #[inline(always)]
3724    fn reduce_min_u16x8(self, a: u16x8<Self>) -> u16 {
3725        crate::kernel!(
3726            #[inline(always)]
3727            fn kernel(token: Sse2, a: u16x8<Sse2>) -> u16 {
3728                let reduced: __m128i = a.into();
3729                let shifted = _mm_srli_si128::<8>(reduced);
3730                let reduced = {
3731                    {
3732                        let a = reduced;
3733                        let b = shifted;
3734                        let gt = {
3735                            let sign_bit = _mm_set1_epi16(0x8000u16.cast_signed());
3736                            let lhs_signed = _mm_xor_si128(a, sign_bit);
3737                            let rhs_signed = _mm_xor_si128(b, sign_bit);
3738                            _mm_cmpgt_epi16(lhs_signed, rhs_signed)
3739                        };
3740                        _mm_or_si128(_mm_and_si128(gt, b), _mm_andnot_si128(gt, a))
3741                    }
3742                };
3743                let shifted = _mm_srli_si128::<4>(reduced);
3744                let reduced = {
3745                    {
3746                        let a = reduced;
3747                        let b = shifted;
3748                        let gt = {
3749                            let sign_bit = _mm_set1_epi16(0x8000u16.cast_signed());
3750                            let lhs_signed = _mm_xor_si128(a, sign_bit);
3751                            let rhs_signed = _mm_xor_si128(b, sign_bit);
3752                            _mm_cmpgt_epi16(lhs_signed, rhs_signed)
3753                        };
3754                        _mm_or_si128(_mm_and_si128(gt, b), _mm_andnot_si128(gt, a))
3755                    }
3756                };
3757                let shifted = _mm_srli_si128::<2>(reduced);
3758                let reduced = {
3759                    {
3760                        let a = reduced;
3761                        let b = shifted;
3762                        let gt = {
3763                            let sign_bit = _mm_set1_epi16(0x8000u16.cast_signed());
3764                            let lhs_signed = _mm_xor_si128(a, sign_bit);
3765                            let rhs_signed = _mm_xor_si128(b, sign_bit);
3766                            _mm_cmpgt_epi16(lhs_signed, rhs_signed)
3767                        };
3768                        _mm_or_si128(_mm_and_si128(gt, b), _mm_andnot_si128(gt, a))
3769                    }
3770                };
3771                {
3772                    let lanes: [u16; 8usize] = crate::transmute::checked_transmute_copy(&reduced);
3773                    lanes[0]
3774                }
3775            }
3776        );
3777        kernel(self, a)
3778    }
3779    #[inline(always)]
3780    fn reduce_sum_u16x8(self, a: u16x8<Self>) -> u16 {
3781        crate::kernel!(
3782            #[inline(always)]
3783            fn kernel(token: Sse2, a: u16x8<Sse2>) -> u16 {
3784                let sum: __m128i = a.into();
3785                let sum = _mm_add_epi16(sum, _mm_srli_si128::<8>(sum));
3786                let sum = _mm_add_epi16(sum, _mm_srli_si128::<4>(sum));
3787                let sum = _mm_add_epi16(sum, _mm_srli_si128::<2>(sum));
3788                let lanes: [u16; 8usize] = crate::transmute::checked_transmute_copy(&sum);
3789                lanes[0]
3790            }
3791        );
3792        kernel(self, a)
3793    }
3794    #[inline(always)]
3795    fn reduce_product_u16x8(self, a: u16x8<Self>) -> u16 {
3796        crate::kernel!(
3797            #[inline(always)]
3798            fn kernel(token: Sse2, a: u16x8<Sse2>) -> u16 {
3799                let product: __m128i = a.into();
3800                let product = _mm_mullo_epi16(product, _mm_shuffle_epi32::<0b11_10_11_10>(product));
3801                let product = _mm_mullo_epi16(product, _mm_shuffle_epi32::<0b01_01_01_01>(product));
3802                let product = _mm_mullo_epi16(product, _mm_srli_epi32::<16>(product));
3803                let lanes: [u16; 8usize] = crate::transmute::checked_transmute_copy(&product);
3804                lanes[0]
3805            }
3806        );
3807        kernel(self, a)
3808    }
3809    #[inline(always)]
3810    fn max_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3811        crate::kernel!(
3812            #[inline(always)]
3813            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> u16x8<Sse2> {
3814                {
3815                    let a = a.into();
3816                    let b = b.into();
3817                    let gt = {
3818                        let sign_bit = _mm_set1_epi16(0x8000u16.cast_signed());
3819                        let lhs_signed = _mm_xor_si128(a, sign_bit);
3820                        let rhs_signed = _mm_xor_si128(b, sign_bit);
3821                        _mm_cmpgt_epi16(lhs_signed, rhs_signed)
3822                    };
3823                    _mm_or_si128(_mm_and_si128(gt, a), _mm_andnot_si128(gt, b))
3824                }
3825                .simd_into(token)
3826            }
3827        );
3828        kernel(self, a, b)
3829    }
3830    #[inline(always)]
3831    fn min_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3832        crate::kernel!(
3833            #[inline(always)]
3834            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> u16x8<Sse2> {
3835                {
3836                    let a = a.into();
3837                    let b = b.into();
3838                    let gt = {
3839                        let sign_bit = _mm_set1_epi16(0x8000u16.cast_signed());
3840                        let lhs_signed = _mm_xor_si128(a, sign_bit);
3841                        let rhs_signed = _mm_xor_si128(b, sign_bit);
3842                        _mm_cmpgt_epi16(lhs_signed, rhs_signed)
3843                    };
3844                    _mm_or_si128(_mm_and_si128(gt, b), _mm_andnot_si128(gt, a))
3845                }
3846                .simd_into(token)
3847            }
3848        );
3849        kernel(self, a, b)
3850    }
3851    #[inline(always)]
3852    fn clamp_u16x8(self, a: u16x8<Self>, b: u16x8<Self>, c: u16x8<Self>) -> u16x8<Self> {
3853        debug_assert!(
3854            b.simd_le(c).all_true(),
3855            "clamp requires min <= max for all elements"
3856        );
3857        a.max(b).min(c)
3858    }
3859    #[inline(always)]
3860    fn simd_eq_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> mask16x8<Self> {
3861        crate::kernel!(
3862            #[inline(always)]
3863            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> mask16x8<Sse2> {
3864                _mm_cmpeq_epi16(a.into(), b.into()).simd_into(token)
3865            }
3866        );
3867        kernel(self, a, b)
3868    }
3869    #[inline(always)]
3870    fn simd_lt_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> mask16x8<Self> {
3871        crate::kernel!(
3872            #[inline(always)]
3873            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> mask16x8<Sse2> {
3874                {
3875                    let sign_bit = _mm_set1_epi16(0x8000u16.cast_signed());
3876                    let lhs_signed = _mm_xor_si128(b.into(), sign_bit);
3877                    let rhs_signed = _mm_xor_si128(a.into(), sign_bit);
3878                    _mm_cmpgt_epi16(lhs_signed, rhs_signed)
3879                }
3880                .simd_into(token)
3881            }
3882        );
3883        kernel(self, a, b)
3884    }
3885    #[inline(always)]
3886    fn simd_le_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> mask16x8<Self> {
3887        crate::kernel!(
3888            #[inline(always)]
3889            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> mask16x8<Sse2> {
3890                {
3891                    let all_ones = _mm_set1_epi8(-1);
3892                    _mm_xor_si128(
3893                        {
3894                            let sign_bit = _mm_set1_epi16(0x8000u16.cast_signed());
3895                            let lhs_signed = _mm_xor_si128(a.into(), sign_bit);
3896                            let rhs_signed = _mm_xor_si128(b.into(), sign_bit);
3897                            _mm_cmpgt_epi16(lhs_signed, rhs_signed)
3898                        },
3899                        all_ones,
3900                    )
3901                }
3902                .simd_into(token)
3903            }
3904        );
3905        kernel(self, a, b)
3906    }
3907    #[inline(always)]
3908    fn zip_low_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3909        crate::kernel!(
3910            #[inline(always)]
3911            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> u16x8<Sse2> {
3912                _mm_unpacklo_epi16(a.into(), b.into()).simd_into(token)
3913            }
3914        );
3915        kernel(self, a, b)
3916    }
3917    #[inline(always)]
3918    fn zip_high_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3919        crate::kernel!(
3920            #[inline(always)]
3921            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> u16x8<Sse2> {
3922                _mm_unpackhi_epi16(a.into(), b.into()).simd_into(token)
3923            }
3924        );
3925        kernel(self, a, b)
3926    }
3927    #[inline(always)]
3928    fn unzip_low_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3929        [
3930            a[0usize], a[2usize], a[4usize], a[6usize], b[0usize], b[2usize], b[4usize], b[6usize],
3931        ]
3932        .simd_into(self)
3933    }
3934    #[inline(always)]
3935    fn unzip_high_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self> {
3936        [
3937            a[1usize], a[3usize], a[5usize], a[7usize], b[1usize], b[3usize], b[5usize], b[7usize],
3938        ]
3939        .simd_into(self)
3940    }
3941    #[inline(always)]
3942    fn interleave_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> (u16x8<Self>, u16x8<Self>) {
3943        (self.zip_low_u16x8(a, b), self.zip_high_u16x8(a, b))
3944    }
3945    #[inline(always)]
3946    fn deinterleave_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> (u16x8<Self>, u16x8<Self>) {
3947        (self.unzip_low_u16x8(a, b), self.unzip_high_u16x8(a, b))
3948    }
3949    #[inline(always)]
3950    fn select_u16x8(self, a: mask16x8<Self>, b: u16x8<Self>, c: u16x8<Self>) -> u16x8<Self> {
3951        crate::kernel!(
3952            #[inline(always)]
3953            fn kernel(
3954                token: Sse2,
3955                a: mask16x8<Sse2>,
3956                b: u16x8<Sse2>,
3957                c: u16x8<Sse2>,
3958            ) -> u16x8<Sse2> {
3959                _mm_or_si128(
3960                    _mm_and_si128(a.into(), b.into()),
3961                    _mm_andnot_si128(a.into(), c.into()),
3962                )
3963                .simd_into(token)
3964            }
3965        );
3966        kernel(self, a, b, c)
3967    }
3968    #[inline(always)]
3969    fn combine_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x16<Self> {
3970        u16x16 {
3971            val: crate::support::Aligned256([a.val.0, b.val.0]),
3972            simd: self,
3973        }
3974    }
3975    #[inline(always)]
3976    fn load_four_interleaved_u16x8(self, src: &[u16; 32usize]) -> [u16x8<Self>; 4usize] {
3977        [
3978            [
3979                src[0usize],
3980                src[4usize],
3981                src[8usize],
3982                src[12usize],
3983                src[16usize],
3984                src[20usize],
3985                src[24usize],
3986                src[28usize],
3987            ]
3988            .simd_into(self),
3989            [
3990                src[1usize],
3991                src[5usize],
3992                src[9usize],
3993                src[13usize],
3994                src[17usize],
3995                src[21usize],
3996                src[25usize],
3997                src[29usize],
3998            ]
3999            .simd_into(self),
4000            [
4001                src[2usize],
4002                src[6usize],
4003                src[10usize],
4004                src[14usize],
4005                src[18usize],
4006                src[22usize],
4007                src[26usize],
4008                src[30usize],
4009            ]
4010            .simd_into(self),
4011            [
4012                src[3usize],
4013                src[7usize],
4014                src[11usize],
4015                src[15usize],
4016                src[19usize],
4017                src[23usize],
4018                src[27usize],
4019                src[31usize],
4020            ]
4021            .simd_into(self),
4022        ]
4023    }
4024    #[inline(always)]
4025    fn store_four_interleaved_u16x8(
4026        self,
4027        vectors: [u16x8<Self>; 4usize],
4028        dest: &mut [u16; 32usize],
4029    ) -> () {
4030        *dest = [
4031            vectors[0usize][0usize],
4032            vectors[1usize][0usize],
4033            vectors[2usize][0usize],
4034            vectors[3usize][0usize],
4035            vectors[0usize][1usize],
4036            vectors[1usize][1usize],
4037            vectors[2usize][1usize],
4038            vectors[3usize][1usize],
4039            vectors[0usize][2usize],
4040            vectors[1usize][2usize],
4041            vectors[2usize][2usize],
4042            vectors[3usize][2usize],
4043            vectors[0usize][3usize],
4044            vectors[1usize][3usize],
4045            vectors[2usize][3usize],
4046            vectors[3usize][3usize],
4047            vectors[0usize][4usize],
4048            vectors[1usize][4usize],
4049            vectors[2usize][4usize],
4050            vectors[3usize][4usize],
4051            vectors[0usize][5usize],
4052            vectors[1usize][5usize],
4053            vectors[2usize][5usize],
4054            vectors[3usize][5usize],
4055            vectors[0usize][6usize],
4056            vectors[1usize][6usize],
4057            vectors[2usize][6usize],
4058            vectors[3usize][6usize],
4059            vectors[0usize][7usize],
4060            vectors[1usize][7usize],
4061            vectors[2usize][7usize],
4062            vectors[3usize][7usize],
4063        ];
4064    }
4065    #[inline(always)]
4066    fn widen_u16x8(self, a: u16x8<Self>) -> (u32x4<Self>, u32x4<Self>) {
4067        crate::kernel!(
4068            #[inline(always)]
4069            fn kernel(token: Sse2, a: u16x8<Sse2>) -> (u32x4<Sse2>, u32x4<Sse2>) {
4070                let raw = a.into();
4071                let sign = _mm_setzero_si128();
4072                (
4073                    _mm_unpacklo_epi16(raw, sign).simd_into(token),
4074                    _mm_unpackhi_epi16(raw, sign).simd_into(token),
4075                )
4076            }
4077        );
4078        kernel(self, a)
4079    }
4080    #[inline(always)]
4081    fn widening_mul_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> (u32x4<Self>, u32x4<Self>) {
4082        crate::kernel!(
4083            #[inline(always)]
4084            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> (u32x4<Sse2>, u32x4<Sse2>) {
4085                let a = a.into();
4086                let b = b.into();
4087                let low = _mm_mullo_epi16(a, b);
4088                let high = _mm_mulhi_epu16(a, b);
4089                let result_low = _mm_unpacklo_epi16(low, high);
4090                let result_high = _mm_unpackhi_epi16(low, high);
4091                (result_low.simd_into(token), result_high.simd_into(token))
4092            }
4093        );
4094        kernel(self, a, b)
4095    }
4096    #[inline(always)]
4097    fn widening_add_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> (u32x4<Self>, u32x4<Self>) {
4098        let (a0, a1) = self.widen_u16x8(a);
4099        let (b0, b1) = self.widen_u16x8(b);
4100        (self.add_u32x4(a0, b0), self.add_u32x4(a1, b1))
4101    }
4102    #[inline(always)]
4103    fn pairwise_widening_add_u16x8(self, a: u16x8<Self>) -> u32x4<Self> {
4104        crate::kernel!(
4105            #[inline(always)]
4106            fn kernel(token: Sse2, a: u16x8<Sse2>) -> u32x4<Sse2> {
4107                ({
4108                    let a = a.into();
4109                    _mm_add_epi32(
4110                        _mm_and_si128(a, _mm_set1_epi32(65535)),
4111                        _mm_srli_epi32::<16>(a),
4112                    )
4113                })
4114                .simd_into(token)
4115            }
4116        );
4117        kernel(self, a)
4118    }
4119    #[inline(always)]
4120    fn pairwise_dot_product_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u32x4<Self> {
4121        let (low, high) = self.widening_mul_u16x8(a, b);
4122        let (even, odd) = self.deinterleave_u32x4(low, high);
4123        self.add_u32x4(even, odd)
4124    }
4125    #[inline(always)]
4126    fn narrow_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u8x16<Self> {
4127        crate::kernel!(
4128            #[inline(always)]
4129            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> u8x16<Sse2> {
4130                let mask = _mm_set1_epi16(0xff);
4131                _mm_packus_epi16(_mm_and_si128(a.into(), mask), _mm_and_si128(b.into(), mask))
4132                    .simd_into(token)
4133            }
4134        );
4135        kernel(self, a, b)
4136    }
4137    #[inline(always)]
4138    fn saturating_narrow_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u8x16<Self> {
4139        crate::kernel!(
4140            #[inline(always)]
4141            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> u8x16<Sse2> {
4142                let max = _mm_set1_epi16(u8::MAX as i16);
4143                let a = a.into();
4144                let b = b.into();
4145                let a = _mm_sub_epi16(a, _mm_subs_epu16(a, max));
4146                let b = _mm_sub_epi16(b, _mm_subs_epu16(b, max));
4147                _mm_packus_epi16(a, b).simd_into(token)
4148            }
4149        );
4150        kernel(self, a, b)
4151    }
4152    #[inline(always)]
4153    fn relaxed_narrow_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u8x16<Self> {
4154        crate::kernel!(
4155            #[inline(always)]
4156            fn kernel(token: Sse2, a: u16x8<Sse2>, b: u16x8<Sse2>) -> u8x16<Sse2> {
4157                debug_assert!(
4158                    a.as_slice()
4159                        .iter()
4160                        .chain(b.as_slice())
4161                        .all(|&value| { value >= u8::MIN as u16 && value <= u8::MAX as u16 }),
4162                    "relaxed_narrow inputs must fit in the destination type",
4163                );
4164                _mm_packus_epi16(a.into(), b.into()).simd_into(token)
4165            }
4166        );
4167        kernel(self, a, b)
4168    }
4169    #[inline(always)]
4170    fn splat_mask16x8(self, val: bool) -> mask16x8<Self> {
4171        crate::kernel!(
4172            #[inline(always)]
4173            fn kernel(token: Sse2, val: bool) -> mask16x8<Sse2> {
4174                let val: i16 = if val { !0 } else { 0 };
4175                _mm_set1_epi16(val).simd_into(token)
4176            }
4177        );
4178        kernel(self, val)
4179    }
4180    #[inline(always)]
4181    fn from_bitmask_mask16x8(self, bits: u64) -> mask16x8<Self> {
4182        crate::kernel!(
4183            #[inline(always)]
4184            fn kernel(token: Sse2, bits: u64) -> mask16x8<Sse2> {
4185                {
4186                    let bit_lanes = _mm_set1_epi16(bits as i16);
4187                    let bit_mask = _mm_setr_epi16(1, 2, 4, 8, 16, 32, 64, 128);
4188                    _mm_cmpeq_epi16(_mm_and_si128(bit_lanes, bit_mask), bit_mask)
4189                }
4190                .simd_into(token)
4191            }
4192        );
4193        kernel(self, bits)
4194    }
4195    #[inline(always)]
4196    fn to_bitmask_mask16x8(self, a: mask16x8<Self>) -> u64 {
4197        crate::kernel!(
4198            #[inline(always)]
4199            fn kernel(token: Sse2, a: mask16x8<Sse2>) -> u64 {
4200                {
4201                    let packed = _mm_packs_epi16(a.into(), a.into());
4202                    _mm_movemask_epi8(packed) as u8 as u64
4203                }
4204            }
4205        );
4206        kernel(self, a)
4207    }
4208    #[inline(always)]
4209    fn from_vector_mask16x8(self, vector: i16x8<Self>) -> mask16x8<Self> {
4210        mask16x8 {
4211            val: vector.val,
4212            simd: self,
4213        }
4214    }
4215    #[inline(always)]
4216    fn to_vector_mask16x8(self, a: mask16x8<Self>) -> i16x8<Self> {
4217        i16x8 {
4218            val: a.val,
4219            simd: self,
4220        }
4221    }
4222    #[inline(always)]
4223    fn set_mask16x8(self, a: &mut mask16x8<Self>, index: usize, value: bool) -> () {
4224        assert!(
4225            index < 8usize,
4226            "mask lane index {index} is out of bounds for {} lanes",
4227            8usize
4228        );
4229        let mut lanes: [i16; 8usize] = (*a).into();
4230        lanes[index] = if value { !0 } else { 0 };
4231        *a = lanes.simd_into(self);
4232    }
4233    #[inline(always)]
4234    fn rotate_elements_left_mask16x8<const OFFSET: usize>(
4235        self,
4236        a: mask16x8<Self>,
4237    ) -> mask16x8<Self> {
4238        let int = i16x8 {
4239            val: crate::transmute::checked_transmute_copy(&a.val),
4240            simd: self,
4241        };
4242        let rotated = int.rotate_elements_left::<OFFSET>();
4243        mask16x8 {
4244            val: crate::transmute::checked_transmute_copy(&rotated.val),
4245            simd: self,
4246        }
4247    }
4248    #[inline(always)]
4249    fn rotate_elements_right_mask16x8<const OFFSET: usize>(
4250        self,
4251        a: mask16x8<Self>,
4252    ) -> mask16x8<Self> {
4253        let int = i16x8 {
4254            val: crate::transmute::checked_transmute_copy(&a.val),
4255            simd: self,
4256        };
4257        let rotated = int.rotate_elements_right::<OFFSET>();
4258        mask16x8 {
4259            val: crate::transmute::checked_transmute_copy(&rotated.val),
4260            simd: self,
4261        }
4262    }
4263    #[inline(always)]
4264    fn and_mask16x8(self, a: mask16x8<Self>, b: mask16x8<Self>) -> mask16x8<Self> {
4265        crate::kernel!(
4266            #[inline(always)]
4267            fn kernel(token: Sse2, a: mask16x8<Sse2>, b: mask16x8<Sse2>) -> mask16x8<Sse2> {
4268                _mm_and_si128(a.into(), b.into()).simd_into(token)
4269            }
4270        );
4271        kernel(self, a, b)
4272    }
4273    #[inline(always)]
4274    fn or_mask16x8(self, a: mask16x8<Self>, b: mask16x8<Self>) -> mask16x8<Self> {
4275        crate::kernel!(
4276            #[inline(always)]
4277            fn kernel(token: Sse2, a: mask16x8<Sse2>, b: mask16x8<Sse2>) -> mask16x8<Sse2> {
4278                _mm_or_si128(a.into(), b.into()).simd_into(token)
4279            }
4280        );
4281        kernel(self, a, b)
4282    }
4283    #[inline(always)]
4284    fn xor_mask16x8(self, a: mask16x8<Self>, b: mask16x8<Self>) -> mask16x8<Self> {
4285        crate::kernel!(
4286            #[inline(always)]
4287            fn kernel(token: Sse2, a: mask16x8<Sse2>, b: mask16x8<Sse2>) -> mask16x8<Sse2> {
4288                _mm_xor_si128(a.into(), b.into()).simd_into(token)
4289            }
4290        );
4291        kernel(self, a, b)
4292    }
4293    #[inline(always)]
4294    fn not_mask16x8(self, a: mask16x8<Self>) -> mask16x8<Self> {
4295        self.xor_mask16x8(a, self.splat_mask16x8(true))
4296    }
4297    #[inline(always)]
4298    fn reverse_mask16x8(self, a: mask16x8<Self>) -> mask16x8<Self> {
4299        let lanes = i16x8 {
4300            val: crate::transmute::checked_transmute_copy(&a.val),
4301            simd: self,
4302        };
4303        let reversed = self.reverse_i16x8(lanes);
4304        mask16x8 {
4305            val: crate::transmute::checked_transmute_copy(&reversed.val),
4306            simd: self,
4307        }
4308    }
4309    #[inline(always)]
4310    fn select_mask16x8(
4311        self,
4312        a: mask16x8<Self>,
4313        b: mask16x8<Self>,
4314        c: mask16x8<Self>,
4315    ) -> mask16x8<Self> {
4316        crate::kernel!(
4317            #[inline(always)]
4318            fn kernel(
4319                token: Sse2,
4320                a: mask16x8<Sse2>,
4321                b: mask16x8<Sse2>,
4322                c: mask16x8<Sse2>,
4323            ) -> mask16x8<Sse2> {
4324                _mm_or_si128(
4325                    _mm_and_si128(a.into(), b.into()),
4326                    _mm_andnot_si128(a.into(), c.into()),
4327                )
4328                .simd_into(token)
4329            }
4330        );
4331        kernel(self, a, b, c)
4332    }
4333    #[inline(always)]
4334    fn simd_eq_mask16x8(self, a: mask16x8<Self>, b: mask16x8<Self>) -> mask16x8<Self> {
4335        crate::kernel!(
4336            #[inline(always)]
4337            fn kernel(token: Sse2, a: mask16x8<Sse2>, b: mask16x8<Sse2>) -> mask16x8<Sse2> {
4338                _mm_cmpeq_epi16(a.into(), b.into()).simd_into(token)
4339            }
4340        );
4341        kernel(self, a, b)
4342    }
4343    #[inline(always)]
4344    fn any_true_mask16x8(self, a: mask16x8<Self>) -> bool {
4345        crate::kernel!(
4346            #[inline(always)]
4347            fn kernel(token: Sse2, a: mask16x8<Sse2>) -> bool {
4348                _mm_movemask_epi8(a.into()) as u32 != 0
4349            }
4350        );
4351        kernel(self, a)
4352    }
4353    #[inline(always)]
4354    fn all_true_mask16x8(self, a: mask16x8<Self>) -> bool {
4355        crate::kernel!(
4356            #[inline(always)]
4357            fn kernel(token: Sse2, a: mask16x8<Sse2>) -> bool {
4358                _mm_movemask_epi8(a.into()) as u32 == 0xffff
4359            }
4360        );
4361        kernel(self, a)
4362    }
4363    #[inline(always)]
4364    fn any_false_mask16x8(self, a: mask16x8<Self>) -> bool {
4365        crate::kernel!(
4366            #[inline(always)]
4367            fn kernel(token: Sse2, a: mask16x8<Sse2>) -> bool {
4368                _mm_movemask_epi8(a.into()) as u32 != 0xffff
4369            }
4370        );
4371        kernel(self, a)
4372    }
4373    #[inline(always)]
4374    fn all_false_mask16x8(self, a: mask16x8<Self>) -> bool {
4375        crate::kernel!(
4376            #[inline(always)]
4377            fn kernel(token: Sse2, a: mask16x8<Sse2>) -> bool {
4378                _mm_movemask_epi8(a.into()) as u32 == 0
4379            }
4380        );
4381        kernel(self, a)
4382    }
4383    #[inline(always)]
4384    fn combine_mask16x8(self, a: mask16x8<Self>, b: mask16x8<Self>) -> mask16x16<Self> {
4385        mask16x16 {
4386            val: crate::support::Aligned256([a.val.0, b.val.0]),
4387            simd: self,
4388        }
4389    }
4390    #[inline(always)]
4391    fn widen_mask16x8(self, a: mask16x8<Self>) -> (mask32x4<Self>, mask32x4<Self>) {
4392        crate::kernel!(
4393            #[inline(always)]
4394            fn kernel(token: Sse2, a: mask16x8<Sse2>) -> (mask32x4<Sse2>, mask32x4<Sse2>) {
4395                let raw = a.into();
4396                (
4397                    _mm_unpacklo_epi16(raw, raw).simd_into(token),
4398                    _mm_unpackhi_epi16(raw, raw).simd_into(token),
4399                )
4400            }
4401        );
4402        kernel(self, a)
4403    }
4404    #[inline(always)]
4405    fn narrow_mask16x8(self, a: mask16x8<Self>, b: mask16x8<Self>) -> mask8x16<Self> {
4406        crate::kernel!(
4407            #[inline(always)]
4408            fn kernel(token: Sse2, a: mask16x8<Sse2>, b: mask16x8<Sse2>) -> mask8x16<Sse2> {
4409                _mm_packs_epi16(a.into(), b.into()).simd_into(token)
4410            }
4411        );
4412        kernel(self, a, b)
4413    }
4414    #[inline(always)]
4415    fn abs_i32x4(self, a: i32x4<Self>) -> i32x4<Self> {
4416        [
4417            i32::wrapping_abs(a[0usize]),
4418            i32::wrapping_abs(a[1usize]),
4419            i32::wrapping_abs(a[2usize]),
4420            i32::wrapping_abs(a[3usize]),
4421        ]
4422        .simd_into(self)
4423    }
4424    #[inline(always)]
4425    fn splat_i32x4(self, val: i32) -> i32x4<Self> {
4426        crate::kernel!(
4427            #[inline(always)]
4428            fn kernel(token: Sse2, val: i32) -> i32x4<Sse2> {
4429                _mm_set1_epi32(val).simd_into(token)
4430            }
4431        );
4432        kernel(self, val)
4433    }
4434    #[inline(always)]
4435    fn reverse_i32x4(self, a: i32x4<Self>) -> i32x4<Self> {
4436        [a[3usize], a[2usize], a[1usize], a[0usize]].simd_into(self)
4437    }
4438    #[inline(always)]
4439    fn slide_i32x4<const SHIFT: usize>(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4440        if SHIFT >= 4usize {
4441            return b;
4442        }
4443        let result = dyn_alignr_128(
4444            self,
4445            Bytes::to_bytes(b).val.0,
4446            Bytes::to_bytes(a).val.0,
4447            SHIFT * 4usize,
4448        );
4449        Bytes::from_bytes(u8x16 {
4450            val: crate::support::Aligned128(result),
4451            simd: self,
4452        })
4453    }
4454    #[inline(always)]
4455    fn compress_i32x4(self, values: i32x4<Self>, mask: mask32x4<Self>) -> i32x4<Self> {
4456        let mask = mask8x16 {
4457            val: crate::transmute::checked_transmute_copy(&mask.val),
4458            simd: self,
4459        };
4460        Bytes::from_bytes(self.compress_u8x16(Bytes::to_bytes(values), mask))
4461    }
4462    #[inline(always)]
4463    fn compress_merge_i32x4(
4464        self,
4465        values: i32x4<Self>,
4466        mask: mask32x4<Self>,
4467        merge: i32x4<Self>,
4468    ) -> i32x4<Self> {
4469        let mask = mask8x16 {
4470            val: crate::transmute::checked_transmute_copy(&mask.val),
4471            simd: self,
4472        };
4473        Bytes::from_bytes(self.compress_merge_u8x16(
4474            Bytes::to_bytes(values),
4475            mask,
4476            Bytes::to_bytes(merge),
4477        ))
4478    }
4479    #[inline(always)]
4480    fn expand_i32x4(self, values: i32x4<Self>, mask: mask32x4<Self>) -> i32x4<Self> {
4481        let mask = mask8x16 {
4482            val: crate::transmute::checked_transmute_copy(&mask.val),
4483            simd: self,
4484        };
4485        Bytes::from_bytes(self.expand_u8x16(Bytes::to_bytes(values), mask))
4486    }
4487    #[inline(always)]
4488    fn expand_merge_i32x4(
4489        self,
4490        values: i32x4<Self>,
4491        mask: mask32x4<Self>,
4492        merge: i32x4<Self>,
4493    ) -> i32x4<Self> {
4494        let mask = mask8x16 {
4495            val: crate::transmute::checked_transmute_copy(&mask.val),
4496            simd: self,
4497        };
4498        Bytes::from_bytes(self.expand_merge_u8x16(
4499            Bytes::to_bytes(values),
4500            mask,
4501            Bytes::to_bytes(merge),
4502        ))
4503    }
4504    #[inline(always)]
4505    fn count_ones_i32x4(self, a: i32x4<Self>) -> i32x4<Self> {
4506        [
4507            a[0usize].count_ones().cast_signed(),
4508            a[1usize].count_ones().cast_signed(),
4509            a[2usize].count_ones().cast_signed(),
4510            a[3usize].count_ones().cast_signed(),
4511        ]
4512        .simd_into(self)
4513    }
4514    #[inline(always)]
4515    fn count_zeros_i32x4(self, a: i32x4<Self>) -> i32x4<Self> {
4516        [
4517            a[0usize].count_zeros().cast_signed(),
4518            a[1usize].count_zeros().cast_signed(),
4519            a[2usize].count_zeros().cast_signed(),
4520            a[3usize].count_zeros().cast_signed(),
4521        ]
4522        .simd_into(self)
4523    }
4524    #[inline(always)]
4525    fn add_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4526        crate::kernel!(
4527            #[inline(always)]
4528            fn kernel(token: Sse2, a: i32x4<Sse2>, b: i32x4<Sse2>) -> i32x4<Sse2> {
4529                _mm_add_epi32(a.into(), b.into()).simd_into(token)
4530            }
4531        );
4532        kernel(self, a, b)
4533    }
4534    #[inline(always)]
4535    fn saturating_add_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4536        [
4537            i32::saturating_add(a[0usize], b[0usize]),
4538            i32::saturating_add(a[1usize], b[1usize]),
4539            i32::saturating_add(a[2usize], b[2usize]),
4540            i32::saturating_add(a[3usize], b[3usize]),
4541        ]
4542        .simd_into(self)
4543    }
4544    #[inline(always)]
4545    fn sub_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4546        crate::kernel!(
4547            #[inline(always)]
4548            fn kernel(token: Sse2, a: i32x4<Sse2>, b: i32x4<Sse2>) -> i32x4<Sse2> {
4549                _mm_sub_epi32(a.into(), b.into()).simd_into(token)
4550            }
4551        );
4552        kernel(self, a, b)
4553    }
4554    #[inline(always)]
4555    fn saturating_sub_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4556        [
4557            i32::saturating_sub(a[0usize], b[0usize]),
4558            i32::saturating_sub(a[1usize], b[1usize]),
4559            i32::saturating_sub(a[2usize], b[2usize]),
4560            i32::saturating_sub(a[3usize], b[3usize]),
4561        ]
4562        .simd_into(self)
4563    }
4564    #[inline(always)]
4565    fn mul_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4566        [
4567            i32::wrapping_mul(a[0usize], b[0usize]),
4568            i32::wrapping_mul(a[1usize], b[1usize]),
4569            i32::wrapping_mul(a[2usize], b[2usize]),
4570            i32::wrapping_mul(a[3usize], b[3usize]),
4571        ]
4572        .simd_into(self)
4573    }
4574    #[inline(always)]
4575    fn and_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4576        crate::kernel!(
4577            #[inline(always)]
4578            fn kernel(token: Sse2, a: i32x4<Sse2>, b: i32x4<Sse2>) -> i32x4<Sse2> {
4579                _mm_and_si128(a.into(), b.into()).simd_into(token)
4580            }
4581        );
4582        kernel(self, a, b)
4583    }
4584    #[inline(always)]
4585    fn or_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4586        crate::kernel!(
4587            #[inline(always)]
4588            fn kernel(token: Sse2, a: i32x4<Sse2>, b: i32x4<Sse2>) -> i32x4<Sse2> {
4589                _mm_or_si128(a.into(), b.into()).simd_into(token)
4590            }
4591        );
4592        kernel(self, a, b)
4593    }
4594    #[inline(always)]
4595    fn xor_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4596        crate::kernel!(
4597            #[inline(always)]
4598            fn kernel(token: Sse2, a: i32x4<Sse2>, b: i32x4<Sse2>) -> i32x4<Sse2> {
4599                _mm_xor_si128(a.into(), b.into()).simd_into(token)
4600            }
4601        );
4602        kernel(self, a, b)
4603    }
4604    #[inline(always)]
4605    fn not_i32x4(self, a: i32x4<Self>) -> i32x4<Self> {
4606        a ^ !0
4607    }
4608    #[inline(always)]
4609    fn shl_i32x4(self, a: i32x4<Self>, shift: u32) -> i32x4<Self> {
4610        crate::kernel!(
4611            #[inline(always)]
4612            fn kernel(token: Sse2, a: i32x4<Sse2>, shift: u32) -> i32x4<Sse2> {
4613                _mm_sll_epi32(a.into(), _mm_cvtsi32_si128(shift.cast_signed())).simd_into(token)
4614            }
4615        );
4616        kernel(self, a, shift)
4617    }
4618    #[inline(always)]
4619    fn shlv_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4620        [
4621            i32::wrapping_shl(a[0usize], b[0usize] as u32),
4622            i32::wrapping_shl(a[1usize], b[1usize] as u32),
4623            i32::wrapping_shl(a[2usize], b[2usize] as u32),
4624            i32::wrapping_shl(a[3usize], b[3usize] as u32),
4625        ]
4626        .simd_into(self)
4627    }
4628    #[inline(always)]
4629    fn shr_i32x4(self, a: i32x4<Self>, shift: u32) -> i32x4<Self> {
4630        crate::kernel!(
4631            #[inline(always)]
4632            fn kernel(token: Sse2, a: i32x4<Sse2>, shift: u32) -> i32x4<Sse2> {
4633                _mm_sra_epi32(a.into(), _mm_cvtsi32_si128(shift.cast_signed())).simd_into(token)
4634            }
4635        );
4636        kernel(self, a, shift)
4637    }
4638    #[inline(always)]
4639    fn shrv_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4640        [
4641            i32::wrapping_shr(a[0usize], b[0usize] as u32),
4642            i32::wrapping_shr(a[1usize], b[1usize] as u32),
4643            i32::wrapping_shr(a[2usize], b[2usize] as u32),
4644            i32::wrapping_shr(a[3usize], b[3usize] as u32),
4645        ]
4646        .simd_into(self)
4647    }
4648    #[inline(always)]
4649    fn reduce_max_i32x4(self, a: i32x4<Self>) -> i32 {
4650        crate::kernel!(
4651            #[inline(always)]
4652            fn kernel(token: Sse2, a: i32x4<Sse2>) -> i32 {
4653                let reduced: __m128i = a.into();
4654                let shifted = _mm_srli_si128::<8>(reduced);
4655                let reduced = {
4656                    {
4657                        let a = reduced;
4658                        let b = shifted;
4659                        let gt = _mm_cmpgt_epi32(a, b);
4660                        _mm_or_si128(_mm_and_si128(gt, a), _mm_andnot_si128(gt, b))
4661                    }
4662                };
4663                let shifted = _mm_srli_si128::<4>(reduced);
4664                let reduced = {
4665                    {
4666                        let a = reduced;
4667                        let b = shifted;
4668                        let gt = _mm_cmpgt_epi32(a, b);
4669                        _mm_or_si128(_mm_and_si128(gt, a), _mm_andnot_si128(gt, b))
4670                    }
4671                };
4672                {
4673                    let lanes: [i32; 4usize] = crate::transmute::checked_transmute_copy(&reduced);
4674                    lanes[0]
4675                }
4676            }
4677        );
4678        kernel(self, a)
4679    }
4680    #[inline(always)]
4681    fn reduce_min_i32x4(self, a: i32x4<Self>) -> i32 {
4682        crate::kernel!(
4683            #[inline(always)]
4684            fn kernel(token: Sse2, a: i32x4<Sse2>) -> i32 {
4685                let reduced: __m128i = a.into();
4686                let shifted = _mm_srli_si128::<8>(reduced);
4687                let reduced = {
4688                    {
4689                        let a = reduced;
4690                        let b = shifted;
4691                        let gt = _mm_cmpgt_epi32(a, b);
4692                        _mm_or_si128(_mm_and_si128(gt, b), _mm_andnot_si128(gt, a))
4693                    }
4694                };
4695                let shifted = _mm_srli_si128::<4>(reduced);
4696                let reduced = {
4697                    {
4698                        let a = reduced;
4699                        let b = shifted;
4700                        let gt = _mm_cmpgt_epi32(a, b);
4701                        _mm_or_si128(_mm_and_si128(gt, b), _mm_andnot_si128(gt, a))
4702                    }
4703                };
4704                {
4705                    let lanes: [i32; 4usize] = crate::transmute::checked_transmute_copy(&reduced);
4706                    lanes[0]
4707                }
4708            }
4709        );
4710        kernel(self, a)
4711    }
4712    #[inline(always)]
4713    fn reduce_sum_i32x4(self, a: i32x4<Self>) -> i32 {
4714        crate::kernel!(
4715            #[inline(always)]
4716            fn kernel(token: Sse2, a: i32x4<Sse2>) -> i32 {
4717                let sum: __m128i = a.into();
4718                let sum = _mm_add_epi32(sum, _mm_srli_si128::<8>(sum));
4719                let sum = _mm_add_epi32(sum, _mm_srli_si128::<4>(sum));
4720                let lanes: [i32; 4usize] = crate::transmute::checked_transmute_copy(&sum);
4721                lanes[0]
4722            }
4723        );
4724        kernel(self, a)
4725    }
4726    #[inline(always)]
4727    fn reduce_product_i32x4(self, a: i32x4<Self>) -> i32 {
4728        let mul_level_0: [i32; 2usize] = [
4729            a[0usize].wrapping_mul(a[1usize]),
4730            a[2usize].wrapping_mul(a[3usize]),
4731        ];
4732        let mul_level_1: [i32; 1usize] = [mul_level_0[0usize].wrapping_mul(mul_level_0[1usize])];
4733        mul_level_1[0]
4734    }
4735    #[inline(always)]
4736    fn max_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4737        crate::kernel!(
4738            #[inline(always)]
4739            fn kernel(token: Sse2, a: i32x4<Sse2>, b: i32x4<Sse2>) -> i32x4<Sse2> {
4740                {
4741                    let a = a.into();
4742                    let b = b.into();
4743                    let gt = _mm_cmpgt_epi32(a, b);
4744                    _mm_or_si128(_mm_and_si128(gt, a), _mm_andnot_si128(gt, b))
4745                }
4746                .simd_into(token)
4747            }
4748        );
4749        kernel(self, a, b)
4750    }
4751    #[inline(always)]
4752    fn min_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4753        crate::kernel!(
4754            #[inline(always)]
4755            fn kernel(token: Sse2, a: i32x4<Sse2>, b: i32x4<Sse2>) -> i32x4<Sse2> {
4756                {
4757                    let a = a.into();
4758                    let b = b.into();
4759                    let gt = _mm_cmpgt_epi32(a, b);
4760                    _mm_or_si128(_mm_and_si128(gt, b), _mm_andnot_si128(gt, a))
4761                }
4762                .simd_into(token)
4763            }
4764        );
4765        kernel(self, a, b)
4766    }
4767    #[inline(always)]
4768    fn clamp_i32x4(self, a: i32x4<Self>, b: i32x4<Self>, c: i32x4<Self>) -> i32x4<Self> {
4769        debug_assert!(
4770            b.simd_le(c).all_true(),
4771            "clamp requires min <= max for all elements"
4772        );
4773        a.max(b).min(c)
4774    }
4775    #[inline(always)]
4776    fn simd_eq_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> mask32x4<Self> {
4777        crate::kernel!(
4778            #[inline(always)]
4779            fn kernel(token: Sse2, a: i32x4<Sse2>, b: i32x4<Sse2>) -> mask32x4<Sse2> {
4780                _mm_cmpeq_epi32(a.into(), b.into()).simd_into(token)
4781            }
4782        );
4783        kernel(self, a, b)
4784    }
4785    #[inline(always)]
4786    fn simd_lt_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> mask32x4<Self> {
4787        crate::kernel!(
4788            #[inline(always)]
4789            fn kernel(token: Sse2, a: i32x4<Sse2>, b: i32x4<Sse2>) -> mask32x4<Sse2> {
4790                _mm_cmpgt_epi32(b.into(), a.into()).simd_into(token)
4791            }
4792        );
4793        kernel(self, a, b)
4794    }
4795    #[inline(always)]
4796    fn simd_le_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> mask32x4<Self> {
4797        crate::kernel!(
4798            #[inline(always)]
4799            fn kernel(token: Sse2, a: i32x4<Sse2>, b: i32x4<Sse2>) -> mask32x4<Sse2> {
4800                {
4801                    let all_ones = _mm_set1_epi8(-1);
4802                    _mm_xor_si128(_mm_cmpgt_epi32(a.into(), b.into()), all_ones)
4803                }
4804                .simd_into(token)
4805            }
4806        );
4807        kernel(self, a, b)
4808    }
4809    #[inline(always)]
4810    fn zip_low_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4811        crate::kernel!(
4812            #[inline(always)]
4813            fn kernel(token: Sse2, a: i32x4<Sse2>, b: i32x4<Sse2>) -> i32x4<Sse2> {
4814                _mm_unpacklo_epi32(a.into(), b.into()).simd_into(token)
4815            }
4816        );
4817        kernel(self, a, b)
4818    }
4819    #[inline(always)]
4820    fn zip_high_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4821        crate::kernel!(
4822            #[inline(always)]
4823            fn kernel(token: Sse2, a: i32x4<Sse2>, b: i32x4<Sse2>) -> i32x4<Sse2> {
4824                _mm_unpackhi_epi32(a.into(), b.into()).simd_into(token)
4825            }
4826        );
4827        kernel(self, a, b)
4828    }
4829    #[inline(always)]
4830    fn unzip_low_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4831        crate::kernel!(
4832            #[inline(always)]
4833            fn kernel(token: Sse2, a: i32x4<Sse2>, b: i32x4<Sse2>) -> i32x4<Sse2> {
4834                let t1 = _mm_shuffle_epi32::<0b11_01_10_00>(a.into());
4835                let t2 = _mm_shuffle_epi32::<0b11_01_10_00>(b.into());
4836                _mm_unpacklo_epi64(t1, t2).simd_into(token)
4837            }
4838        );
4839        kernel(self, a, b)
4840    }
4841    #[inline(always)]
4842    fn unzip_high_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self> {
4843        crate::kernel!(
4844            #[inline(always)]
4845            fn kernel(token: Sse2, a: i32x4<Sse2>, b: i32x4<Sse2>) -> i32x4<Sse2> {
4846                let t1 = _mm_shuffle_epi32::<0b11_01_10_00>(a.into());
4847                let t2 = _mm_shuffle_epi32::<0b11_01_10_00>(b.into());
4848                _mm_unpackhi_epi64(t1, t2).simd_into(token)
4849            }
4850        );
4851        kernel(self, a, b)
4852    }
4853    #[inline(always)]
4854    fn interleave_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> (i32x4<Self>, i32x4<Self>) {
4855        (self.zip_low_i32x4(a, b), self.zip_high_i32x4(a, b))
4856    }
4857    #[inline(always)]
4858    fn deinterleave_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> (i32x4<Self>, i32x4<Self>) {
4859        (self.unzip_low_i32x4(a, b), self.unzip_high_i32x4(a, b))
4860    }
4861    #[inline(always)]
4862    fn select_i32x4(self, a: mask32x4<Self>, b: i32x4<Self>, c: i32x4<Self>) -> i32x4<Self> {
4863        crate::kernel!(
4864            #[inline(always)]
4865            fn kernel(
4866                token: Sse2,
4867                a: mask32x4<Sse2>,
4868                b: i32x4<Sse2>,
4869                c: i32x4<Sse2>,
4870            ) -> i32x4<Sse2> {
4871                _mm_or_si128(
4872                    _mm_and_si128(a.into(), b.into()),
4873                    _mm_andnot_si128(a.into(), c.into()),
4874                )
4875                .simd_into(token)
4876            }
4877        );
4878        kernel(self, a, b, c)
4879    }
4880    #[inline(always)]
4881    fn combine_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x8<Self> {
4882        i32x8 {
4883            val: crate::support::Aligned256([a.val.0, b.val.0]),
4884            simd: self,
4885        }
4886    }
4887    #[inline(always)]
4888    fn neg_i32x4(self, a: i32x4<Self>) -> i32x4<Self> {
4889        crate::kernel!(
4890            #[inline(always)]
4891            fn kernel(token: Sse2, a: i32x4<Sse2>) -> i32x4<Sse2> {
4892                _mm_sub_epi32(_mm_setzero_si128(), a.into()).simd_into(token)
4893            }
4894        );
4895        kernel(self, a)
4896    }
4897    #[inline(always)]
4898    fn load_four_interleaved_i32x4(self, src: &[i32; 16usize]) -> [i32x4<Self>; 4usize] {
4899        crate::kernel!(
4900            #[inline(always)]
4901            fn kernel(token: Sse2, src: &[i32; 16usize]) -> [i32x4<Sse2>; 4usize] {
4902                let (chunks, []) = src.as_chunks::<4usize>() else {
4903                    unreachable!()
4904                };
4905                let v0: __m128i =
4906                    crate::transmute::checked_transmute_copy::<[i32; 4usize], __m128i>(&chunks[0]);
4907                let v1: __m128i =
4908                    crate::transmute::checked_transmute_copy::<[i32; 4usize], __m128i>(&chunks[1]);
4909                let v2: __m128i =
4910                    crate::transmute::checked_transmute_copy::<[i32; 4usize], __m128i>(&chunks[2]);
4911                let v3: __m128i =
4912                    crate::transmute::checked_transmute_copy::<[i32; 4usize], __m128i>(&chunks[3]);
4913                let tmp0 = _mm_unpacklo_epi32(v0, v1);
4914                let tmp1 = _mm_unpackhi_epi32(v0, v1);
4915                let tmp2 = _mm_unpacklo_epi32(v2, v3);
4916                let tmp3 = _mm_unpackhi_epi32(v2, v3);
4917                let out0 = _mm_unpacklo_epi64(tmp0, tmp2);
4918                let out1 = _mm_unpackhi_epi64(tmp0, tmp2);
4919                let out2 = _mm_unpacklo_epi64(tmp1, tmp3);
4920                let out3 = _mm_unpackhi_epi64(tmp1, tmp3);
4921                [
4922                    out0.simd_into(token),
4923                    out1.simd_into(token),
4924                    out2.simd_into(token),
4925                    out3.simd_into(token),
4926                ]
4927            }
4928        );
4929        kernel(self, src)
4930    }
4931    #[inline(always)]
4932    fn store_four_interleaved_i32x4(
4933        self,
4934        vectors: [i32x4<Self>; 4usize],
4935        dest: &mut [i32; 16usize],
4936    ) -> () {
4937        crate::kernel!(
4938            #[inline(always)]
4939            fn kernel(
4940                token: Sse2,
4941                vectors: [i32x4<Sse2>; 4usize],
4942                dest: &mut [i32; 16usize],
4943            ) -> () {
4944                let _ = token;
4945                let v0: __m128i = vectors[0].into();
4946                let v1: __m128i = vectors[1].into();
4947                let v2: __m128i = vectors[2].into();
4948                let v3: __m128i = vectors[3].into();
4949                let tmp0 = _mm_unpacklo_epi32(v0, v1);
4950                let tmp1 = _mm_unpackhi_epi32(v0, v1);
4951                let tmp2 = _mm_unpacklo_epi32(v2, v3);
4952                let tmp3 = _mm_unpackhi_epi32(v2, v3);
4953                let out0 = _mm_unpacklo_epi64(tmp0, tmp2);
4954                let out1 = _mm_unpackhi_epi64(tmp0, tmp2);
4955                let out2 = _mm_unpacklo_epi64(tmp1, tmp3);
4956                let out3 = _mm_unpackhi_epi64(tmp1, tmp3);
4957                let (chunks, []) = dest.as_chunks_mut::<4usize>() else {
4958                    unreachable!()
4959                };
4960                crate::transmute::checked_transmute_store::<__m128i, [i32; 4usize]>(
4961                    out0,
4962                    &mut chunks[0],
4963                );
4964                crate::transmute::checked_transmute_store::<__m128i, [i32; 4usize]>(
4965                    out1,
4966                    &mut chunks[1],
4967                );
4968                crate::transmute::checked_transmute_store::<__m128i, [i32; 4usize]>(
4969                    out2,
4970                    &mut chunks[2],
4971                );
4972                crate::transmute::checked_transmute_store::<__m128i, [i32; 4usize]>(
4973                    out3,
4974                    &mut chunks[3],
4975                );
4976            }
4977        );
4978        kernel(self, vectors, dest);
4979    }
4980    #[inline(always)]
4981    fn widen_i32x4(self, a: i32x4<Self>) -> (i64x2<Self>, i64x2<Self>) {
4982        crate::kernel!(
4983            #[inline(always)]
4984            fn kernel(token: Sse2, a: i32x4<Sse2>) -> (i64x2<Sse2>, i64x2<Sse2>) {
4985                let raw = a.into();
4986                let sign = _mm_srai_epi32::<31>(raw);
4987                (
4988                    _mm_unpacklo_epi32(raw, sign).simd_into(token),
4989                    _mm_unpackhi_epi32(raw, sign).simd_into(token),
4990                )
4991            }
4992        );
4993        kernel(self, a)
4994    }
4995    #[inline(always)]
4996    fn widening_mul_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> (i64x2<Self>, i64x2<Self>) {
4997        let (a0, a1) = self.widen_i32x4(a);
4998        let (b0, b1) = self.widen_i32x4(b);
4999        (self.mul_i64x2(a0, b0), self.mul_i64x2(a1, b1))
5000    }
5001    #[inline(always)]
5002    fn widening_add_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> (i64x2<Self>, i64x2<Self>) {
5003        let (a0, a1) = self.widen_i32x4(a);
5004        let (b0, b1) = self.widen_i32x4(b);
5005        (self.add_i64x2(a0, b0), self.add_i64x2(a1, b1))
5006    }
5007    #[inline(always)]
5008    fn pairwise_widening_add_i32x4(self, a: i32x4<Self>) -> i64x2<Self> {
5009        crate::kernel!(
5010            #[inline(always)]
5011            fn kernel(token: Sse2, a: i32x4<Sse2>) -> i64x2<Sse2> {
5012                ({
5013                    let y = _mm_xor_si128(a.into(), _mm_set1_epi32(i32::MIN));
5014                    _mm_add_epi64(
5015                        _mm_or_si128(y, _mm_set1_epi64x(-0x1_0000_0000)),
5016                        _mm_srli_epi64::<32>(y),
5017                    )
5018                })
5019                .simd_into(token)
5020            }
5021        );
5022        kernel(self, a)
5023    }
5024    #[inline(always)]
5025    fn pairwise_dot_product_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i64x2<Self> {
5026        let (low, high) = self.widening_mul_i32x4(a, b);
5027        let (even, odd) = self.deinterleave_i64x2(low, high);
5028        self.add_i64x2(even, odd)
5029    }
5030    #[inline(always)]
5031    fn narrow_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i16x8<Self> {
5032        [
5033            a[0usize] as i16,
5034            a[1usize] as i16,
5035            a[2usize] as i16,
5036            a[3usize] as i16,
5037            b[0usize] as i16,
5038            b[1usize] as i16,
5039            b[2usize] as i16,
5040            b[3usize] as i16,
5041        ]
5042        .simd_into(self)
5043    }
5044    #[inline(always)]
5045    fn saturating_narrow_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i16x8<Self> {
5046        crate::kernel!(
5047            #[inline(always)]
5048            fn kernel(token: Sse2, a: i32x4<Sse2>, b: i32x4<Sse2>) -> i16x8<Sse2> {
5049                _mm_packs_epi32(a.into(), b.into()).simd_into(token)
5050            }
5051        );
5052        kernel(self, a, b)
5053    }
5054    #[inline(always)]
5055    fn relaxed_narrow_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i16x8<Self> {
5056        debug_assert!(
5057            a.as_slice()
5058                .iter()
5059                .chain(b.as_slice())
5060                .all(|&value| { value >= i16::MIN as i32 && value <= i16::MAX as i32 }),
5061            "relaxed_narrow inputs must fit in the destination type",
5062        );
5063        self.saturating_narrow_i32x4(a, b)
5064    }
5065    #[inline(always)]
5066    fn cvt_f32_i32x4(self, a: i32x4<Self>) -> f32x4<Self> {
5067        crate::kernel!(
5068            #[inline(always)]
5069            fn kernel(token: Sse2, a: i32x4<Sse2>) -> f32x4<Sse2> {
5070                _mm_cvtepi32_ps(a.into()).simd_into(token)
5071            }
5072        );
5073        kernel(self, a)
5074    }
5075    #[inline(always)]
5076    fn splat_u32x4(self, val: u32) -> u32x4<Self> {
5077        crate::kernel!(
5078            #[inline(always)]
5079            fn kernel(token: Sse2, val: u32) -> u32x4<Sse2> {
5080                _mm_set1_epi32(val.cast_signed()).simd_into(token)
5081            }
5082        );
5083        kernel(self, val)
5084    }
5085    #[inline(always)]
5086    fn reverse_u32x4(self, a: u32x4<Self>) -> u32x4<Self> {
5087        [a[3usize], a[2usize], a[1usize], a[0usize]].simd_into(self)
5088    }
5089    #[inline(always)]
5090    fn slide_u32x4<const SHIFT: usize>(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5091        if SHIFT >= 4usize {
5092            return b;
5093        }
5094        let result = dyn_alignr_128(
5095            self,
5096            Bytes::to_bytes(b).val.0,
5097            Bytes::to_bytes(a).val.0,
5098            SHIFT * 4usize,
5099        );
5100        Bytes::from_bytes(u8x16 {
5101            val: crate::support::Aligned128(result),
5102            simd: self,
5103        })
5104    }
5105    #[inline(always)]
5106    fn compress_u32x4(self, values: u32x4<Self>, mask: mask32x4<Self>) -> u32x4<Self> {
5107        let mask = mask8x16 {
5108            val: crate::transmute::checked_transmute_copy(&mask.val),
5109            simd: self,
5110        };
5111        Bytes::from_bytes(self.compress_u8x16(Bytes::to_bytes(values), mask))
5112    }
5113    #[inline(always)]
5114    fn compress_merge_u32x4(
5115        self,
5116        values: u32x4<Self>,
5117        mask: mask32x4<Self>,
5118        merge: u32x4<Self>,
5119    ) -> u32x4<Self> {
5120        let mask = mask8x16 {
5121            val: crate::transmute::checked_transmute_copy(&mask.val),
5122            simd: self,
5123        };
5124        Bytes::from_bytes(self.compress_merge_u8x16(
5125            Bytes::to_bytes(values),
5126            mask,
5127            Bytes::to_bytes(merge),
5128        ))
5129    }
5130    #[inline(always)]
5131    fn expand_u32x4(self, values: u32x4<Self>, mask: mask32x4<Self>) -> u32x4<Self> {
5132        let mask = mask8x16 {
5133            val: crate::transmute::checked_transmute_copy(&mask.val),
5134            simd: self,
5135        };
5136        Bytes::from_bytes(self.expand_u8x16(Bytes::to_bytes(values), mask))
5137    }
5138    #[inline(always)]
5139    fn expand_merge_u32x4(
5140        self,
5141        values: u32x4<Self>,
5142        mask: mask32x4<Self>,
5143        merge: u32x4<Self>,
5144    ) -> u32x4<Self> {
5145        let mask = mask8x16 {
5146            val: crate::transmute::checked_transmute_copy(&mask.val),
5147            simd: self,
5148        };
5149        Bytes::from_bytes(self.expand_merge_u8x16(
5150            Bytes::to_bytes(values),
5151            mask,
5152            Bytes::to_bytes(merge),
5153        ))
5154    }
5155    #[inline(always)]
5156    fn count_ones_u32x4(self, a: u32x4<Self>) -> u32x4<Self> {
5157        [
5158            a[0usize].count_ones(),
5159            a[1usize].count_ones(),
5160            a[2usize].count_ones(),
5161            a[3usize].count_ones(),
5162        ]
5163        .simd_into(self)
5164    }
5165    #[inline(always)]
5166    fn count_zeros_u32x4(self, a: u32x4<Self>) -> u32x4<Self> {
5167        [
5168            a[0usize].count_zeros(),
5169            a[1usize].count_zeros(),
5170            a[2usize].count_zeros(),
5171            a[3usize].count_zeros(),
5172        ]
5173        .simd_into(self)
5174    }
5175    #[inline(always)]
5176    fn add_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5177        crate::kernel!(
5178            #[inline(always)]
5179            fn kernel(token: Sse2, a: u32x4<Sse2>, b: u32x4<Sse2>) -> u32x4<Sse2> {
5180                _mm_add_epi32(a.into(), b.into()).simd_into(token)
5181            }
5182        );
5183        kernel(self, a, b)
5184    }
5185    #[inline(always)]
5186    fn saturating_add_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5187        [
5188            u32::saturating_add(a[0usize], b[0usize]),
5189            u32::saturating_add(a[1usize], b[1usize]),
5190            u32::saturating_add(a[2usize], b[2usize]),
5191            u32::saturating_add(a[3usize], b[3usize]),
5192        ]
5193        .simd_into(self)
5194    }
5195    #[inline(always)]
5196    fn sub_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5197        crate::kernel!(
5198            #[inline(always)]
5199            fn kernel(token: Sse2, a: u32x4<Sse2>, b: u32x4<Sse2>) -> u32x4<Sse2> {
5200                _mm_sub_epi32(a.into(), b.into()).simd_into(token)
5201            }
5202        );
5203        kernel(self, a, b)
5204    }
5205    #[inline(always)]
5206    fn saturating_sub_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5207        [
5208            u32::saturating_sub(a[0usize], b[0usize]),
5209            u32::saturating_sub(a[1usize], b[1usize]),
5210            u32::saturating_sub(a[2usize], b[2usize]),
5211            u32::saturating_sub(a[3usize], b[3usize]),
5212        ]
5213        .simd_into(self)
5214    }
5215    #[inline(always)]
5216    fn mul_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5217        [
5218            u32::wrapping_mul(a[0usize], b[0usize]),
5219            u32::wrapping_mul(a[1usize], b[1usize]),
5220            u32::wrapping_mul(a[2usize], b[2usize]),
5221            u32::wrapping_mul(a[3usize], b[3usize]),
5222        ]
5223        .simd_into(self)
5224    }
5225    #[inline(always)]
5226    fn and_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5227        crate::kernel!(
5228            #[inline(always)]
5229            fn kernel(token: Sse2, a: u32x4<Sse2>, b: u32x4<Sse2>) -> u32x4<Sse2> {
5230                _mm_and_si128(a.into(), b.into()).simd_into(token)
5231            }
5232        );
5233        kernel(self, a, b)
5234    }
5235    #[inline(always)]
5236    fn or_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5237        crate::kernel!(
5238            #[inline(always)]
5239            fn kernel(token: Sse2, a: u32x4<Sse2>, b: u32x4<Sse2>) -> u32x4<Sse2> {
5240                _mm_or_si128(a.into(), b.into()).simd_into(token)
5241            }
5242        );
5243        kernel(self, a, b)
5244    }
5245    #[inline(always)]
5246    fn xor_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5247        crate::kernel!(
5248            #[inline(always)]
5249            fn kernel(token: Sse2, a: u32x4<Sse2>, b: u32x4<Sse2>) -> u32x4<Sse2> {
5250                _mm_xor_si128(a.into(), b.into()).simd_into(token)
5251            }
5252        );
5253        kernel(self, a, b)
5254    }
5255    #[inline(always)]
5256    fn not_u32x4(self, a: u32x4<Self>) -> u32x4<Self> {
5257        a ^ !0
5258    }
5259    #[inline(always)]
5260    fn shl_u32x4(self, a: u32x4<Self>, shift: u32) -> u32x4<Self> {
5261        crate::kernel!(
5262            #[inline(always)]
5263            fn kernel(token: Sse2, a: u32x4<Sse2>, shift: u32) -> u32x4<Sse2> {
5264                _mm_sll_epi32(a.into(), _mm_cvtsi32_si128(shift.cast_signed())).simd_into(token)
5265            }
5266        );
5267        kernel(self, a, shift)
5268    }
5269    #[inline(always)]
5270    fn shlv_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5271        [
5272            u32::wrapping_shl(a[0usize], b[0usize] as u32),
5273            u32::wrapping_shl(a[1usize], b[1usize] as u32),
5274            u32::wrapping_shl(a[2usize], b[2usize] as u32),
5275            u32::wrapping_shl(a[3usize], b[3usize] as u32),
5276        ]
5277        .simd_into(self)
5278    }
5279    #[inline(always)]
5280    fn shr_u32x4(self, a: u32x4<Self>, shift: u32) -> u32x4<Self> {
5281        crate::kernel!(
5282            #[inline(always)]
5283            fn kernel(token: Sse2, a: u32x4<Sse2>, shift: u32) -> u32x4<Sse2> {
5284                _mm_srl_epi32(a.into(), _mm_cvtsi32_si128(shift.cast_signed())).simd_into(token)
5285            }
5286        );
5287        kernel(self, a, shift)
5288    }
5289    #[inline(always)]
5290    fn shrv_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5291        [
5292            u32::wrapping_shr(a[0usize], b[0usize] as u32),
5293            u32::wrapping_shr(a[1usize], b[1usize] as u32),
5294            u32::wrapping_shr(a[2usize], b[2usize] as u32),
5295            u32::wrapping_shr(a[3usize], b[3usize] as u32),
5296        ]
5297        .simd_into(self)
5298    }
5299    #[inline(always)]
5300    fn reduce_max_u32x4(self, a: u32x4<Self>) -> u32 {
5301        crate::kernel!(
5302            #[inline(always)]
5303            fn kernel(token: Sse2, a: u32x4<Sse2>) -> u32 {
5304                let reduced: __m128i = a.into();
5305                let shifted = _mm_srli_si128::<8>(reduced);
5306                let reduced = {
5307                    {
5308                        let a = reduced;
5309                        let b = shifted;
5310                        let gt = {
5311                            let sign_bit = _mm_set1_epi32(0x80000000u32.cast_signed());
5312                            let lhs_signed = _mm_xor_si128(a, sign_bit);
5313                            let rhs_signed = _mm_xor_si128(b, sign_bit);
5314                            _mm_cmpgt_epi32(lhs_signed, rhs_signed)
5315                        };
5316                        _mm_or_si128(_mm_and_si128(gt, a), _mm_andnot_si128(gt, b))
5317                    }
5318                };
5319                let shifted = _mm_srli_si128::<4>(reduced);
5320                let reduced = {
5321                    {
5322                        let a = reduced;
5323                        let b = shifted;
5324                        let gt = {
5325                            let sign_bit = _mm_set1_epi32(0x80000000u32.cast_signed());
5326                            let lhs_signed = _mm_xor_si128(a, sign_bit);
5327                            let rhs_signed = _mm_xor_si128(b, sign_bit);
5328                            _mm_cmpgt_epi32(lhs_signed, rhs_signed)
5329                        };
5330                        _mm_or_si128(_mm_and_si128(gt, a), _mm_andnot_si128(gt, b))
5331                    }
5332                };
5333                {
5334                    let lanes: [u32; 4usize] = crate::transmute::checked_transmute_copy(&reduced);
5335                    lanes[0]
5336                }
5337            }
5338        );
5339        kernel(self, a)
5340    }
5341    #[inline(always)]
5342    fn reduce_min_u32x4(self, a: u32x4<Self>) -> u32 {
5343        crate::kernel!(
5344            #[inline(always)]
5345            fn kernel(token: Sse2, a: u32x4<Sse2>) -> u32 {
5346                let reduced: __m128i = a.into();
5347                let shifted = _mm_srli_si128::<8>(reduced);
5348                let reduced = {
5349                    {
5350                        let a = reduced;
5351                        let b = shifted;
5352                        let gt = {
5353                            let sign_bit = _mm_set1_epi32(0x80000000u32.cast_signed());
5354                            let lhs_signed = _mm_xor_si128(a, sign_bit);
5355                            let rhs_signed = _mm_xor_si128(b, sign_bit);
5356                            _mm_cmpgt_epi32(lhs_signed, rhs_signed)
5357                        };
5358                        _mm_or_si128(_mm_and_si128(gt, b), _mm_andnot_si128(gt, a))
5359                    }
5360                };
5361                let shifted = _mm_srli_si128::<4>(reduced);
5362                let reduced = {
5363                    {
5364                        let a = reduced;
5365                        let b = shifted;
5366                        let gt = {
5367                            let sign_bit = _mm_set1_epi32(0x80000000u32.cast_signed());
5368                            let lhs_signed = _mm_xor_si128(a, sign_bit);
5369                            let rhs_signed = _mm_xor_si128(b, sign_bit);
5370                            _mm_cmpgt_epi32(lhs_signed, rhs_signed)
5371                        };
5372                        _mm_or_si128(_mm_and_si128(gt, b), _mm_andnot_si128(gt, a))
5373                    }
5374                };
5375                {
5376                    let lanes: [u32; 4usize] = crate::transmute::checked_transmute_copy(&reduced);
5377                    lanes[0]
5378                }
5379            }
5380        );
5381        kernel(self, a)
5382    }
5383    #[inline(always)]
5384    fn reduce_sum_u32x4(self, a: u32x4<Self>) -> u32 {
5385        crate::kernel!(
5386            #[inline(always)]
5387            fn kernel(token: Sse2, a: u32x4<Sse2>) -> u32 {
5388                let sum: __m128i = a.into();
5389                let sum = _mm_add_epi32(sum, _mm_srli_si128::<8>(sum));
5390                let sum = _mm_add_epi32(sum, _mm_srli_si128::<4>(sum));
5391                let lanes: [u32; 4usize] = crate::transmute::checked_transmute_copy(&sum);
5392                lanes[0]
5393            }
5394        );
5395        kernel(self, a)
5396    }
5397    #[inline(always)]
5398    fn reduce_product_u32x4(self, a: u32x4<Self>) -> u32 {
5399        let mul_level_0: [u32; 2usize] = [
5400            a[0usize].wrapping_mul(a[1usize]),
5401            a[2usize].wrapping_mul(a[3usize]),
5402        ];
5403        let mul_level_1: [u32; 1usize] = [mul_level_0[0usize].wrapping_mul(mul_level_0[1usize])];
5404        mul_level_1[0]
5405    }
5406    #[inline(always)]
5407    fn max_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5408        crate::kernel!(
5409            #[inline(always)]
5410            fn kernel(token: Sse2, a: u32x4<Sse2>, b: u32x4<Sse2>) -> u32x4<Sse2> {
5411                {
5412                    let a = a.into();
5413                    let b = b.into();
5414                    let gt = {
5415                        let sign_bit = _mm_set1_epi32(0x80000000u32.cast_signed());
5416                        let lhs_signed = _mm_xor_si128(a, sign_bit);
5417                        let rhs_signed = _mm_xor_si128(b, sign_bit);
5418                        _mm_cmpgt_epi32(lhs_signed, rhs_signed)
5419                    };
5420                    _mm_or_si128(_mm_and_si128(gt, a), _mm_andnot_si128(gt, b))
5421                }
5422                .simd_into(token)
5423            }
5424        );
5425        kernel(self, a, b)
5426    }
5427    #[inline(always)]
5428    fn min_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5429        crate::kernel!(
5430            #[inline(always)]
5431            fn kernel(token: Sse2, a: u32x4<Sse2>, b: u32x4<Sse2>) -> u32x4<Sse2> {
5432                {
5433                    let a = a.into();
5434                    let b = b.into();
5435                    let gt = {
5436                        let sign_bit = _mm_set1_epi32(0x80000000u32.cast_signed());
5437                        let lhs_signed = _mm_xor_si128(a, sign_bit);
5438                        let rhs_signed = _mm_xor_si128(b, sign_bit);
5439                        _mm_cmpgt_epi32(lhs_signed, rhs_signed)
5440                    };
5441                    _mm_or_si128(_mm_and_si128(gt, b), _mm_andnot_si128(gt, a))
5442                }
5443                .simd_into(token)
5444            }
5445        );
5446        kernel(self, a, b)
5447    }
5448    #[inline(always)]
5449    fn clamp_u32x4(self, a: u32x4<Self>, b: u32x4<Self>, c: u32x4<Self>) -> u32x4<Self> {
5450        debug_assert!(
5451            b.simd_le(c).all_true(),
5452            "clamp requires min <= max for all elements"
5453        );
5454        a.max(b).min(c)
5455    }
5456    #[inline(always)]
5457    fn simd_eq_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> mask32x4<Self> {
5458        crate::kernel!(
5459            #[inline(always)]
5460            fn kernel(token: Sse2, a: u32x4<Sse2>, b: u32x4<Sse2>) -> mask32x4<Sse2> {
5461                _mm_cmpeq_epi32(a.into(), b.into()).simd_into(token)
5462            }
5463        );
5464        kernel(self, a, b)
5465    }
5466    #[inline(always)]
5467    fn simd_lt_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> mask32x4<Self> {
5468        crate::kernel!(
5469            #[inline(always)]
5470            fn kernel(token: Sse2, a: u32x4<Sse2>, b: u32x4<Sse2>) -> mask32x4<Sse2> {
5471                {
5472                    let sign_bit = _mm_set1_epi32(0x80000000u32.cast_signed());
5473                    let lhs_signed = _mm_xor_si128(b.into(), sign_bit);
5474                    let rhs_signed = _mm_xor_si128(a.into(), sign_bit);
5475                    _mm_cmpgt_epi32(lhs_signed, rhs_signed)
5476                }
5477                .simd_into(token)
5478            }
5479        );
5480        kernel(self, a, b)
5481    }
5482    #[inline(always)]
5483    fn simd_le_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> mask32x4<Self> {
5484        crate::kernel!(
5485            #[inline(always)]
5486            fn kernel(token: Sse2, a: u32x4<Sse2>, b: u32x4<Sse2>) -> mask32x4<Sse2> {
5487                {
5488                    let all_ones = _mm_set1_epi8(-1);
5489                    _mm_xor_si128(
5490                        {
5491                            let sign_bit = _mm_set1_epi32(0x80000000u32.cast_signed());
5492                            let lhs_signed = _mm_xor_si128(a.into(), sign_bit);
5493                            let rhs_signed = _mm_xor_si128(b.into(), sign_bit);
5494                            _mm_cmpgt_epi32(lhs_signed, rhs_signed)
5495                        },
5496                        all_ones,
5497                    )
5498                }
5499                .simd_into(token)
5500            }
5501        );
5502        kernel(self, a, b)
5503    }
5504    #[inline(always)]
5505    fn zip_low_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5506        crate::kernel!(
5507            #[inline(always)]
5508            fn kernel(token: Sse2, a: u32x4<Sse2>, b: u32x4<Sse2>) -> u32x4<Sse2> {
5509                _mm_unpacklo_epi32(a.into(), b.into()).simd_into(token)
5510            }
5511        );
5512        kernel(self, a, b)
5513    }
5514    #[inline(always)]
5515    fn zip_high_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5516        crate::kernel!(
5517            #[inline(always)]
5518            fn kernel(token: Sse2, a: u32x4<Sse2>, b: u32x4<Sse2>) -> u32x4<Sse2> {
5519                _mm_unpackhi_epi32(a.into(), b.into()).simd_into(token)
5520            }
5521        );
5522        kernel(self, a, b)
5523    }
5524    #[inline(always)]
5525    fn unzip_low_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5526        crate::kernel!(
5527            #[inline(always)]
5528            fn kernel(token: Sse2, a: u32x4<Sse2>, b: u32x4<Sse2>) -> u32x4<Sse2> {
5529                let t1 = _mm_shuffle_epi32::<0b11_01_10_00>(a.into());
5530                let t2 = _mm_shuffle_epi32::<0b11_01_10_00>(b.into());
5531                _mm_unpacklo_epi64(t1, t2).simd_into(token)
5532            }
5533        );
5534        kernel(self, a, b)
5535    }
5536    #[inline(always)]
5537    fn unzip_high_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self> {
5538        crate::kernel!(
5539            #[inline(always)]
5540            fn kernel(token: Sse2, a: u32x4<Sse2>, b: u32x4<Sse2>) -> u32x4<Sse2> {
5541                let t1 = _mm_shuffle_epi32::<0b11_01_10_00>(a.into());
5542                let t2 = _mm_shuffle_epi32::<0b11_01_10_00>(b.into());
5543                _mm_unpackhi_epi64(t1, t2).simd_into(token)
5544            }
5545        );
5546        kernel(self, a, b)
5547    }
5548    #[inline(always)]
5549    fn interleave_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> (u32x4<Self>, u32x4<Self>) {
5550        (self.zip_low_u32x4(a, b), self.zip_high_u32x4(a, b))
5551    }
5552    #[inline(always)]
5553    fn deinterleave_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> (u32x4<Self>, u32x4<Self>) {
5554        (self.unzip_low_u32x4(a, b), self.unzip_high_u32x4(a, b))
5555    }
5556    #[inline(always)]
5557    fn select_u32x4(self, a: mask32x4<Self>, b: u32x4<Self>, c: u32x4<Self>) -> u32x4<Self> {
5558        crate::kernel!(
5559            #[inline(always)]
5560            fn kernel(
5561                token: Sse2,
5562                a: mask32x4<Sse2>,
5563                b: u32x4<Sse2>,
5564                c: u32x4<Sse2>,
5565            ) -> u32x4<Sse2> {
5566                _mm_or_si128(
5567                    _mm_and_si128(a.into(), b.into()),
5568                    _mm_andnot_si128(a.into(), c.into()),
5569                )
5570                .simd_into(token)
5571            }
5572        );
5573        kernel(self, a, b, c)
5574    }
5575    #[inline(always)]
5576    fn combine_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x8<Self> {
5577        u32x8 {
5578            val: crate::support::Aligned256([a.val.0, b.val.0]),
5579            simd: self,
5580        }
5581    }
5582    #[inline(always)]
5583    fn load_four_interleaved_u32x4(self, src: &[u32; 16usize]) -> [u32x4<Self>; 4usize] {
5584        crate::kernel!(
5585            #[inline(always)]
5586            fn kernel(token: Sse2, src: &[u32; 16usize]) -> [u32x4<Sse2>; 4usize] {
5587                let (chunks, []) = src.as_chunks::<4usize>() else {
5588                    unreachable!()
5589                };
5590                let v0: __m128i =
5591                    crate::transmute::checked_transmute_copy::<[u32; 4usize], __m128i>(&chunks[0]);
5592                let v1: __m128i =
5593                    crate::transmute::checked_transmute_copy::<[u32; 4usize], __m128i>(&chunks[1]);
5594                let v2: __m128i =
5595                    crate::transmute::checked_transmute_copy::<[u32; 4usize], __m128i>(&chunks[2]);
5596                let v3: __m128i =
5597                    crate::transmute::checked_transmute_copy::<[u32; 4usize], __m128i>(&chunks[3]);
5598                let tmp0 = _mm_unpacklo_epi32(v0, v1);
5599                let tmp1 = _mm_unpackhi_epi32(v0, v1);
5600                let tmp2 = _mm_unpacklo_epi32(v2, v3);
5601                let tmp3 = _mm_unpackhi_epi32(v2, v3);
5602                let out0 = _mm_unpacklo_epi64(tmp0, tmp2);
5603                let out1 = _mm_unpackhi_epi64(tmp0, tmp2);
5604                let out2 = _mm_unpacklo_epi64(tmp1, tmp3);
5605                let out3 = _mm_unpackhi_epi64(tmp1, tmp3);
5606                [
5607                    out0.simd_into(token),
5608                    out1.simd_into(token),
5609                    out2.simd_into(token),
5610                    out3.simd_into(token),
5611                ]
5612            }
5613        );
5614        kernel(self, src)
5615    }
5616    #[inline(always)]
5617    fn store_four_interleaved_u32x4(
5618        self,
5619        vectors: [u32x4<Self>; 4usize],
5620        dest: &mut [u32; 16usize],
5621    ) -> () {
5622        crate::kernel!(
5623            #[inline(always)]
5624            fn kernel(
5625                token: Sse2,
5626                vectors: [u32x4<Sse2>; 4usize],
5627                dest: &mut [u32; 16usize],
5628            ) -> () {
5629                let _ = token;
5630                let v0: __m128i = vectors[0].into();
5631                let v1: __m128i = vectors[1].into();
5632                let v2: __m128i = vectors[2].into();
5633                let v3: __m128i = vectors[3].into();
5634                let tmp0 = _mm_unpacklo_epi32(v0, v1);
5635                let tmp1 = _mm_unpackhi_epi32(v0, v1);
5636                let tmp2 = _mm_unpacklo_epi32(v2, v3);
5637                let tmp3 = _mm_unpackhi_epi32(v2, v3);
5638                let out0 = _mm_unpacklo_epi64(tmp0, tmp2);
5639                let out1 = _mm_unpackhi_epi64(tmp0, tmp2);
5640                let out2 = _mm_unpacklo_epi64(tmp1, tmp3);
5641                let out3 = _mm_unpackhi_epi64(tmp1, tmp3);
5642                let (chunks, []) = dest.as_chunks_mut::<4usize>() else {
5643                    unreachable!()
5644                };
5645                crate::transmute::checked_transmute_store::<__m128i, [u32; 4usize]>(
5646                    out0,
5647                    &mut chunks[0],
5648                );
5649                crate::transmute::checked_transmute_store::<__m128i, [u32; 4usize]>(
5650                    out1,
5651                    &mut chunks[1],
5652                );
5653                crate::transmute::checked_transmute_store::<__m128i, [u32; 4usize]>(
5654                    out2,
5655                    &mut chunks[2],
5656                );
5657                crate::transmute::checked_transmute_store::<__m128i, [u32; 4usize]>(
5658                    out3,
5659                    &mut chunks[3],
5660                );
5661            }
5662        );
5663        kernel(self, vectors, dest);
5664    }
5665    #[inline(always)]
5666    fn widen_u32x4(self, a: u32x4<Self>) -> (u64x2<Self>, u64x2<Self>) {
5667        crate::kernel!(
5668            #[inline(always)]
5669            fn kernel(token: Sse2, a: u32x4<Sse2>) -> (u64x2<Sse2>, u64x2<Sse2>) {
5670                let raw = a.into();
5671                let sign = _mm_setzero_si128();
5672                (
5673                    _mm_unpacklo_epi32(raw, sign).simd_into(token),
5674                    _mm_unpackhi_epi32(raw, sign).simd_into(token),
5675                )
5676            }
5677        );
5678        kernel(self, a)
5679    }
5680    #[inline(always)]
5681    fn widening_mul_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> (u64x2<Self>, u64x2<Self>) {
5682        let (a0, a1) = self.widen_u32x4(a);
5683        let (b0, b1) = self.widen_u32x4(b);
5684        (self.mul_u64x2(a0, b0), self.mul_u64x2(a1, b1))
5685    }
5686    #[inline(always)]
5687    fn widening_add_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> (u64x2<Self>, u64x2<Self>) {
5688        let (a0, a1) = self.widen_u32x4(a);
5689        let (b0, b1) = self.widen_u32x4(b);
5690        (self.add_u64x2(a0, b0), self.add_u64x2(a1, b1))
5691    }
5692    #[inline(always)]
5693    fn pairwise_widening_add_u32x4(self, a: u32x4<Self>) -> u64x2<Self> {
5694        crate::kernel!(
5695            #[inline(always)]
5696            fn kernel(token: Sse2, a: u32x4<Sse2>) -> u64x2<Sse2> {
5697                ({
5698                    let a = a.into();
5699                    _mm_add_epi64(
5700                        _mm_and_si128(a, _mm_set1_epi64x(4294967295)),
5701                        _mm_srli_epi64::<32>(a),
5702                    )
5703                })
5704                .simd_into(token)
5705            }
5706        );
5707        kernel(self, a)
5708    }
5709    #[inline(always)]
5710    fn pairwise_dot_product_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u64x2<Self> {
5711        let (low, high) = self.widening_mul_u32x4(a, b);
5712        let (even, odd) = self.deinterleave_u64x2(low, high);
5713        self.add_u64x2(even, odd)
5714    }
5715    #[inline(always)]
5716    fn narrow_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u16x8<Self> {
5717        [
5718            a[0usize] as u16,
5719            a[1usize] as u16,
5720            a[2usize] as u16,
5721            a[3usize] as u16,
5722            b[0usize] as u16,
5723            b[1usize] as u16,
5724            b[2usize] as u16,
5725            b[3usize] as u16,
5726        ]
5727        .simd_into(self)
5728    }
5729    #[inline(always)]
5730    fn saturating_narrow_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u16x8<Self> {
5731        [
5732            a[0usize].clamp(u16::MIN as u32, u16::MAX as u32) as u16,
5733            a[1usize].clamp(u16::MIN as u32, u16::MAX as u32) as u16,
5734            a[2usize].clamp(u16::MIN as u32, u16::MAX as u32) as u16,
5735            a[3usize].clamp(u16::MIN as u32, u16::MAX as u32) as u16,
5736            b[0usize].clamp(u16::MIN as u32, u16::MAX as u32) as u16,
5737            b[1usize].clamp(u16::MIN as u32, u16::MAX as u32) as u16,
5738            b[2usize].clamp(u16::MIN as u32, u16::MAX as u32) as u16,
5739            b[3usize].clamp(u16::MIN as u32, u16::MAX as u32) as u16,
5740        ]
5741        .simd_into(self)
5742    }
5743    #[inline(always)]
5744    fn relaxed_narrow_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u16x8<Self> {
5745        debug_assert!(
5746            a.as_slice()
5747                .iter()
5748                .chain(b.as_slice())
5749                .all(|&value| { value >= u16::MIN as u32 && value <= u16::MAX as u32 }),
5750            "relaxed_narrow inputs must fit in the destination type",
5751        );
5752        self.narrow_u32x4(a, b)
5753    }
5754    #[inline(always)]
5755    fn cvt_f32_u32x4(self, a: u32x4<Self>) -> f32x4<Self> {
5756        [
5757            a[0usize] as f32,
5758            a[1usize] as f32,
5759            a[2usize] as f32,
5760            a[3usize] as f32,
5761        ]
5762        .simd_into(self)
5763    }
5764    #[inline(always)]
5765    fn splat_mask32x4(self, val: bool) -> mask32x4<Self> {
5766        crate::kernel!(
5767            #[inline(always)]
5768            fn kernel(token: Sse2, val: bool) -> mask32x4<Sse2> {
5769                let val: i32 = if val { !0 } else { 0 };
5770                _mm_set1_epi32(val).simd_into(token)
5771            }
5772        );
5773        kernel(self, val)
5774    }
5775    #[inline(always)]
5776    fn from_bitmask_mask32x4(self, bits: u64) -> mask32x4<Self> {
5777        crate::kernel!(
5778            #[inline(always)]
5779            fn kernel(token: Sse2, bits: u64) -> mask32x4<Sse2> {
5780                {
5781                    let bit_lanes = _mm_set1_epi32(bits as i32);
5782                    let bit_mask = _mm_setr_epi32(1, 2, 4, 8);
5783                    _mm_cmpeq_epi32(_mm_and_si128(bit_lanes, bit_mask), bit_mask)
5784                }
5785                .simd_into(token)
5786            }
5787        );
5788        kernel(self, bits)
5789    }
5790    #[inline(always)]
5791    fn to_bitmask_mask32x4(self, a: mask32x4<Self>) -> u64 {
5792        crate::kernel!(
5793            #[inline(always)]
5794            fn kernel(token: Sse2, a: mask32x4<Sse2>) -> u64 {
5795                _mm_movemask_ps(_mm_castsi128_ps(a.into())) as u32 as u64
5796            }
5797        );
5798        kernel(self, a)
5799    }
5800    #[inline(always)]
5801    fn from_vector_mask32x4(self, vector: i32x4<Self>) -> mask32x4<Self> {
5802        mask32x4 {
5803            val: vector.val,
5804            simd: self,
5805        }
5806    }
5807    #[inline(always)]
5808    fn to_vector_mask32x4(self, a: mask32x4<Self>) -> i32x4<Self> {
5809        i32x4 {
5810            val: a.val,
5811            simd: self,
5812        }
5813    }
5814    #[inline(always)]
5815    fn set_mask32x4(self, a: &mut mask32x4<Self>, index: usize, value: bool) -> () {
5816        assert!(
5817            index < 4usize,
5818            "mask lane index {index} is out of bounds for {} lanes",
5819            4usize
5820        );
5821        let mut lanes: [i32; 4usize] = (*a).into();
5822        lanes[index] = if value { !0 } else { 0 };
5823        *a = lanes.simd_into(self);
5824    }
5825    #[inline(always)]
5826    fn rotate_elements_left_mask32x4<const OFFSET: usize>(
5827        self,
5828        a: mask32x4<Self>,
5829    ) -> mask32x4<Self> {
5830        let int = i32x4 {
5831            val: crate::transmute::checked_transmute_copy(&a.val),
5832            simd: self,
5833        };
5834        let rotated = int.rotate_elements_left::<OFFSET>();
5835        mask32x4 {
5836            val: crate::transmute::checked_transmute_copy(&rotated.val),
5837            simd: self,
5838        }
5839    }
5840    #[inline(always)]
5841    fn rotate_elements_right_mask32x4<const OFFSET: usize>(
5842        self,
5843        a: mask32x4<Self>,
5844    ) -> mask32x4<Self> {
5845        let int = i32x4 {
5846            val: crate::transmute::checked_transmute_copy(&a.val),
5847            simd: self,
5848        };
5849        let rotated = int.rotate_elements_right::<OFFSET>();
5850        mask32x4 {
5851            val: crate::transmute::checked_transmute_copy(&rotated.val),
5852            simd: self,
5853        }
5854    }
5855    #[inline(always)]
5856    fn and_mask32x4(self, a: mask32x4<Self>, b: mask32x4<Self>) -> mask32x4<Self> {
5857        crate::kernel!(
5858            #[inline(always)]
5859            fn kernel(token: Sse2, a: mask32x4<Sse2>, b: mask32x4<Sse2>) -> mask32x4<Sse2> {
5860                _mm_and_si128(a.into(), b.into()).simd_into(token)
5861            }
5862        );
5863        kernel(self, a, b)
5864    }
5865    #[inline(always)]
5866    fn or_mask32x4(self, a: mask32x4<Self>, b: mask32x4<Self>) -> mask32x4<Self> {
5867        crate::kernel!(
5868            #[inline(always)]
5869            fn kernel(token: Sse2, a: mask32x4<Sse2>, b: mask32x4<Sse2>) -> mask32x4<Sse2> {
5870                _mm_or_si128(a.into(), b.into()).simd_into(token)
5871            }
5872        );
5873        kernel(self, a, b)
5874    }
5875    #[inline(always)]
5876    fn xor_mask32x4(self, a: mask32x4<Self>, b: mask32x4<Self>) -> mask32x4<Self> {
5877        crate::kernel!(
5878            #[inline(always)]
5879            fn kernel(token: Sse2, a: mask32x4<Sse2>, b: mask32x4<Sse2>) -> mask32x4<Sse2> {
5880                _mm_xor_si128(a.into(), b.into()).simd_into(token)
5881            }
5882        );
5883        kernel(self, a, b)
5884    }
5885    #[inline(always)]
5886    fn not_mask32x4(self, a: mask32x4<Self>) -> mask32x4<Self> {
5887        self.xor_mask32x4(a, self.splat_mask32x4(true))
5888    }
5889    #[inline(always)]
5890    fn reverse_mask32x4(self, a: mask32x4<Self>) -> mask32x4<Self> {
5891        let lanes = i32x4 {
5892            val: crate::transmute::checked_transmute_copy(&a.val),
5893            simd: self,
5894        };
5895        let reversed = self.reverse_i32x4(lanes);
5896        mask32x4 {
5897            val: crate::transmute::checked_transmute_copy(&reversed.val),
5898            simd: self,
5899        }
5900    }
5901    #[inline(always)]
5902    fn select_mask32x4(
5903        self,
5904        a: mask32x4<Self>,
5905        b: mask32x4<Self>,
5906        c: mask32x4<Self>,
5907    ) -> mask32x4<Self> {
5908        crate::kernel!(
5909            #[inline(always)]
5910            fn kernel(
5911                token: Sse2,
5912                a: mask32x4<Sse2>,
5913                b: mask32x4<Sse2>,
5914                c: mask32x4<Sse2>,
5915            ) -> mask32x4<Sse2> {
5916                _mm_or_si128(
5917                    _mm_and_si128(a.into(), b.into()),
5918                    _mm_andnot_si128(a.into(), c.into()),
5919                )
5920                .simd_into(token)
5921            }
5922        );
5923        kernel(self, a, b, c)
5924    }
5925    #[inline(always)]
5926    fn simd_eq_mask32x4(self, a: mask32x4<Self>, b: mask32x4<Self>) -> mask32x4<Self> {
5927        crate::kernel!(
5928            #[inline(always)]
5929            fn kernel(token: Sse2, a: mask32x4<Sse2>, b: mask32x4<Sse2>) -> mask32x4<Sse2> {
5930                _mm_cmpeq_epi32(a.into(), b.into()).simd_into(token)
5931            }
5932        );
5933        kernel(self, a, b)
5934    }
5935    #[inline(always)]
5936    fn any_true_mask32x4(self, a: mask32x4<Self>) -> bool {
5937        crate::kernel!(
5938            #[inline(always)]
5939            fn kernel(token: Sse2, a: mask32x4<Sse2>) -> bool {
5940                _mm_movemask_ps(_mm_castsi128_ps(a.into())) as u32 != 0
5941            }
5942        );
5943        kernel(self, a)
5944    }
5945    #[inline(always)]
5946    fn all_true_mask32x4(self, a: mask32x4<Self>) -> bool {
5947        crate::kernel!(
5948            #[inline(always)]
5949            fn kernel(token: Sse2, a: mask32x4<Sse2>) -> bool {
5950                _mm_movemask_ps(_mm_castsi128_ps(a.into())) as u32 == 0b1111
5951            }
5952        );
5953        kernel(self, a)
5954    }
5955    #[inline(always)]
5956    fn any_false_mask32x4(self, a: mask32x4<Self>) -> bool {
5957        crate::kernel!(
5958            #[inline(always)]
5959            fn kernel(token: Sse2, a: mask32x4<Sse2>) -> bool {
5960                _mm_movemask_ps(_mm_castsi128_ps(a.into())) as u32 != 0b1111
5961            }
5962        );
5963        kernel(self, a)
5964    }
5965    #[inline(always)]
5966    fn all_false_mask32x4(self, a: mask32x4<Self>) -> bool {
5967        crate::kernel!(
5968            #[inline(always)]
5969            fn kernel(token: Sse2, a: mask32x4<Sse2>) -> bool {
5970                _mm_movemask_ps(_mm_castsi128_ps(a.into())) as u32 == 0
5971            }
5972        );
5973        kernel(self, a)
5974    }
5975    #[inline(always)]
5976    fn combine_mask32x4(self, a: mask32x4<Self>, b: mask32x4<Self>) -> mask32x8<Self> {
5977        mask32x8 {
5978            val: crate::support::Aligned256([a.val.0, b.val.0]),
5979            simd: self,
5980        }
5981    }
5982    #[inline(always)]
5983    fn widen_mask32x4(self, a: mask32x4<Self>) -> (mask64x2<Self>, mask64x2<Self>) {
5984        crate::kernel!(
5985            #[inline(always)]
5986            fn kernel(token: Sse2, a: mask32x4<Sse2>) -> (mask64x2<Sse2>, mask64x2<Sse2>) {
5987                let raw = a.into();
5988                (
5989                    _mm_unpacklo_epi32(raw, raw).simd_into(token),
5990                    _mm_unpackhi_epi32(raw, raw).simd_into(token),
5991                )
5992            }
5993        );
5994        kernel(self, a)
5995    }
5996    #[inline(always)]
5997    fn narrow_mask32x4(self, a: mask32x4<Self>, b: mask32x4<Self>) -> mask16x8<Self> {
5998        crate::kernel!(
5999            #[inline(always)]
6000            fn kernel(token: Sse2, a: mask32x4<Sse2>, b: mask32x4<Sse2>) -> mask16x8<Sse2> {
6001                _mm_packs_epi32(a.into(), b.into()).simd_into(token)
6002            }
6003        );
6004        kernel(self, a, b)
6005    }
6006    #[inline(always)]
6007    fn abs_f64x2(self, a: f64x2<Self>) -> f64x2<Self> {
6008        crate::kernel!(
6009            #[inline(always)]
6010            fn kernel(token: Sse2, a: f64x2<Sse2>) -> f64x2<Sse2> {
6011                _mm_andnot_pd(_mm_set1_pd(-0.0), a.into()).simd_into(token)
6012            }
6013        );
6014        kernel(self, a)
6015    }
6016    #[inline(always)]
6017    fn splat_f64x2(self, val: f64) -> f64x2<Self> {
6018        crate::kernel!(
6019            #[inline(always)]
6020            fn kernel(token: Sse2, val: f64) -> f64x2<Sse2> {
6021                _mm_set1_pd(val).simd_into(token)
6022            }
6023        );
6024        kernel(self, val)
6025    }
6026    #[inline(always)]
6027    fn reverse_f64x2(self, a: f64x2<Self>) -> f64x2<Self> {
6028        [a[1usize], a[0usize]].simd_into(self)
6029    }
6030    #[inline(always)]
6031    fn slide_f64x2<const SHIFT: usize>(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self> {
6032        if SHIFT >= 2usize {
6033            return b;
6034        }
6035        let result = dyn_alignr_128(
6036            self,
6037            Bytes::to_bytes(b).val.0,
6038            Bytes::to_bytes(a).val.0,
6039            SHIFT * 8usize,
6040        );
6041        Bytes::from_bytes(u8x16 {
6042            val: crate::support::Aligned128(result),
6043            simd: self,
6044        })
6045    }
6046    #[inline(always)]
6047    fn compress_f64x2(self, values: f64x2<Self>, mask: mask64x2<Self>) -> f64x2<Self> {
6048        let mask = mask8x16 {
6049            val: crate::transmute::checked_transmute_copy(&mask.val),
6050            simd: self,
6051        };
6052        Bytes::from_bytes(self.compress_u8x16(Bytes::to_bytes(values), mask))
6053    }
6054    #[inline(always)]
6055    fn compress_merge_f64x2(
6056        self,
6057        values: f64x2<Self>,
6058        mask: mask64x2<Self>,
6059        merge: f64x2<Self>,
6060    ) -> f64x2<Self> {
6061        let mask = mask8x16 {
6062            val: crate::transmute::checked_transmute_copy(&mask.val),
6063            simd: self,
6064        };
6065        Bytes::from_bytes(self.compress_merge_u8x16(
6066            Bytes::to_bytes(values),
6067            mask,
6068            Bytes::to_bytes(merge),
6069        ))
6070    }
6071    #[inline(always)]
6072    fn expand_f64x2(self, values: f64x2<Self>, mask: mask64x2<Self>) -> f64x2<Self> {
6073        let mask = mask8x16 {
6074            val: crate::transmute::checked_transmute_copy(&mask.val),
6075            simd: self,
6076        };
6077        Bytes::from_bytes(self.expand_u8x16(Bytes::to_bytes(values), mask))
6078    }
6079    #[inline(always)]
6080    fn expand_merge_f64x2(
6081        self,
6082        values: f64x2<Self>,
6083        mask: mask64x2<Self>,
6084        merge: f64x2<Self>,
6085    ) -> f64x2<Self> {
6086        let mask = mask8x16 {
6087            val: crate::transmute::checked_transmute_copy(&mask.val),
6088            simd: self,
6089        };
6090        Bytes::from_bytes(self.expand_merge_u8x16(
6091            Bytes::to_bytes(values),
6092            mask,
6093            Bytes::to_bytes(merge),
6094        ))
6095    }
6096    #[inline(always)]
6097    fn neg_f64x2(self, a: f64x2<Self>) -> f64x2<Self> {
6098        crate::kernel!(
6099            #[inline(always)]
6100            fn kernel(token: Sse2, a: f64x2<Sse2>) -> f64x2<Sse2> {
6101                _mm_xor_pd(a.into(), _mm_set1_pd(-0.0)).simd_into(token)
6102            }
6103        );
6104        kernel(self, a)
6105    }
6106    #[inline(always)]
6107    fn sqrt_f64x2(self, a: f64x2<Self>) -> f64x2<Self> {
6108        crate::kernel!(
6109            #[inline(always)]
6110            fn kernel(token: Sse2, a: f64x2<Sse2>) -> f64x2<Sse2> {
6111                _mm_sqrt_pd(a.into()).simd_into(token)
6112            }
6113        );
6114        kernel(self, a)
6115    }
6116    #[inline(always)]
6117    fn approximate_recip_f64x2(self, a: f64x2<Self>) -> f64x2<Self> {
6118        1.0 / a
6119    }
6120    #[inline(always)]
6121    fn add_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self> {
6122        crate::kernel!(
6123            #[inline(always)]
6124            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> f64x2<Sse2> {
6125                _mm_add_pd(a.into(), b.into()).simd_into(token)
6126            }
6127        );
6128        kernel(self, a, b)
6129    }
6130    #[inline(always)]
6131    fn sub_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self> {
6132        crate::kernel!(
6133            #[inline(always)]
6134            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> f64x2<Sse2> {
6135                _mm_sub_pd(a.into(), b.into()).simd_into(token)
6136            }
6137        );
6138        kernel(self, a, b)
6139    }
6140    #[inline(always)]
6141    fn mul_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self> {
6142        crate::kernel!(
6143            #[inline(always)]
6144            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> f64x2<Sse2> {
6145                _mm_mul_pd(a.into(), b.into()).simd_into(token)
6146            }
6147        );
6148        kernel(self, a, b)
6149    }
6150    #[inline(always)]
6151    fn div_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self> {
6152        crate::kernel!(
6153            #[inline(always)]
6154            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> f64x2<Sse2> {
6155                _mm_div_pd(a.into(), b.into()).simd_into(token)
6156            }
6157        );
6158        kernel(self, a, b)
6159    }
6160    #[inline(always)]
6161    fn copysign_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self> {
6162        crate::kernel!(
6163            #[inline(always)]
6164            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> f64x2<Sse2> {
6165                let mask = _mm_set1_pd(-0.0);
6166                _mm_or_pd(_mm_and_pd(mask, b.into()), _mm_andnot_pd(mask, a.into()))
6167                    .simd_into(token)
6168            }
6169        );
6170        kernel(self, a, b)
6171    }
6172    #[inline(always)]
6173    fn reduce_max_f64x2(self, a: f64x2<Self>) -> f64 {
6174        crate::kernel!(
6175            #[inline(always)]
6176            fn kernel(token: Sse2, a: f64x2<Sse2>) -> f64 {
6177                let reduced: __m128d = a.into();
6178                let shifted = _mm_castsi128_pd(_mm_srli_si128::<8>(_mm_castpd_si128(reduced)));
6179                let reduced = { _mm_max_pd(reduced, shifted) };
6180                _mm_cvtsd_f64(reduced)
6181            }
6182        );
6183        kernel(self, a)
6184    }
6185    #[inline(always)]
6186    fn reduce_min_f64x2(self, a: f64x2<Self>) -> f64 {
6187        crate::kernel!(
6188            #[inline(always)]
6189            fn kernel(token: Sse2, a: f64x2<Sse2>) -> f64 {
6190                let reduced: __m128d = a.into();
6191                let shifted = _mm_castsi128_pd(_mm_srli_si128::<8>(_mm_castpd_si128(reduced)));
6192                let reduced = { _mm_min_pd(reduced, shifted) };
6193                _mm_cvtsd_f64(reduced)
6194            }
6195        );
6196        kernel(self, a)
6197    }
6198    #[inline(always)]
6199    fn reduce_max_precise_f64x2(self, a: f64x2<Self>) -> f64 {
6200        crate::kernel!(
6201            #[inline(always)]
6202            fn kernel(token: Sse2, a: f64x2<Sse2>) -> f64 {
6203                let reduced: __m128d = a.into();
6204                let shifted = _mm_castsi128_pd(_mm_srli_si128::<8>(_mm_castpd_si128(reduced)));
6205                let reduced = {
6206                    let intermediate = _mm_max_pd(reduced, shifted);
6207                    let shifted_is_nan = _mm_cmpunord_pd(shifted, shifted);
6208                    _mm_or_pd(
6209                        _mm_and_pd(shifted_is_nan, reduced),
6210                        _mm_andnot_pd(shifted_is_nan, intermediate),
6211                    )
6212                };
6213                _mm_cvtsd_f64(reduced)
6214            }
6215        );
6216        kernel(self, a)
6217    }
6218    #[inline(always)]
6219    fn reduce_min_precise_f64x2(self, a: f64x2<Self>) -> f64 {
6220        crate::kernel!(
6221            #[inline(always)]
6222            fn kernel(token: Sse2, a: f64x2<Sse2>) -> f64 {
6223                let reduced: __m128d = a.into();
6224                let shifted = _mm_castsi128_pd(_mm_srli_si128::<8>(_mm_castpd_si128(reduced)));
6225                let reduced = {
6226                    let intermediate = _mm_min_pd(reduced, shifted);
6227                    let shifted_is_nan = _mm_cmpunord_pd(shifted, shifted);
6228                    _mm_or_pd(
6229                        _mm_and_pd(shifted_is_nan, reduced),
6230                        _mm_andnot_pd(shifted_is_nan, intermediate),
6231                    )
6232                };
6233                _mm_cvtsd_f64(reduced)
6234            }
6235        );
6236        kernel(self, a)
6237    }
6238    #[inline(always)]
6239    fn reduce_sum_f64x2(self, a: f64x2<Self>) -> f64 {
6240        crate::kernel!(
6241            #[inline(always)]
6242            fn kernel(token: Sse2, a: f64x2<Sse2>) -> f64 {
6243                let a: __m128d = a.into();
6244                _mm_cvtsd_f64(_mm_add_sd(a, _mm_unpackhi_pd(a, a)))
6245            }
6246        );
6247        kernel(self, a)
6248    }
6249    #[inline(always)]
6250    fn reduce_product_f64x2(self, a: f64x2<Self>) -> f64 {
6251        crate::kernel!(
6252            #[inline(always)]
6253            fn kernel(token: Sse2, a: f64x2<Sse2>) -> f64 {
6254                let a: __m128d = a.into();
6255                _mm_cvtsd_f64(_mm_mul_sd(a, _mm_unpackhi_pd(a, a)))
6256            }
6257        );
6258        kernel(self, a)
6259    }
6260    #[inline(always)]
6261    fn max_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self> {
6262        crate::kernel!(
6263            #[inline(always)]
6264            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> f64x2<Sse2> {
6265                _mm_max_pd(a.into(), b.into()).simd_into(token)
6266            }
6267        );
6268        kernel(self, a, b)
6269    }
6270    #[inline(always)]
6271    fn min_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self> {
6272        crate::kernel!(
6273            #[inline(always)]
6274            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> f64x2<Sse2> {
6275                _mm_min_pd(a.into(), b.into()).simd_into(token)
6276            }
6277        );
6278        kernel(self, a, b)
6279    }
6280    #[inline(always)]
6281    fn max_precise_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self> {
6282        crate::kernel!(
6283            #[inline(always)]
6284            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> f64x2<Sse2> {
6285                let a = a.into();
6286                let b = b.into();
6287                let intermediate = _mm_max_pd(a, b);
6288                let b_is_nan = _mm_cmpunord_pd(b, b);
6289                _mm_or_pd(
6290                    _mm_and_pd(b_is_nan, a),
6291                    _mm_andnot_pd(b_is_nan, intermediate),
6292                )
6293                .simd_into(token)
6294            }
6295        );
6296        kernel(self, a, b)
6297    }
6298    #[inline(always)]
6299    fn min_precise_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self> {
6300        crate::kernel!(
6301            #[inline(always)]
6302            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> f64x2<Sse2> {
6303                let a = a.into();
6304                let b = b.into();
6305                let intermediate = _mm_min_pd(a, b);
6306                let b_is_nan = _mm_cmpunord_pd(b, b);
6307                _mm_or_pd(
6308                    _mm_and_pd(b_is_nan, a),
6309                    _mm_andnot_pd(b_is_nan, intermediate),
6310                )
6311                .simd_into(token)
6312            }
6313        );
6314        kernel(self, a, b)
6315    }
6316    #[inline(always)]
6317    fn clamp_f64x2(self, a: f64x2<Self>, b: f64x2<Self>, c: f64x2<Self>) -> f64x2<Self> {
6318        crate::kernel!(
6319            #[inline(always)]
6320            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>, c: f64x2<Sse2>) -> f64x2<Sse2> {
6321                debug_assert!(
6322                    b.simd_le(c).all_true(),
6323                    "clamp requires min <= max for all elements"
6324                );
6325                _mm_min_pd(c.into(), _mm_max_pd(b.into(), a.into())).simd_into(token)
6326            }
6327        );
6328        kernel(self, a, b, c)
6329    }
6330    #[inline(always)]
6331    fn simd_eq_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> mask64x2<Self> {
6332        crate::kernel!(
6333            #[inline(always)]
6334            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> mask64x2<Sse2> {
6335                _mm_castpd_si128(_mm_cmpeq_pd(a.into(), b.into())).simd_into(token)
6336            }
6337        );
6338        kernel(self, a, b)
6339    }
6340    #[inline(always)]
6341    fn simd_ne_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> mask64x2<Self> {
6342        crate::kernel!(
6343            #[inline(always)]
6344            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> mask64x2<Sse2> {
6345                _mm_castpd_si128(_mm_cmpneq_pd(a.into(), b.into())).simd_into(token)
6346            }
6347        );
6348        kernel(self, a, b)
6349    }
6350    #[inline(always)]
6351    fn simd_lt_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> mask64x2<Self> {
6352        crate::kernel!(
6353            #[inline(always)]
6354            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> mask64x2<Sse2> {
6355                _mm_castpd_si128(_mm_cmplt_pd(a.into(), b.into())).simd_into(token)
6356            }
6357        );
6358        kernel(self, a, b)
6359    }
6360    #[inline(always)]
6361    fn simd_le_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> mask64x2<Self> {
6362        crate::kernel!(
6363            #[inline(always)]
6364            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> mask64x2<Sse2> {
6365                _mm_castpd_si128(_mm_cmple_pd(a.into(), b.into())).simd_into(token)
6366            }
6367        );
6368        kernel(self, a, b)
6369    }
6370    #[inline(always)]
6371    fn zip_low_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self> {
6372        crate::kernel!(
6373            #[inline(always)]
6374            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> f64x2<Sse2> {
6375                _mm_unpacklo_pd(a.into(), b.into()).simd_into(token)
6376            }
6377        );
6378        kernel(self, a, b)
6379    }
6380    #[inline(always)]
6381    fn zip_high_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self> {
6382        crate::kernel!(
6383            #[inline(always)]
6384            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> f64x2<Sse2> {
6385                _mm_unpackhi_pd(a.into(), b.into()).simd_into(token)
6386            }
6387        );
6388        kernel(self, a, b)
6389    }
6390    #[inline(always)]
6391    fn unzip_low_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self> {
6392        crate::kernel!(
6393            #[inline(always)]
6394            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> f64x2<Sse2> {
6395                _mm_shuffle_pd::<0b00>(a.into(), b.into()).simd_into(token)
6396            }
6397        );
6398        kernel(self, a, b)
6399    }
6400    #[inline(always)]
6401    fn unzip_high_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self> {
6402        crate::kernel!(
6403            #[inline(always)]
6404            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> f64x2<Sse2> {
6405                _mm_shuffle_pd::<0b11>(a.into(), b.into()).simd_into(token)
6406            }
6407        );
6408        kernel(self, a, b)
6409    }
6410    #[inline(always)]
6411    fn interleave_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> (f64x2<Self>, f64x2<Self>) {
6412        (self.zip_low_f64x2(a, b), self.zip_high_f64x2(a, b))
6413    }
6414    #[inline(always)]
6415    fn deinterleave_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> (f64x2<Self>, f64x2<Self>) {
6416        (self.unzip_low_f64x2(a, b), self.unzip_high_f64x2(a, b))
6417    }
6418    #[inline(always)]
6419    fn mul_add_f64x2(self, a: f64x2<Self>, b: f64x2<Self>, c: f64x2<Self>) -> f64x2<Self> {
6420        a * b + c
6421    }
6422    #[inline(always)]
6423    fn mul_add_precise_f64x2(self, a: f64x2<Self>, b: f64x2<Self>, c: f64x2<Self>) -> f64x2<Self> {
6424        crate::math::mul_add_precise_f64x2(self, a, b, c)
6425    }
6426    #[inline(always)]
6427    fn mul_sub_f64x2(self, a: f64x2<Self>, b: f64x2<Self>, c: f64x2<Self>) -> f64x2<Self> {
6428        a * b - c
6429    }
6430    #[inline(always)]
6431    fn mul_sub_precise_f64x2(self, a: f64x2<Self>, b: f64x2<Self>, c: f64x2<Self>) -> f64x2<Self> {
6432        self.mul_add_precise_f64x2(a, b, -c)
6433    }
6434    #[inline(always)]
6435    fn floor_f64x2(self, a: f64x2<Self>) -> f64x2<Self> {
6436        [f64::floor(a[0usize]), f64::floor(a[1usize])].simd_into(self)
6437    }
6438    #[inline(always)]
6439    fn ceil_f64x2(self, a: f64x2<Self>) -> f64x2<Self> {
6440        [f64::ceil(a[0usize]), f64::ceil(a[1usize])].simd_into(self)
6441    }
6442    #[inline(always)]
6443    fn round_ties_even_f64x2(self, a: f64x2<Self>) -> f64x2<Self> {
6444        [
6445            f64::round_ties_even(a[0usize]),
6446            f64::round_ties_even(a[1usize]),
6447        ]
6448        .simd_into(self)
6449    }
6450    #[inline(always)]
6451    fn round_f64x2(self, a: f64x2<Self>) -> f64x2<Self> {
6452        let bias = self.splat_f64x2(const { f64::next_down(0.5) });
6453        (a + self.copysign_f64x2(bias, a)).trunc()
6454    }
6455    #[inline(always)]
6456    fn fract_f64x2(self, a: f64x2<Self>) -> f64x2<Self> {
6457        a - self.trunc_f64x2(a)
6458    }
6459    #[inline(always)]
6460    fn trunc_f64x2(self, a: f64x2<Self>) -> f64x2<Self> {
6461        [f64::trunc(a[0usize]), f64::trunc(a[1usize])].simd_into(self)
6462    }
6463    #[inline(always)]
6464    fn to_degrees_f64x2(self, a: f64x2<Self>) -> f64x2<Self> {
6465        a * const { f64::to_degrees(1.0) }
6466    }
6467    #[inline(always)]
6468    fn to_radians_f64x2(self, a: f64x2<Self>) -> f64x2<Self> {
6469        a * const { f64::to_radians(1.0) }
6470    }
6471    #[inline(always)]
6472    fn is_nan_f64x2(self, a: f64x2<Self>) -> mask64x2<Self> {
6473        a.simd_ne(a)
6474    }
6475    #[inline(always)]
6476    fn is_infinite_f64x2(self, a: f64x2<Self>) -> mask64x2<Self> {
6477        a.abs().simd_eq(f64::INFINITY)
6478    }
6479    #[inline(always)]
6480    fn is_finite_f64x2(self, a: f64x2<Self>) -> mask64x2<Self> {
6481        a.abs().simd_lt(f64::INFINITY)
6482    }
6483    #[inline(always)]
6484    fn is_subnormal_f64x2(self, a: f64x2<Self>) -> mask64x2<Self> {
6485        let i: i64x2<Self> = a.bitcast();
6486        (i & 0x7FF0_0000_0000_0000_i64).simd_eq(0) & (i & 0x000F_FFFF_FFFF_FFFF_i64).simd_ne(0)
6487    }
6488    #[inline(always)]
6489    fn is_normal_f64x2(self, a: f64x2<Self>) -> mask64x2<Self> {
6490        let i: i64x2<Self> = a.bitcast();
6491        let exp = i & 0x7FF0_0000_0000_0000_i64;
6492        exp.simd_ne(0) & exp.simd_ne(0x7FF0_0000_0000_0000_i64)
6493    }
6494    #[inline(always)]
6495    fn is_sign_positive_f64x2(self, a: f64x2<Self>) -> mask64x2<Self> {
6496        let i: i64x2<Self> = a.bitcast();
6497        (i & i64::MIN).simd_eq(0)
6498    }
6499    #[inline(always)]
6500    fn is_sign_negative_f64x2(self, a: f64x2<Self>) -> mask64x2<Self> {
6501        !a.is_sign_positive()
6502    }
6503    #[inline(always)]
6504    fn select_f64x2(self, a: mask64x2<Self>, b: f64x2<Self>, c: f64x2<Self>) -> f64x2<Self> {
6505        crate::kernel!(
6506            #[inline(always)]
6507            fn kernel(
6508                token: Sse2,
6509                a: mask64x2<Sse2>,
6510                b: f64x2<Sse2>,
6511                c: f64x2<Sse2>,
6512            ) -> f64x2<Sse2> {
6513                _mm_or_pd(
6514                    _mm_and_pd(_mm_castsi128_pd(a.into()), b.into()),
6515                    _mm_andnot_pd(_mm_castsi128_pd(a.into()), c.into()),
6516                )
6517                .simd_into(token)
6518            }
6519        );
6520        kernel(self, a, b, c)
6521    }
6522    #[inline(always)]
6523    fn combine_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x4<Self> {
6524        f64x4 {
6525            val: crate::support::Aligned256([a.val.0, b.val.0]),
6526            simd: self,
6527        }
6528    }
6529    #[inline(always)]
6530    fn load_four_interleaved_f64x2(self, src: &[f64; 8usize]) -> [f64x2<Self>; 4usize] {
6531        crate::kernel!(
6532            #[inline(always)]
6533            fn kernel(token: Sse2, src: &[f64; 8usize]) -> [f64x2<Sse2>; 4usize] {
6534                let (chunks, []) = src.as_chunks::<2usize>() else {
6535                    unreachable!()
6536                };
6537                let v0: __m128d =
6538                    crate::transmute::checked_transmute_copy::<[f64; 2usize], __m128d>(&chunks[0]);
6539                let v1: __m128d =
6540                    crate::transmute::checked_transmute_copy::<[f64; 2usize], __m128d>(&chunks[1]);
6541                let v2: __m128d =
6542                    crate::transmute::checked_transmute_copy::<[f64; 2usize], __m128d>(&chunks[2]);
6543                let v3: __m128d =
6544                    crate::transmute::checked_transmute_copy::<[f64; 2usize], __m128d>(&chunks[3]);
6545                let out0 = _mm_unpacklo_pd(v0, v2);
6546                let out1 = _mm_unpackhi_pd(v0, v2);
6547                let out2 = _mm_unpacklo_pd(v1, v3);
6548                let out3 = _mm_unpackhi_pd(v1, v3);
6549                [
6550                    out0.simd_into(token),
6551                    out1.simd_into(token),
6552                    out2.simd_into(token),
6553                    out3.simd_into(token),
6554                ]
6555            }
6556        );
6557        kernel(self, src)
6558    }
6559    #[inline(always)]
6560    fn store_four_interleaved_f64x2(
6561        self,
6562        vectors: [f64x2<Self>; 4usize],
6563        dest: &mut [f64; 8usize],
6564    ) -> () {
6565        crate::kernel!(
6566            #[inline(always)]
6567            fn kernel(token: Sse2, vectors: [f64x2<Sse2>; 4usize], dest: &mut [f64; 8usize]) -> () {
6568                let _ = token;
6569                let v0: __m128d = vectors[0].into();
6570                let v1: __m128d = vectors[1].into();
6571                let v2: __m128d = vectors[2].into();
6572                let v3: __m128d = vectors[3].into();
6573                let out0 = _mm_unpacklo_pd(v0, v1);
6574                let out1 = _mm_unpacklo_pd(v2, v3);
6575                let out2 = _mm_unpackhi_pd(v0, v1);
6576                let out3 = _mm_unpackhi_pd(v2, v3);
6577                let (chunks, []) = dest.as_chunks_mut::<2usize>() else {
6578                    unreachable!()
6579                };
6580                crate::transmute::checked_transmute_store::<__m128d, [f64; 2usize]>(
6581                    out0,
6582                    &mut chunks[0],
6583                );
6584                crate::transmute::checked_transmute_store::<__m128d, [f64; 2usize]>(
6585                    out1,
6586                    &mut chunks[1],
6587                );
6588                crate::transmute::checked_transmute_store::<__m128d, [f64; 2usize]>(
6589                    out2,
6590                    &mut chunks[2],
6591                );
6592                crate::transmute::checked_transmute_store::<__m128d, [f64; 2usize]>(
6593                    out3,
6594                    &mut chunks[3],
6595                );
6596            }
6597        );
6598        kernel(self, vectors, dest);
6599    }
6600    #[inline(always)]
6601    fn narrow_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f32x4<Self> {
6602        crate::kernel!(
6603            #[inline(always)]
6604            fn kernel(token: Sse2, a: f64x2<Sse2>, b: f64x2<Sse2>) -> f32x4<Sse2> {
6605                let low = _mm_cvtpd_ps(a.into());
6606                let high = _mm_cvtpd_ps(b.into());
6607                _mm_movelh_ps(low, high).simd_into(token)
6608            }
6609        );
6610        kernel(self, a, b)
6611    }
6612    #[inline(always)]
6613    fn saturating_narrow_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f32x4<Self> {
6614        self.narrow_f64x2(a, b)
6615    }
6616    #[inline(always)]
6617    fn relaxed_narrow_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f32x4<Self> {
6618        self.narrow_f64x2(a, b)
6619    }
6620    #[inline(always)]
6621    fn cvt_u64_f64x2(self, a: f64x2<Self>) -> u64x2<Self> {
6622        [a[0usize] as u64, a[1usize] as u64].simd_into(self)
6623    }
6624    #[inline(always)]
6625    fn cvt_u64_precise_f64x2(self, a: f64x2<Self>) -> u64x2<Self> {
6626        [a[0usize] as u64, a[1usize] as u64].simd_into(self)
6627    }
6628    #[inline(always)]
6629    #[cfg(target_arch = "x86_64")]
6630    fn cvt_i64_f64x2(self, a: f64x2<Self>) -> i64x2<Self> {
6631        crate::kernel!(
6632            #[inline(always)]
6633            fn kernel(token: Sse2, a: f64x2<Sse2>) -> i64x2<Sse2> {
6634                let a = a.into();
6635                let low = _mm_cvttsd_si64(a);
6636                let high = _mm_cvttsd_si64(_mm_unpackhi_pd(a, a));
6637                _mm_set_epi64x(high, low).simd_into(token)
6638            }
6639        );
6640        kernel(self, a)
6641    }
6642    #[cfg(target_arch = "x86")]
6643    fn cvt_i64_f64x2(self, a: f64x2<Self>) -> i64x2<Self> {
6644        [a[0usize] as i64, a[1usize] as i64].simd_into(self)
6645    }
6646    #[inline(always)]
6647    fn cvt_i64_precise_f64x2(self, a: f64x2<Self>) -> i64x2<Self> {
6648        [a[0usize] as i64, a[1usize] as i64].simd_into(self)
6649    }
6650    #[inline(always)]
6651    fn abs_i64x2(self, a: i64x2<Self>) -> i64x2<Self> {
6652        [i64::wrapping_abs(a[0usize]), i64::wrapping_abs(a[1usize])].simd_into(self)
6653    }
6654    #[inline(always)]
6655    fn splat_i64x2(self, val: i64) -> i64x2<Self> {
6656        crate::kernel!(
6657            #[inline(always)]
6658            fn kernel(token: Sse2, val: i64) -> i64x2<Sse2> {
6659                _mm_set1_epi64x(val).simd_into(token)
6660            }
6661        );
6662        kernel(self, val)
6663    }
6664    #[inline(always)]
6665    fn reverse_i64x2(self, a: i64x2<Self>) -> i64x2<Self> {
6666        [a[1usize], a[0usize]].simd_into(self)
6667    }
6668    #[inline(always)]
6669    fn slide_i64x2<const SHIFT: usize>(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
6670        if SHIFT >= 2usize {
6671            return b;
6672        }
6673        let result = dyn_alignr_128(
6674            self,
6675            Bytes::to_bytes(b).val.0,
6676            Bytes::to_bytes(a).val.0,
6677            SHIFT * 8usize,
6678        );
6679        Bytes::from_bytes(u8x16 {
6680            val: crate::support::Aligned128(result),
6681            simd: self,
6682        })
6683    }
6684    #[inline(always)]
6685    fn compress_i64x2(self, values: i64x2<Self>, mask: mask64x2<Self>) -> i64x2<Self> {
6686        let mask = mask8x16 {
6687            val: crate::transmute::checked_transmute_copy(&mask.val),
6688            simd: self,
6689        };
6690        Bytes::from_bytes(self.compress_u8x16(Bytes::to_bytes(values), mask))
6691    }
6692    #[inline(always)]
6693    fn compress_merge_i64x2(
6694        self,
6695        values: i64x2<Self>,
6696        mask: mask64x2<Self>,
6697        merge: i64x2<Self>,
6698    ) -> i64x2<Self> {
6699        let mask = mask8x16 {
6700            val: crate::transmute::checked_transmute_copy(&mask.val),
6701            simd: self,
6702        };
6703        Bytes::from_bytes(self.compress_merge_u8x16(
6704            Bytes::to_bytes(values),
6705            mask,
6706            Bytes::to_bytes(merge),
6707        ))
6708    }
6709    #[inline(always)]
6710    fn expand_i64x2(self, values: i64x2<Self>, mask: mask64x2<Self>) -> i64x2<Self> {
6711        let mask = mask8x16 {
6712            val: crate::transmute::checked_transmute_copy(&mask.val),
6713            simd: self,
6714        };
6715        Bytes::from_bytes(self.expand_u8x16(Bytes::to_bytes(values), mask))
6716    }
6717    #[inline(always)]
6718    fn expand_merge_i64x2(
6719        self,
6720        values: i64x2<Self>,
6721        mask: mask64x2<Self>,
6722        merge: i64x2<Self>,
6723    ) -> i64x2<Self> {
6724        let mask = mask8x16 {
6725            val: crate::transmute::checked_transmute_copy(&mask.val),
6726            simd: self,
6727        };
6728        Bytes::from_bytes(self.expand_merge_u8x16(
6729            Bytes::to_bytes(values),
6730            mask,
6731            Bytes::to_bytes(merge),
6732        ))
6733    }
6734    #[inline(always)]
6735    fn count_ones_i64x2(self, a: i64x2<Self>) -> i64x2<Self> {
6736        [
6737            i64::from(a[0usize].count_ones()),
6738            i64::from(a[1usize].count_ones()),
6739        ]
6740        .simd_into(self)
6741    }
6742    #[inline(always)]
6743    fn count_zeros_i64x2(self, a: i64x2<Self>) -> i64x2<Self> {
6744        [
6745            i64::from(a[0usize].count_zeros()),
6746            i64::from(a[1usize].count_zeros()),
6747        ]
6748        .simd_into(self)
6749    }
6750    #[inline(always)]
6751    fn add_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
6752        crate::kernel!(
6753            #[inline(always)]
6754            fn kernel(token: Sse2, a: i64x2<Sse2>, b: i64x2<Sse2>) -> i64x2<Sse2> {
6755                _mm_add_epi64(a.into(), b.into()).simd_into(token)
6756            }
6757        );
6758        kernel(self, a, b)
6759    }
6760    #[inline(always)]
6761    fn saturating_add_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
6762        [
6763            i64::saturating_add(a[0usize], b[0usize]),
6764            i64::saturating_add(a[1usize], b[1usize]),
6765        ]
6766        .simd_into(self)
6767    }
6768    #[inline(always)]
6769    fn sub_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
6770        crate::kernel!(
6771            #[inline(always)]
6772            fn kernel(token: Sse2, a: i64x2<Sse2>, b: i64x2<Sse2>) -> i64x2<Sse2> {
6773                _mm_sub_epi64(a.into(), b.into()).simd_into(token)
6774            }
6775        );
6776        kernel(self, a, b)
6777    }
6778    #[inline(always)]
6779    fn saturating_sub_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
6780        [
6781            i64::saturating_sub(a[0usize], b[0usize]),
6782            i64::saturating_sub(a[1usize], b[1usize]),
6783        ]
6784        .simd_into(self)
6785    }
6786    #[inline(always)]
6787    fn mul_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
6788        crate::kernel!(
6789            #[inline(always)]
6790            fn kernel(token: Sse2, a: i64x2<Sse2>, b: i64x2<Sse2>) -> i64x2<Sse2> {
6791                let a = a.into();
6792                let b = b.into();
6793                let a_high = _mm_shuffle_epi32::<0xf5>(a);
6794                let b_high = _mm_shuffle_epi32::<0xf5>(b);
6795                let cross = _mm_add_epi64(_mm_mul_epu32(a_high, b), _mm_mul_epu32(a, b_high));
6796                let low = _mm_mul_epu32(a, b);
6797                _mm_add_epi64(low, _mm_slli_epi64::<32>(cross)).simd_into(token)
6798            }
6799        );
6800        kernel(self, a, b)
6801    }
6802    #[inline(always)]
6803    fn and_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
6804        crate::kernel!(
6805            #[inline(always)]
6806            fn kernel(token: Sse2, a: i64x2<Sse2>, b: i64x2<Sse2>) -> i64x2<Sse2> {
6807                _mm_and_si128(a.into(), b.into()).simd_into(token)
6808            }
6809        );
6810        kernel(self, a, b)
6811    }
6812    #[inline(always)]
6813    fn or_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
6814        crate::kernel!(
6815            #[inline(always)]
6816            fn kernel(token: Sse2, a: i64x2<Sse2>, b: i64x2<Sse2>) -> i64x2<Sse2> {
6817                _mm_or_si128(a.into(), b.into()).simd_into(token)
6818            }
6819        );
6820        kernel(self, a, b)
6821    }
6822    #[inline(always)]
6823    fn xor_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
6824        crate::kernel!(
6825            #[inline(always)]
6826            fn kernel(token: Sse2, a: i64x2<Sse2>, b: i64x2<Sse2>) -> i64x2<Sse2> {
6827                _mm_xor_si128(a.into(), b.into()).simd_into(token)
6828            }
6829        );
6830        kernel(self, a, b)
6831    }
6832    #[inline(always)]
6833    fn not_i64x2(self, a: i64x2<Self>) -> i64x2<Self> {
6834        a ^ !0
6835    }
6836    #[inline(always)]
6837    fn shl_i64x2(self, a: i64x2<Self>, shift: u32) -> i64x2<Self> {
6838        crate::kernel!(
6839            #[inline(always)]
6840            fn kernel(token: Sse2, a: i64x2<Sse2>, shift: u32) -> i64x2<Sse2> {
6841                _mm_sll_epi64(a.into(), _mm_cvtsi32_si128(shift.cast_signed())).simd_into(token)
6842            }
6843        );
6844        kernel(self, a, shift)
6845    }
6846    #[inline(always)]
6847    fn shlv_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
6848        [
6849            i64::wrapping_shl(a[0usize], b[0usize] as u32),
6850            i64::wrapping_shl(a[1usize], b[1usize] as u32),
6851        ]
6852        .simd_into(self)
6853    }
6854    #[inline(always)]
6855    fn shr_i64x2(self, a: i64x2<Self>, shift: u32) -> i64x2<Self> {
6856        crate::kernel!(
6857            #[inline(always)]
6858            fn kernel(token: Sse2, a: i64x2<Sse2>, shift: u32) -> i64x2<Sse2> {
6859                let value = a.into();
6860                let count = _mm_cvtsi32_si128(shift.cast_signed());
6861                let shifted_bias = _mm_srl_epi64(_mm_set1_epi64x(i64::MIN), count);
6862                let shifted = _mm_srl_epi64(value, count);
6863                _mm_sub_epi64(_mm_xor_si128(shifted, shifted_bias), shifted_bias).simd_into(token)
6864            }
6865        );
6866        kernel(self, a, shift)
6867    }
6868    #[inline(always)]
6869    fn shrv_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
6870        [
6871            i64::wrapping_shr(a[0usize], b[0usize] as u32),
6872            i64::wrapping_shr(a[1usize], b[1usize] as u32),
6873        ]
6874        .simd_into(self)
6875    }
6876    #[inline(always)]
6877    fn reduce_max_i64x2(self, a: i64x2<Self>) -> i64 {
6878        crate::kernel!(
6879            #[inline(always)]
6880            fn kernel(token: Sse2, a: i64x2<Sse2>) -> i64 {
6881                let lanes: [i64; 2] = a.into();
6882                lanes[0].max(lanes[1])
6883            }
6884        );
6885        kernel(self, a)
6886    }
6887    #[inline(always)]
6888    fn reduce_min_i64x2(self, a: i64x2<Self>) -> i64 {
6889        crate::kernel!(
6890            #[inline(always)]
6891            fn kernel(token: Sse2, a: i64x2<Sse2>) -> i64 {
6892                let lanes: [i64; 2] = a.into();
6893                lanes[0].min(lanes[1])
6894            }
6895        );
6896        kernel(self, a)
6897    }
6898    #[inline(always)]
6899    fn reduce_sum_i64x2(self, a: i64x2<Self>) -> i64 {
6900        crate::kernel!(
6901            #[inline(always)]
6902            fn kernel(token: Sse2, a: i64x2<Sse2>) -> i64 {
6903                let sum: __m128i = a.into();
6904                let sum = _mm_add_epi64(sum, _mm_srli_si128::<8>(sum));
6905                let lanes: [i64; 2usize] = crate::transmute::checked_transmute_copy(&sum);
6906                lanes[0]
6907            }
6908        );
6909        kernel(self, a)
6910    }
6911    #[inline(always)]
6912    fn reduce_product_i64x2(self, a: i64x2<Self>) -> i64 {
6913        let mul_level_0: [i64; 1usize] = [a[0usize].wrapping_mul(a[1usize])];
6914        mul_level_0[0]
6915    }
6916    #[inline(always)]
6917    fn max_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
6918        [
6919            i64::max(a[0usize], b[0usize]),
6920            i64::max(a[1usize], b[1usize]),
6921        ]
6922        .simd_into(self)
6923    }
6924    #[inline(always)]
6925    fn min_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
6926        [
6927            i64::min(a[0usize], b[0usize]),
6928            i64::min(a[1usize], b[1usize]),
6929        ]
6930        .simd_into(self)
6931    }
6932    #[inline(always)]
6933    fn clamp_i64x2(self, a: i64x2<Self>, b: i64x2<Self>, c: i64x2<Self>) -> i64x2<Self> {
6934        debug_assert!(
6935            b.simd_le(c).all_true(),
6936            "clamp requires min <= max for all elements"
6937        );
6938        a.max(b).min(c)
6939    }
6940    #[inline(always)]
6941    fn simd_eq_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> mask64x2<Self> {
6942        crate::kernel!(
6943            #[inline(always)]
6944            fn kernel(token: Sse2, a: i64x2<Sse2>, b: i64x2<Sse2>) -> mask64x2<Sse2> {
6945                {
6946                    let eq32 = _mm_cmpeq_epi32(a.into(), b.into());
6947                    let swapped = _mm_shuffle_epi32::<0b10_11_00_01>(eq32);
6948                    _mm_and_si128(eq32, swapped)
6949                }
6950                .simd_into(token)
6951            }
6952        );
6953        kernel(self, a, b)
6954    }
6955    #[inline(always)]
6956    fn simd_lt_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> mask64x2<Self> {
6957        [
6958            -(i64::lt(&a[0usize], &b[0usize]) as i64),
6959            -(i64::lt(&a[1usize], &b[1usize]) as i64),
6960        ]
6961        .simd_into(self)
6962    }
6963    #[inline(always)]
6964    fn simd_le_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> mask64x2<Self> {
6965        [
6966            -(i64::le(&a[0usize], &b[0usize]) as i64),
6967            -(i64::le(&a[1usize], &b[1usize]) as i64),
6968        ]
6969        .simd_into(self)
6970    }
6971    #[inline(always)]
6972    fn zip_low_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
6973        crate::kernel!(
6974            #[inline(always)]
6975            fn kernel(token: Sse2, a: i64x2<Sse2>, b: i64x2<Sse2>) -> i64x2<Sse2> {
6976                _mm_unpacklo_epi64(a.into(), b.into()).simd_into(token)
6977            }
6978        );
6979        kernel(self, a, b)
6980    }
6981    #[inline(always)]
6982    fn zip_high_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
6983        crate::kernel!(
6984            #[inline(always)]
6985            fn kernel(token: Sse2, a: i64x2<Sse2>, b: i64x2<Sse2>) -> i64x2<Sse2> {
6986                _mm_unpackhi_epi64(a.into(), b.into()).simd_into(token)
6987            }
6988        );
6989        kernel(self, a, b)
6990    }
6991    #[inline(always)]
6992    fn unzip_low_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
6993        crate::kernel!(
6994            #[inline(always)]
6995            fn kernel(token: Sse2, a: i64x2<Sse2>, b: i64x2<Sse2>) -> i64x2<Sse2> {
6996                _mm_unpacklo_epi64(a.into(), b.into()).simd_into(token)
6997            }
6998        );
6999        kernel(self, a, b)
7000    }
7001    #[inline(always)]
7002    fn unzip_high_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self> {
7003        crate::kernel!(
7004            #[inline(always)]
7005            fn kernel(token: Sse2, a: i64x2<Sse2>, b: i64x2<Sse2>) -> i64x2<Sse2> {
7006                _mm_unpackhi_epi64(a.into(), b.into()).simd_into(token)
7007            }
7008        );
7009        kernel(self, a, b)
7010    }
7011    #[inline(always)]
7012    fn interleave_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> (i64x2<Self>, i64x2<Self>) {
7013        (self.zip_low_i64x2(a, b), self.zip_high_i64x2(a, b))
7014    }
7015    #[inline(always)]
7016    fn deinterleave_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> (i64x2<Self>, i64x2<Self>) {
7017        (self.unzip_low_i64x2(a, b), self.unzip_high_i64x2(a, b))
7018    }
7019    #[inline(always)]
7020    fn select_i64x2(self, a: mask64x2<Self>, b: i64x2<Self>, c: i64x2<Self>) -> i64x2<Self> {
7021        crate::kernel!(
7022            #[inline(always)]
7023            fn kernel(
7024                token: Sse2,
7025                a: mask64x2<Sse2>,
7026                b: i64x2<Sse2>,
7027                c: i64x2<Sse2>,
7028            ) -> i64x2<Sse2> {
7029                _mm_or_si128(
7030                    _mm_and_si128(a.into(), b.into()),
7031                    _mm_andnot_si128(a.into(), c.into()),
7032                )
7033                .simd_into(token)
7034            }
7035        );
7036        kernel(self, a, b, c)
7037    }
7038    #[inline(always)]
7039    fn combine_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x4<Self> {
7040        i64x4 {
7041            val: crate::support::Aligned256([a.val.0, b.val.0]),
7042            simd: self,
7043        }
7044    }
7045    #[inline(always)]
7046    fn neg_i64x2(self, a: i64x2<Self>) -> i64x2<Self> {
7047        crate::kernel!(
7048            #[inline(always)]
7049            fn kernel(token: Sse2, a: i64x2<Sse2>) -> i64x2<Sse2> {
7050                _mm_sub_epi64(_mm_setzero_si128(), a.into()).simd_into(token)
7051            }
7052        );
7053        kernel(self, a)
7054    }
7055    #[inline(always)]
7056    fn load_four_interleaved_i64x2(self, src: &[i64; 8usize]) -> [i64x2<Self>; 4usize] {
7057        crate::kernel!(
7058            #[inline(always)]
7059            fn kernel(token: Sse2, src: &[i64; 8usize]) -> [i64x2<Sse2>; 4usize] {
7060                let (chunks, []) = src.as_chunks::<2usize>() else {
7061                    unreachable!()
7062                };
7063                let v0: __m128i =
7064                    crate::transmute::checked_transmute_copy::<[i64; 2usize], __m128i>(&chunks[0]);
7065                let v1: __m128i =
7066                    crate::transmute::checked_transmute_copy::<[i64; 2usize], __m128i>(&chunks[1]);
7067                let v2: __m128i =
7068                    crate::transmute::checked_transmute_copy::<[i64; 2usize], __m128i>(&chunks[2]);
7069                let v3: __m128i =
7070                    crate::transmute::checked_transmute_copy::<[i64; 2usize], __m128i>(&chunks[3]);
7071                let out0 = _mm_unpacklo_epi64(v0, v2);
7072                let out1 = _mm_unpackhi_epi64(v0, v2);
7073                let out2 = _mm_unpacklo_epi64(v1, v3);
7074                let out3 = _mm_unpackhi_epi64(v1, v3);
7075                [
7076                    out0.simd_into(token),
7077                    out1.simd_into(token),
7078                    out2.simd_into(token),
7079                    out3.simd_into(token),
7080                ]
7081            }
7082        );
7083        kernel(self, src)
7084    }
7085    #[inline(always)]
7086    fn store_four_interleaved_i64x2(
7087        self,
7088        vectors: [i64x2<Self>; 4usize],
7089        dest: &mut [i64; 8usize],
7090    ) -> () {
7091        crate::kernel!(
7092            #[inline(always)]
7093            fn kernel(token: Sse2, vectors: [i64x2<Sse2>; 4usize], dest: &mut [i64; 8usize]) -> () {
7094                let _ = token;
7095                let v0: __m128i = vectors[0].into();
7096                let v1: __m128i = vectors[1].into();
7097                let v2: __m128i = vectors[2].into();
7098                let v3: __m128i = vectors[3].into();
7099                let out0 = _mm_unpacklo_epi64(v0, v1);
7100                let out1 = _mm_unpacklo_epi64(v2, v3);
7101                let out2 = _mm_unpackhi_epi64(v0, v1);
7102                let out3 = _mm_unpackhi_epi64(v2, v3);
7103                let (chunks, []) = dest.as_chunks_mut::<2usize>() else {
7104                    unreachable!()
7105                };
7106                crate::transmute::checked_transmute_store::<__m128i, [i64; 2usize]>(
7107                    out0,
7108                    &mut chunks[0],
7109                );
7110                crate::transmute::checked_transmute_store::<__m128i, [i64; 2usize]>(
7111                    out1,
7112                    &mut chunks[1],
7113                );
7114                crate::transmute::checked_transmute_store::<__m128i, [i64; 2usize]>(
7115                    out2,
7116                    &mut chunks[2],
7117                );
7118                crate::transmute::checked_transmute_store::<__m128i, [i64; 2usize]>(
7119                    out3,
7120                    &mut chunks[3],
7121                );
7122            }
7123        );
7124        kernel(self, vectors, dest);
7125    }
7126    #[inline(always)]
7127    fn narrow_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i32x4<Self> {
7128        crate::kernel!(
7129            #[inline(always)]
7130            fn kernel(token: Sse2, a: i64x2<Sse2>, b: i64x2<Sse2>) -> i32x4<Sse2> {
7131                _mm_castps_si128(_mm_shuffle_ps::<0x88>(
7132                    _mm_castsi128_ps(a.into()),
7133                    _mm_castsi128_ps(b.into()),
7134                ))
7135                .simd_into(token)
7136            }
7137        );
7138        kernel(self, a, b)
7139    }
7140    #[inline(always)]
7141    fn saturating_narrow_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i32x4<Self> {
7142        [
7143            a[0usize].clamp(i32::MIN as i64, i32::MAX as i64) as i32,
7144            a[1usize].clamp(i32::MIN as i64, i32::MAX as i64) as i32,
7145            b[0usize].clamp(i32::MIN as i64, i32::MAX as i64) as i32,
7146            b[1usize].clamp(i32::MIN as i64, i32::MAX as i64) as i32,
7147        ]
7148        .simd_into(self)
7149    }
7150    #[inline(always)]
7151    fn relaxed_narrow_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i32x4<Self> {
7152        debug_assert!(
7153            a.as_slice()
7154                .iter()
7155                .chain(b.as_slice())
7156                .all(|&value| { value >= i32::MIN as i64 && value <= i32::MAX as i64 }),
7157            "relaxed_narrow inputs must fit in the destination type",
7158        );
7159        self.narrow_i64x2(a, b)
7160    }
7161    #[inline(always)]
7162    fn cvt_f64_i64x2(self, a: i64x2<Self>) -> f64x2<Self> {
7163        [a[0usize] as f64, a[1usize] as f64].simd_into(self)
7164    }
7165    #[inline(always)]
7166    fn splat_u64x2(self, val: u64) -> u64x2<Self> {
7167        crate::kernel!(
7168            #[inline(always)]
7169            fn kernel(token: Sse2, val: u64) -> u64x2<Sse2> {
7170                _mm_set1_epi64x(val.cast_signed()).simd_into(token)
7171            }
7172        );
7173        kernel(self, val)
7174    }
7175    #[inline(always)]
7176    fn reverse_u64x2(self, a: u64x2<Self>) -> u64x2<Self> {
7177        [a[1usize], a[0usize]].simd_into(self)
7178    }
7179    #[inline(always)]
7180    fn slide_u64x2<const SHIFT: usize>(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7181        if SHIFT >= 2usize {
7182            return b;
7183        }
7184        let result = dyn_alignr_128(
7185            self,
7186            Bytes::to_bytes(b).val.0,
7187            Bytes::to_bytes(a).val.0,
7188            SHIFT * 8usize,
7189        );
7190        Bytes::from_bytes(u8x16 {
7191            val: crate::support::Aligned128(result),
7192            simd: self,
7193        })
7194    }
7195    #[inline(always)]
7196    fn compress_u64x2(self, values: u64x2<Self>, mask: mask64x2<Self>) -> u64x2<Self> {
7197        let mask = mask8x16 {
7198            val: crate::transmute::checked_transmute_copy(&mask.val),
7199            simd: self,
7200        };
7201        Bytes::from_bytes(self.compress_u8x16(Bytes::to_bytes(values), mask))
7202    }
7203    #[inline(always)]
7204    fn compress_merge_u64x2(
7205        self,
7206        values: u64x2<Self>,
7207        mask: mask64x2<Self>,
7208        merge: u64x2<Self>,
7209    ) -> u64x2<Self> {
7210        let mask = mask8x16 {
7211            val: crate::transmute::checked_transmute_copy(&mask.val),
7212            simd: self,
7213        };
7214        Bytes::from_bytes(self.compress_merge_u8x16(
7215            Bytes::to_bytes(values),
7216            mask,
7217            Bytes::to_bytes(merge),
7218        ))
7219    }
7220    #[inline(always)]
7221    fn expand_u64x2(self, values: u64x2<Self>, mask: mask64x2<Self>) -> u64x2<Self> {
7222        let mask = mask8x16 {
7223            val: crate::transmute::checked_transmute_copy(&mask.val),
7224            simd: self,
7225        };
7226        Bytes::from_bytes(self.expand_u8x16(Bytes::to_bytes(values), mask))
7227    }
7228    #[inline(always)]
7229    fn expand_merge_u64x2(
7230        self,
7231        values: u64x2<Self>,
7232        mask: mask64x2<Self>,
7233        merge: u64x2<Self>,
7234    ) -> u64x2<Self> {
7235        let mask = mask8x16 {
7236            val: crate::transmute::checked_transmute_copy(&mask.val),
7237            simd: self,
7238        };
7239        Bytes::from_bytes(self.expand_merge_u8x16(
7240            Bytes::to_bytes(values),
7241            mask,
7242            Bytes::to_bytes(merge),
7243        ))
7244    }
7245    #[inline(always)]
7246    fn count_ones_u64x2(self, a: u64x2<Self>) -> u64x2<Self> {
7247        [
7248            u64::from(a[0usize].count_ones()),
7249            u64::from(a[1usize].count_ones()),
7250        ]
7251        .simd_into(self)
7252    }
7253    #[inline(always)]
7254    fn count_zeros_u64x2(self, a: u64x2<Self>) -> u64x2<Self> {
7255        [
7256            u64::from(a[0usize].count_zeros()),
7257            u64::from(a[1usize].count_zeros()),
7258        ]
7259        .simd_into(self)
7260    }
7261    #[inline(always)]
7262    fn add_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7263        crate::kernel!(
7264            #[inline(always)]
7265            fn kernel(token: Sse2, a: u64x2<Sse2>, b: u64x2<Sse2>) -> u64x2<Sse2> {
7266                _mm_add_epi64(a.into(), b.into()).simd_into(token)
7267            }
7268        );
7269        kernel(self, a, b)
7270    }
7271    #[inline(always)]
7272    fn saturating_add_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7273        [
7274            u64::saturating_add(a[0usize], b[0usize]),
7275            u64::saturating_add(a[1usize], b[1usize]),
7276        ]
7277        .simd_into(self)
7278    }
7279    #[inline(always)]
7280    fn sub_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7281        crate::kernel!(
7282            #[inline(always)]
7283            fn kernel(token: Sse2, a: u64x2<Sse2>, b: u64x2<Sse2>) -> u64x2<Sse2> {
7284                _mm_sub_epi64(a.into(), b.into()).simd_into(token)
7285            }
7286        );
7287        kernel(self, a, b)
7288    }
7289    #[inline(always)]
7290    fn saturating_sub_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7291        [
7292            u64::saturating_sub(a[0usize], b[0usize]),
7293            u64::saturating_sub(a[1usize], b[1usize]),
7294        ]
7295        .simd_into(self)
7296    }
7297    #[inline(always)]
7298    fn mul_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7299        crate::kernel!(
7300            #[inline(always)]
7301            fn kernel(token: Sse2, a: u64x2<Sse2>, b: u64x2<Sse2>) -> u64x2<Sse2> {
7302                let a = a.into();
7303                let b = b.into();
7304                let a_high = _mm_shuffle_epi32::<0xf5>(a);
7305                let b_high = _mm_shuffle_epi32::<0xf5>(b);
7306                let cross = _mm_add_epi64(_mm_mul_epu32(a_high, b), _mm_mul_epu32(a, b_high));
7307                let low = _mm_mul_epu32(a, b);
7308                _mm_add_epi64(low, _mm_slli_epi64::<32>(cross)).simd_into(token)
7309            }
7310        );
7311        kernel(self, a, b)
7312    }
7313    #[inline(always)]
7314    fn and_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7315        crate::kernel!(
7316            #[inline(always)]
7317            fn kernel(token: Sse2, a: u64x2<Sse2>, b: u64x2<Sse2>) -> u64x2<Sse2> {
7318                _mm_and_si128(a.into(), b.into()).simd_into(token)
7319            }
7320        );
7321        kernel(self, a, b)
7322    }
7323    #[inline(always)]
7324    fn or_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7325        crate::kernel!(
7326            #[inline(always)]
7327            fn kernel(token: Sse2, a: u64x2<Sse2>, b: u64x2<Sse2>) -> u64x2<Sse2> {
7328                _mm_or_si128(a.into(), b.into()).simd_into(token)
7329            }
7330        );
7331        kernel(self, a, b)
7332    }
7333    #[inline(always)]
7334    fn xor_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7335        crate::kernel!(
7336            #[inline(always)]
7337            fn kernel(token: Sse2, a: u64x2<Sse2>, b: u64x2<Sse2>) -> u64x2<Sse2> {
7338                _mm_xor_si128(a.into(), b.into()).simd_into(token)
7339            }
7340        );
7341        kernel(self, a, b)
7342    }
7343    #[inline(always)]
7344    fn not_u64x2(self, a: u64x2<Self>) -> u64x2<Self> {
7345        a ^ !0
7346    }
7347    #[inline(always)]
7348    fn shl_u64x2(self, a: u64x2<Self>, shift: u32) -> u64x2<Self> {
7349        crate::kernel!(
7350            #[inline(always)]
7351            fn kernel(token: Sse2, a: u64x2<Sse2>, shift: u32) -> u64x2<Sse2> {
7352                _mm_sll_epi64(a.into(), _mm_cvtsi32_si128(shift.cast_signed())).simd_into(token)
7353            }
7354        );
7355        kernel(self, a, shift)
7356    }
7357    #[inline(always)]
7358    fn shlv_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7359        [
7360            u64::wrapping_shl(a[0usize], b[0usize] as u32),
7361            u64::wrapping_shl(a[1usize], b[1usize] as u32),
7362        ]
7363        .simd_into(self)
7364    }
7365    #[inline(always)]
7366    fn shr_u64x2(self, a: u64x2<Self>, shift: u32) -> u64x2<Self> {
7367        crate::kernel!(
7368            #[inline(always)]
7369            fn kernel(token: Sse2, a: u64x2<Sse2>, shift: u32) -> u64x2<Sse2> {
7370                _mm_srl_epi64(a.into(), _mm_cvtsi32_si128(shift.cast_signed())).simd_into(token)
7371            }
7372        );
7373        kernel(self, a, shift)
7374    }
7375    #[inline(always)]
7376    fn shrv_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7377        [
7378            u64::wrapping_shr(a[0usize], b[0usize] as u32),
7379            u64::wrapping_shr(a[1usize], b[1usize] as u32),
7380        ]
7381        .simd_into(self)
7382    }
7383    #[inline(always)]
7384    fn reduce_max_u64x2(self, a: u64x2<Self>) -> u64 {
7385        crate::kernel!(
7386            #[inline(always)]
7387            fn kernel(token: Sse2, a: u64x2<Sse2>) -> u64 {
7388                let lanes: [u64; 2] = a.into();
7389                lanes[0].max(lanes[1])
7390            }
7391        );
7392        kernel(self, a)
7393    }
7394    #[inline(always)]
7395    fn reduce_min_u64x2(self, a: u64x2<Self>) -> u64 {
7396        crate::kernel!(
7397            #[inline(always)]
7398            fn kernel(token: Sse2, a: u64x2<Sse2>) -> u64 {
7399                let lanes: [u64; 2] = a.into();
7400                lanes[0].min(lanes[1])
7401            }
7402        );
7403        kernel(self, a)
7404    }
7405    #[inline(always)]
7406    fn reduce_sum_u64x2(self, a: u64x2<Self>) -> u64 {
7407        crate::kernel!(
7408            #[inline(always)]
7409            fn kernel(token: Sse2, a: u64x2<Sse2>) -> u64 {
7410                let sum: __m128i = a.into();
7411                let sum = _mm_add_epi64(sum, _mm_srli_si128::<8>(sum));
7412                let lanes: [u64; 2usize] = crate::transmute::checked_transmute_copy(&sum);
7413                lanes[0]
7414            }
7415        );
7416        kernel(self, a)
7417    }
7418    #[inline(always)]
7419    fn reduce_product_u64x2(self, a: u64x2<Self>) -> u64 {
7420        let mul_level_0: [u64; 1usize] = [a[0usize].wrapping_mul(a[1usize])];
7421        mul_level_0[0]
7422    }
7423    #[inline(always)]
7424    fn max_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7425        [
7426            u64::max(a[0usize], b[0usize]),
7427            u64::max(a[1usize], b[1usize]),
7428        ]
7429        .simd_into(self)
7430    }
7431    #[inline(always)]
7432    fn min_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7433        [
7434            u64::min(a[0usize], b[0usize]),
7435            u64::min(a[1usize], b[1usize]),
7436        ]
7437        .simd_into(self)
7438    }
7439    #[inline(always)]
7440    fn clamp_u64x2(self, a: u64x2<Self>, b: u64x2<Self>, c: u64x2<Self>) -> u64x2<Self> {
7441        debug_assert!(
7442            b.simd_le(c).all_true(),
7443            "clamp requires min <= max for all elements"
7444        );
7445        a.max(b).min(c)
7446    }
7447    #[inline(always)]
7448    fn simd_eq_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> mask64x2<Self> {
7449        crate::kernel!(
7450            #[inline(always)]
7451            fn kernel(token: Sse2, a: u64x2<Sse2>, b: u64x2<Sse2>) -> mask64x2<Sse2> {
7452                {
7453                    let eq32 = _mm_cmpeq_epi32(a.into(), b.into());
7454                    let swapped = _mm_shuffle_epi32::<0b10_11_00_01>(eq32);
7455                    _mm_and_si128(eq32, swapped)
7456                }
7457                .simd_into(token)
7458            }
7459        );
7460        kernel(self, a, b)
7461    }
7462    #[inline(always)]
7463    fn simd_lt_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> mask64x2<Self> {
7464        [
7465            -(u64::lt(&a[0usize], &b[0usize]) as i64),
7466            -(u64::lt(&a[1usize], &b[1usize]) as i64),
7467        ]
7468        .simd_into(self)
7469    }
7470    #[inline(always)]
7471    fn simd_le_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> mask64x2<Self> {
7472        [
7473            -(u64::le(&a[0usize], &b[0usize]) as i64),
7474            -(u64::le(&a[1usize], &b[1usize]) as i64),
7475        ]
7476        .simd_into(self)
7477    }
7478    #[inline(always)]
7479    fn zip_low_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7480        crate::kernel!(
7481            #[inline(always)]
7482            fn kernel(token: Sse2, a: u64x2<Sse2>, b: u64x2<Sse2>) -> u64x2<Sse2> {
7483                _mm_unpacklo_epi64(a.into(), b.into()).simd_into(token)
7484            }
7485        );
7486        kernel(self, a, b)
7487    }
7488    #[inline(always)]
7489    fn zip_high_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7490        crate::kernel!(
7491            #[inline(always)]
7492            fn kernel(token: Sse2, a: u64x2<Sse2>, b: u64x2<Sse2>) -> u64x2<Sse2> {
7493                _mm_unpackhi_epi64(a.into(), b.into()).simd_into(token)
7494            }
7495        );
7496        kernel(self, a, b)
7497    }
7498    #[inline(always)]
7499    fn unzip_low_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7500        crate::kernel!(
7501            #[inline(always)]
7502            fn kernel(token: Sse2, a: u64x2<Sse2>, b: u64x2<Sse2>) -> u64x2<Sse2> {
7503                _mm_unpacklo_epi64(a.into(), b.into()).simd_into(token)
7504            }
7505        );
7506        kernel(self, a, b)
7507    }
7508    #[inline(always)]
7509    fn unzip_high_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self> {
7510        crate::kernel!(
7511            #[inline(always)]
7512            fn kernel(token: Sse2, a: u64x2<Sse2>, b: u64x2<Sse2>) -> u64x2<Sse2> {
7513                _mm_unpackhi_epi64(a.into(), b.into()).simd_into(token)
7514            }
7515        );
7516        kernel(self, a, b)
7517    }
7518    #[inline(always)]
7519    fn interleave_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> (u64x2<Self>, u64x2<Self>) {
7520        (self.zip_low_u64x2(a, b), self.zip_high_u64x2(a, b))
7521    }
7522    #[inline(always)]
7523    fn deinterleave_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> (u64x2<Self>, u64x2<Self>) {
7524        (self.unzip_low_u64x2(a, b), self.unzip_high_u64x2(a, b))
7525    }
7526    #[inline(always)]
7527    fn select_u64x2(self, a: mask64x2<Self>, b: u64x2<Self>, c: u64x2<Self>) -> u64x2<Self> {
7528        crate::kernel!(
7529            #[inline(always)]
7530            fn kernel(
7531                token: Sse2,
7532                a: mask64x2<Sse2>,
7533                b: u64x2<Sse2>,
7534                c: u64x2<Sse2>,
7535            ) -> u64x2<Sse2> {
7536                _mm_or_si128(
7537                    _mm_and_si128(a.into(), b.into()),
7538                    _mm_andnot_si128(a.into(), c.into()),
7539                )
7540                .simd_into(token)
7541            }
7542        );
7543        kernel(self, a, b, c)
7544    }
7545    #[inline(always)]
7546    fn combine_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x4<Self> {
7547        u64x4 {
7548            val: crate::support::Aligned256([a.val.0, b.val.0]),
7549            simd: self,
7550        }
7551    }
7552    #[inline(always)]
7553    fn load_four_interleaved_u64x2(self, src: &[u64; 8usize]) -> [u64x2<Self>; 4usize] {
7554        crate::kernel!(
7555            #[inline(always)]
7556            fn kernel(token: Sse2, src: &[u64; 8usize]) -> [u64x2<Sse2>; 4usize] {
7557                let (chunks, []) = src.as_chunks::<2usize>() else {
7558                    unreachable!()
7559                };
7560                let v0: __m128i =
7561                    crate::transmute::checked_transmute_copy::<[u64; 2usize], __m128i>(&chunks[0]);
7562                let v1: __m128i =
7563                    crate::transmute::checked_transmute_copy::<[u64; 2usize], __m128i>(&chunks[1]);
7564                let v2: __m128i =
7565                    crate::transmute::checked_transmute_copy::<[u64; 2usize], __m128i>(&chunks[2]);
7566                let v3: __m128i =
7567                    crate::transmute::checked_transmute_copy::<[u64; 2usize], __m128i>(&chunks[3]);
7568                let out0 = _mm_unpacklo_epi64(v0, v2);
7569                let out1 = _mm_unpackhi_epi64(v0, v2);
7570                let out2 = _mm_unpacklo_epi64(v1, v3);
7571                let out3 = _mm_unpackhi_epi64(v1, v3);
7572                [
7573                    out0.simd_into(token),
7574                    out1.simd_into(token),
7575                    out2.simd_into(token),
7576                    out3.simd_into(token),
7577                ]
7578            }
7579        );
7580        kernel(self, src)
7581    }
7582    #[inline(always)]
7583    fn store_four_interleaved_u64x2(
7584        self,
7585        vectors: [u64x2<Self>; 4usize],
7586        dest: &mut [u64; 8usize],
7587    ) -> () {
7588        crate::kernel!(
7589            #[inline(always)]
7590            fn kernel(token: Sse2, vectors: [u64x2<Sse2>; 4usize], dest: &mut [u64; 8usize]) -> () {
7591                let _ = token;
7592                let v0: __m128i = vectors[0].into();
7593                let v1: __m128i = vectors[1].into();
7594                let v2: __m128i = vectors[2].into();
7595                let v3: __m128i = vectors[3].into();
7596                let out0 = _mm_unpacklo_epi64(v0, v1);
7597                let out1 = _mm_unpacklo_epi64(v2, v3);
7598                let out2 = _mm_unpackhi_epi64(v0, v1);
7599                let out3 = _mm_unpackhi_epi64(v2, v3);
7600                let (chunks, []) = dest.as_chunks_mut::<2usize>() else {
7601                    unreachable!()
7602                };
7603                crate::transmute::checked_transmute_store::<__m128i, [u64; 2usize]>(
7604                    out0,
7605                    &mut chunks[0],
7606                );
7607                crate::transmute::checked_transmute_store::<__m128i, [u64; 2usize]>(
7608                    out1,
7609                    &mut chunks[1],
7610                );
7611                crate::transmute::checked_transmute_store::<__m128i, [u64; 2usize]>(
7612                    out2,
7613                    &mut chunks[2],
7614                );
7615                crate::transmute::checked_transmute_store::<__m128i, [u64; 2usize]>(
7616                    out3,
7617                    &mut chunks[3],
7618                );
7619            }
7620        );
7621        kernel(self, vectors, dest);
7622    }
7623    #[inline(always)]
7624    fn narrow_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u32x4<Self> {
7625        crate::kernel!(
7626            #[inline(always)]
7627            fn kernel(token: Sse2, a: u64x2<Sse2>, b: u64x2<Sse2>) -> u32x4<Sse2> {
7628                _mm_castps_si128(_mm_shuffle_ps::<0x88>(
7629                    _mm_castsi128_ps(a.into()),
7630                    _mm_castsi128_ps(b.into()),
7631                ))
7632                .simd_into(token)
7633            }
7634        );
7635        kernel(self, a, b)
7636    }
7637    #[inline(always)]
7638    fn saturating_narrow_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u32x4<Self> {
7639        [
7640            a[0usize].clamp(u32::MIN as u64, u32::MAX as u64) as u32,
7641            a[1usize].clamp(u32::MIN as u64, u32::MAX as u64) as u32,
7642            b[0usize].clamp(u32::MIN as u64, u32::MAX as u64) as u32,
7643            b[1usize].clamp(u32::MIN as u64, u32::MAX as u64) as u32,
7644        ]
7645        .simd_into(self)
7646    }
7647    #[inline(always)]
7648    fn relaxed_narrow_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u32x4<Self> {
7649        debug_assert!(
7650            a.as_slice()
7651                .iter()
7652                .chain(b.as_slice())
7653                .all(|&value| { value >= u32::MIN as u64 && value <= u32::MAX as u64 }),
7654            "relaxed_narrow inputs must fit in the destination type",
7655        );
7656        self.narrow_u64x2(a, b)
7657    }
7658    #[inline(always)]
7659    fn cvt_f64_u64x2(self, a: u64x2<Self>) -> f64x2<Self> {
7660        [a[0usize] as f64, a[1usize] as f64].simd_into(self)
7661    }
7662    #[inline(always)]
7663    fn splat_mask64x2(self, val: bool) -> mask64x2<Self> {
7664        crate::kernel!(
7665            #[inline(always)]
7666            fn kernel(token: Sse2, val: bool) -> mask64x2<Sse2> {
7667                let val: i64 = if val { !0 } else { 0 };
7668                _mm_set1_epi64x(val).simd_into(token)
7669            }
7670        );
7671        kernel(self, val)
7672    }
7673    #[inline(always)]
7674    fn from_bitmask_mask64x2(self, bits: u64) -> mask64x2<Self> {
7675        let lanes: [i64; 2usize] = [
7676            if bits & 1 != 0 { !0 } else { 0 },
7677            if (bits >> 1usize) & 1 != 0 { !0 } else { 0 },
7678        ];
7679        lanes.simd_into(self)
7680    }
7681    #[inline(always)]
7682    fn to_bitmask_mask64x2(self, a: mask64x2<Self>) -> u64 {
7683        crate::kernel!(
7684            #[inline(always)]
7685            fn kernel(token: Sse2, a: mask64x2<Sse2>) -> u64 {
7686                _mm_movemask_pd(_mm_castsi128_pd(a.into())) as u32 as u64
7687            }
7688        );
7689        kernel(self, a)
7690    }
7691    #[inline(always)]
7692    fn from_vector_mask64x2(self, vector: i64x2<Self>) -> mask64x2<Self> {
7693        mask64x2 {
7694            val: vector.val,
7695            simd: self,
7696        }
7697    }
7698    #[inline(always)]
7699    fn to_vector_mask64x2(self, a: mask64x2<Self>) -> i64x2<Self> {
7700        i64x2 {
7701            val: a.val,
7702            simd: self,
7703        }
7704    }
7705    #[inline(always)]
7706    fn set_mask64x2(self, a: &mut mask64x2<Self>, index: usize, value: bool) -> () {
7707        assert!(
7708            index < 2usize,
7709            "mask lane index {index} is out of bounds for {} lanes",
7710            2usize
7711        );
7712        let mut lanes: [i64; 2usize] = (*a).into();
7713        lanes[index] = if value { !0 } else { 0 };
7714        *a = lanes.simd_into(self);
7715    }
7716    #[inline(always)]
7717    fn rotate_elements_left_mask64x2<const OFFSET: usize>(
7718        self,
7719        a: mask64x2<Self>,
7720    ) -> mask64x2<Self> {
7721        let int = i64x2 {
7722            val: crate::transmute::checked_transmute_copy(&a.val),
7723            simd: self,
7724        };
7725        let rotated = int.rotate_elements_left::<OFFSET>();
7726        mask64x2 {
7727            val: crate::transmute::checked_transmute_copy(&rotated.val),
7728            simd: self,
7729        }
7730    }
7731    #[inline(always)]
7732    fn rotate_elements_right_mask64x2<const OFFSET: usize>(
7733        self,
7734        a: mask64x2<Self>,
7735    ) -> mask64x2<Self> {
7736        let int = i64x2 {
7737            val: crate::transmute::checked_transmute_copy(&a.val),
7738            simd: self,
7739        };
7740        let rotated = int.rotate_elements_right::<OFFSET>();
7741        mask64x2 {
7742            val: crate::transmute::checked_transmute_copy(&rotated.val),
7743            simd: self,
7744        }
7745    }
7746    #[inline(always)]
7747    fn and_mask64x2(self, a: mask64x2<Self>, b: mask64x2<Self>) -> mask64x2<Self> {
7748        crate::kernel!(
7749            #[inline(always)]
7750            fn kernel(token: Sse2, a: mask64x2<Sse2>, b: mask64x2<Sse2>) -> mask64x2<Sse2> {
7751                _mm_and_si128(a.into(), b.into()).simd_into(token)
7752            }
7753        );
7754        kernel(self, a, b)
7755    }
7756    #[inline(always)]
7757    fn or_mask64x2(self, a: mask64x2<Self>, b: mask64x2<Self>) -> mask64x2<Self> {
7758        crate::kernel!(
7759            #[inline(always)]
7760            fn kernel(token: Sse2, a: mask64x2<Sse2>, b: mask64x2<Sse2>) -> mask64x2<Sse2> {
7761                _mm_or_si128(a.into(), b.into()).simd_into(token)
7762            }
7763        );
7764        kernel(self, a, b)
7765    }
7766    #[inline(always)]
7767    fn xor_mask64x2(self, a: mask64x2<Self>, b: mask64x2<Self>) -> mask64x2<Self> {
7768        crate::kernel!(
7769            #[inline(always)]
7770            fn kernel(token: Sse2, a: mask64x2<Sse2>, b: mask64x2<Sse2>) -> mask64x2<Sse2> {
7771                _mm_xor_si128(a.into(), b.into()).simd_into(token)
7772            }
7773        );
7774        kernel(self, a, b)
7775    }
7776    #[inline(always)]
7777    fn not_mask64x2(self, a: mask64x2<Self>) -> mask64x2<Self> {
7778        self.xor_mask64x2(a, self.splat_mask64x2(true))
7779    }
7780    #[inline(always)]
7781    fn reverse_mask64x2(self, a: mask64x2<Self>) -> mask64x2<Self> {
7782        let lanes = i64x2 {
7783            val: crate::transmute::checked_transmute_copy(&a.val),
7784            simd: self,
7785        };
7786        let reversed = self.reverse_i64x2(lanes);
7787        mask64x2 {
7788            val: crate::transmute::checked_transmute_copy(&reversed.val),
7789            simd: self,
7790        }
7791    }
7792    #[inline(always)]
7793    fn select_mask64x2(
7794        self,
7795        a: mask64x2<Self>,
7796        b: mask64x2<Self>,
7797        c: mask64x2<Self>,
7798    ) -> mask64x2<Self> {
7799        crate::kernel!(
7800            #[inline(always)]
7801            fn kernel(
7802                token: Sse2,
7803                a: mask64x2<Sse2>,
7804                b: mask64x2<Sse2>,
7805                c: mask64x2<Sse2>,
7806            ) -> mask64x2<Sse2> {
7807                _mm_or_si128(
7808                    _mm_and_si128(a.into(), b.into()),
7809                    _mm_andnot_si128(a.into(), c.into()),
7810                )
7811                .simd_into(token)
7812            }
7813        );
7814        kernel(self, a, b, c)
7815    }
7816    #[inline(always)]
7817    fn simd_eq_mask64x2(self, a: mask64x2<Self>, b: mask64x2<Self>) -> mask64x2<Self> {
7818        crate::kernel!(
7819            #[inline(always)]
7820            fn kernel(token: Sse2, a: mask64x2<Sse2>, b: mask64x2<Sse2>) -> mask64x2<Sse2> {
7821                {
7822                    let eq32 = _mm_cmpeq_epi32(a.into(), b.into());
7823                    let swapped = _mm_shuffle_epi32::<0b10_11_00_01>(eq32);
7824                    _mm_and_si128(eq32, swapped)
7825                }
7826                .simd_into(token)
7827            }
7828        );
7829        kernel(self, a, b)
7830    }
7831    #[inline(always)]
7832    fn any_true_mask64x2(self, a: mask64x2<Self>) -> bool {
7833        crate::kernel!(
7834            #[inline(always)]
7835            fn kernel(token: Sse2, a: mask64x2<Sse2>) -> bool {
7836                _mm_movemask_pd(_mm_castsi128_pd(a.into())) as u32 != 0
7837            }
7838        );
7839        kernel(self, a)
7840    }
7841    #[inline(always)]
7842    fn all_true_mask64x2(self, a: mask64x2<Self>) -> bool {
7843        crate::kernel!(
7844            #[inline(always)]
7845            fn kernel(token: Sse2, a: mask64x2<Sse2>) -> bool {
7846                _mm_movemask_pd(_mm_castsi128_pd(a.into())) as u32 == 0b11
7847            }
7848        );
7849        kernel(self, a)
7850    }
7851    #[inline(always)]
7852    fn any_false_mask64x2(self, a: mask64x2<Self>) -> bool {
7853        crate::kernel!(
7854            #[inline(always)]
7855            fn kernel(token: Sse2, a: mask64x2<Sse2>) -> bool {
7856                _mm_movemask_pd(_mm_castsi128_pd(a.into())) as u32 != 0b11
7857            }
7858        );
7859        kernel(self, a)
7860    }
7861    #[inline(always)]
7862    fn all_false_mask64x2(self, a: mask64x2<Self>) -> bool {
7863        crate::kernel!(
7864            #[inline(always)]
7865            fn kernel(token: Sse2, a: mask64x2<Sse2>) -> bool {
7866                _mm_movemask_pd(_mm_castsi128_pd(a.into())) as u32 == 0
7867            }
7868        );
7869        kernel(self, a)
7870    }
7871    #[inline(always)]
7872    fn combine_mask64x2(self, a: mask64x2<Self>, b: mask64x2<Self>) -> mask64x4<Self> {
7873        mask64x4 {
7874            val: crate::support::Aligned256([a.val.0, b.val.0]),
7875            simd: self,
7876        }
7877    }
7878    #[inline(always)]
7879    fn narrow_mask64x2(self, a: mask64x2<Self>, b: mask64x2<Self>) -> mask32x4<Self> {
7880        crate::kernel!(
7881            #[inline(always)]
7882            fn kernel(token: Sse2, a: mask64x2<Sse2>, b: mask64x2<Sse2>) -> mask32x4<Sse2> {
7883                _mm_castps_si128(_mm_shuffle_ps::<0x88>(
7884                    _mm_castsi128_ps(a.into()),
7885                    _mm_castsi128_ps(b.into()),
7886                ))
7887                .simd_into(token)
7888            }
7889        );
7890        kernel(self, a, b)
7891    }
7892    #[inline(always)]
7893    fn slide_f32x8<const SHIFT: usize>(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x8<Self> {
7894        if SHIFT >= 8usize {
7895            return b;
7896        }
7897        let result = cross_block_alignr_128x2(
7898            self,
7899            Bytes::to_bytes(b).val.0,
7900            Bytes::to_bytes(a).val.0,
7901            SHIFT * 4usize,
7902        );
7903        Bytes::from_bytes(u8x32 {
7904            val: crate::support::Aligned256(result),
7905            simd: self,
7906        })
7907    }
7908    #[inline(always)]
7909    fn compress_f32x8(self, values: f32x8<Self>, mask: mask32x8<Self>) -> f32x8<Self> {
7910        let mask = mask8x32 {
7911            val: crate::transmute::checked_transmute_copy(&mask.val),
7912            simd: self,
7913        };
7914        Bytes::from_bytes(self.compress_u8x32(Bytes::to_bytes(values), mask))
7915    }
7916    #[inline(always)]
7917    fn compress_merge_f32x8(
7918        self,
7919        values: f32x8<Self>,
7920        mask: mask32x8<Self>,
7921        merge: f32x8<Self>,
7922    ) -> f32x8<Self> {
7923        let mask = mask8x32 {
7924            val: crate::transmute::checked_transmute_copy(&mask.val),
7925            simd: self,
7926        };
7927        Bytes::from_bytes(self.compress_merge_u8x32(
7928            Bytes::to_bytes(values),
7929            mask,
7930            Bytes::to_bytes(merge),
7931        ))
7932    }
7933    #[inline(always)]
7934    fn expand_f32x8(self, values: f32x8<Self>, mask: mask32x8<Self>) -> f32x8<Self> {
7935        let mask = mask8x32 {
7936            val: crate::transmute::checked_transmute_copy(&mask.val),
7937            simd: self,
7938        };
7939        Bytes::from_bytes(self.expand_u8x32(Bytes::to_bytes(values), mask))
7940    }
7941    #[inline(always)]
7942    fn expand_merge_f32x8(
7943        self,
7944        values: f32x8<Self>,
7945        mask: mask32x8<Self>,
7946        merge: f32x8<Self>,
7947    ) -> f32x8<Self> {
7948        let mask = mask8x32 {
7949            val: crate::transmute::checked_transmute_copy(&mask.val),
7950            simd: self,
7951        };
7952        Bytes::from_bytes(self.expand_merge_u8x32(
7953            Bytes::to_bytes(values),
7954            mask,
7955            Bytes::to_bytes(merge),
7956        ))
7957    }
7958    #[inline(always)]
7959    fn simd_ne_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> mask32x8<Self> {
7960        let (a0, a1) = self.split_f32x8(a);
7961        let (b0, b1) = self.split_f32x8(b);
7962        self.combine_mask32x4(self.simd_ne_f32x4(a0, b0), self.simd_ne_f32x4(a1, b1))
7963    }
7964    #[inline(always)]
7965    fn is_nan_f32x8(self, a: f32x8<Self>) -> mask32x8<Self> {
7966        a.simd_ne(a)
7967    }
7968    #[inline(always)]
7969    fn is_infinite_f32x8(self, a: f32x8<Self>) -> mask32x8<Self> {
7970        a.abs().simd_eq(f32::INFINITY)
7971    }
7972    #[inline(always)]
7973    fn is_finite_f32x8(self, a: f32x8<Self>) -> mask32x8<Self> {
7974        a.abs().simd_lt(f32::INFINITY)
7975    }
7976    #[inline(always)]
7977    fn is_subnormal_f32x8(self, a: f32x8<Self>) -> mask32x8<Self> {
7978        let i: i32x8<Self> = a.bitcast();
7979        (i & 0x7F80_0000_i32).simd_eq(0) & (i & 0x007F_FFFF_i32).simd_ne(0)
7980    }
7981    #[inline(always)]
7982    fn is_normal_f32x8(self, a: f32x8<Self>) -> mask32x8<Self> {
7983        let i: i32x8<Self> = a.bitcast();
7984        let exp = i & 0x7F80_0000_i32;
7985        exp.simd_ne(0) & exp.simd_ne(0x7F80_0000_i32)
7986    }
7987    #[inline(always)]
7988    fn is_sign_positive_f32x8(self, a: f32x8<Self>) -> mask32x8<Self> {
7989        let i: i32x8<Self> = a.bitcast();
7990        (i & i32::MIN).simd_eq(0)
7991    }
7992    #[inline(always)]
7993    fn is_sign_negative_f32x8(self, a: f32x8<Self>) -> mask32x8<Self> {
7994        !a.is_sign_positive()
7995    }
7996    #[inline(always)]
7997    fn combine_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x16<Self> {
7998        f32x16 {
7999            val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]),
8000            simd: self,
8001        }
8002    }
8003    #[inline(always)]
8004    fn split_f32x8(self, a: f32x8<Self>) -> (f32x4<Self>, f32x4<Self>) {
8005        (
8006            f32x4 {
8007                val: crate::support::Aligned128(a.val.0[0]),
8008                simd: self,
8009            },
8010            f32x4 {
8011                val: crate::support::Aligned128(a.val.0[1]),
8012                simd: self,
8013            },
8014        )
8015    }
8016    #[inline(always)]
8017    fn slide_i8x32<const SHIFT: usize>(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
8018        if SHIFT >= 32usize {
8019            return b;
8020        }
8021        let result = cross_block_alignr_128x2(
8022            self,
8023            Bytes::to_bytes(b).val.0,
8024            Bytes::to_bytes(a).val.0,
8025            SHIFT,
8026        );
8027        Bytes::from_bytes(u8x32 {
8028            val: crate::support::Aligned256(result),
8029            simd: self,
8030        })
8031    }
8032    #[inline(always)]
8033    fn compress_i8x32(self, values: i8x32<Self>, mask: mask8x32<Self>) -> i8x32<Self> {
8034        let mask = mask8x32 {
8035            val: crate::transmute::checked_transmute_copy(&mask.val),
8036            simd: self,
8037        };
8038        Bytes::from_bytes(self.compress_u8x32(Bytes::to_bytes(values), mask))
8039    }
8040    #[inline(always)]
8041    fn compress_merge_i8x32(
8042        self,
8043        values: i8x32<Self>,
8044        mask: mask8x32<Self>,
8045        merge: i8x32<Self>,
8046    ) -> i8x32<Self> {
8047        let mask = mask8x32 {
8048            val: crate::transmute::checked_transmute_copy(&mask.val),
8049            simd: self,
8050        };
8051        Bytes::from_bytes(self.compress_merge_u8x32(
8052            Bytes::to_bytes(values),
8053            mask,
8054            Bytes::to_bytes(merge),
8055        ))
8056    }
8057    #[inline(always)]
8058    fn expand_i8x32(self, values: i8x32<Self>, mask: mask8x32<Self>) -> i8x32<Self> {
8059        let mask = mask8x32 {
8060            val: crate::transmute::checked_transmute_copy(&mask.val),
8061            simd: self,
8062        };
8063        Bytes::from_bytes(self.expand_u8x32(Bytes::to_bytes(values), mask))
8064    }
8065    #[inline(always)]
8066    fn expand_merge_i8x32(
8067        self,
8068        values: i8x32<Self>,
8069        mask: mask8x32<Self>,
8070        merge: i8x32<Self>,
8071    ) -> i8x32<Self> {
8072        let mask = mask8x32 {
8073            val: crate::transmute::checked_transmute_copy(&mask.val),
8074            simd: self,
8075        };
8076        Bytes::from_bytes(self.expand_merge_u8x32(
8077            Bytes::to_bytes(values),
8078            mask,
8079            Bytes::to_bytes(merge),
8080        ))
8081    }
8082    #[inline(always)]
8083    fn combine_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x64<Self> {
8084        i8x64 {
8085            val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]),
8086            simd: self,
8087        }
8088    }
8089    #[inline(always)]
8090    fn split_i8x32(self, a: i8x32<Self>) -> (i8x16<Self>, i8x16<Self>) {
8091        (
8092            i8x16 {
8093                val: crate::support::Aligned128(a.val.0[0]),
8094                simd: self,
8095            },
8096            i8x16 {
8097                val: crate::support::Aligned128(a.val.0[1]),
8098                simd: self,
8099            },
8100        )
8101    }
8102    #[inline(always)]
8103    fn slide_u8x32<const SHIFT: usize>(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
8104        if SHIFT >= 32usize {
8105            return b;
8106        }
8107        let result = cross_block_alignr_128x2(
8108            self,
8109            Bytes::to_bytes(b).val.0,
8110            Bytes::to_bytes(a).val.0,
8111            SHIFT,
8112        );
8113        Bytes::from_bytes(u8x32 {
8114            val: crate::support::Aligned256(result),
8115            simd: self,
8116        })
8117    }
8118    #[inline(always)]
8119    fn swizzle_dyn_u8x32(self, a: u8x32<Self>, indices: u8x32<Self>) -> u8x32<Self> {
8120        let bytes = Bytes::to_bytes(a);
8121        let mut output = [0u8; 32usize];
8122        for lane in 0..32usize {
8123            let index = indices[lane] as usize;
8124            output[lane] = bytes[index % 32usize];
8125        }
8126        let result: u8x32<Self> = output.simd_into(self);
8127        Bytes::from_bytes(result)
8128    }
8129    #[inline(always)]
8130    fn swizzle_dyn_precise_u8x32(self, a: u8x32<Self>, indices: u8x32<Self>) -> u8x32<Self> {
8131        let bytes = Bytes::to_bytes(a);
8132        let mut output = [0u8; 32usize];
8133        for lane in 0..32usize {
8134            let index = indices[lane] as usize;
8135            let value = bytes[index % 32usize];
8136            output[lane] = core::hint::select_unpredictable(index < 32usize, value, 0u8);
8137        }
8138        let result: u8x32<Self> = output.simd_into(self);
8139        Bytes::from_bytes(result)
8140    }
8141    #[inline(always)]
8142    fn concat_swizzle_dyn_u8x32(
8143        self,
8144        a: u8x32<Self>,
8145        b: u8x32<Self>,
8146        indices: u8x32<Self>,
8147    ) -> u8x32<Self> {
8148        let first_table = Bytes::to_bytes(a);
8149        let second_table = Bytes::to_bytes(b);
8150        let mut output = [0u8; 32usize];
8151        for lane in 0..32usize {
8152            let index = indices[lane] as usize % 64usize;
8153            output[lane] = if index < 32usize {
8154                first_table[index]
8155            } else {
8156                second_table[index - 32usize]
8157            };
8158        }
8159        let result: u8x32<Self> = output.simd_into(self);
8160        Bytes::from_bytes(result)
8161    }
8162    #[inline(always)]
8163    fn concat_swizzle_dyn_precise_u8x32(
8164        self,
8165        a: u8x32<Self>,
8166        b: u8x32<Self>,
8167        indices: u8x32<Self>,
8168    ) -> u8x32<Self> {
8169        let first_table = Bytes::to_bytes(a);
8170        let second_table = Bytes::to_bytes(b);
8171        let mut output = [0u8; 32usize];
8172        for lane in 0..32usize {
8173            let index = indices[lane] as usize;
8174            let table_index = index % 32usize;
8175            let value = if index < 32usize {
8176                first_table[table_index]
8177            } else {
8178                second_table[table_index]
8179            };
8180            output[lane] = if index < 64usize { value } else { 0 };
8181        }
8182        let result: u8x32<Self> = output.simd_into(self);
8183        Bytes::from_bytes(result)
8184    }
8185    #[inline(always)]
8186    fn compress_u8x32(self, values: u8x32<Self>, mask: mask8x32<Self>) -> u8x32<Self> {
8187        self.compress_merge_u8x32(values, mask, u8x32::splat(self, 0))
8188    }
8189    #[inline(always)]
8190    fn compress_merge_u8x32(
8191        self,
8192        values: u8x32<Self>,
8193        mask: mask8x32<Self>,
8194        merge: u8x32<Self>,
8195    ) -> u8x32<Self> {
8196        let mask = self.to_bitmask_mask8x32(mask);
8197        let mut merge_padded = [0u8; 32 + 1];
8198        merge_padded[..32].copy_from_slice(&*merge);
8199        let mut compacted = merge_padded;
8200        let mut output_lane = 0;
8201        for input_lane in 0..32 {
8202            compacted[output_lane] = values[input_lane];
8203            output_lane += ((mask >> input_lane) & 1) as usize;
8204        }
8205        compacted[output_lane] = merge_padded[output_lane];
8206        let mut result = merge;
8207        result.copy_from_slice(&compacted[..32]);
8208        result
8209    }
8210    #[inline(always)]
8211    fn expand_u8x32(self, values: u8x32<Self>, mask: mask8x32<Self>) -> u8x32<Self> {
8212        self.expand_merge_u8x32(values, mask, u8x32::splat(self, 0))
8213    }
8214    #[inline(always)]
8215    fn expand_merge_u8x32(
8216        self,
8217        values: u8x32<Self>,
8218        mask: mask8x32<Self>,
8219        merge: u8x32<Self>,
8220    ) -> u8x32<Self> {
8221        let mask = self.to_bitmask_mask8x32(mask);
8222        let mut result = merge;
8223        let mut input_lane = 0;
8224        for output_lane in 0..32 {
8225            let bit = ((mask >> output_lane) & 1) as u8;
8226            let keep = 0u8.wrapping_sub(bit);
8227            result[output_lane] = (values[input_lane] & keep) | (result[output_lane] & !keep);
8228            input_lane += usize::from(bit);
8229        }
8230        result
8231    }
8232    #[inline(always)]
8233    fn combine_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x64<Self> {
8234        u8x64 {
8235            val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]),
8236            simd: self,
8237        }
8238    }
8239    #[inline(always)]
8240    fn split_u8x32(self, a: u8x32<Self>) -> (u8x16<Self>, u8x16<Self>) {
8241        (
8242            u8x16 {
8243                val: crate::support::Aligned128(a.val.0[0]),
8244                simd: self,
8245            },
8246            u8x16 {
8247                val: crate::support::Aligned128(a.val.0[1]),
8248                simd: self,
8249            },
8250        )
8251    }
8252    #[inline(always)]
8253    fn from_vector_mask8x32(self, vector: i8x32<Self>) -> mask8x32<Self> {
8254        mask8x32 {
8255            val: vector.val,
8256            simd: self,
8257        }
8258    }
8259    #[inline(always)]
8260    fn to_vector_mask8x32(self, a: mask8x32<Self>) -> i8x32<Self> {
8261        i8x32 {
8262            val: a.val,
8263            simd: self,
8264        }
8265    }
8266    #[inline(always)]
8267    fn set_mask8x32(self, a: &mut mask8x32<Self>, index: usize, value: bool) -> () {
8268        assert!(
8269            index < 32usize,
8270            "mask lane index {index} is out of bounds for {} lanes",
8271            32usize
8272        );
8273        let mut lanes: [i8; 32usize] = (*a).into();
8274        lanes[index] = if value { !0 } else { 0 };
8275        *a = lanes.simd_into(self);
8276    }
8277    #[inline(always)]
8278    fn rotate_elements_left_mask8x32<const OFFSET: usize>(
8279        self,
8280        a: mask8x32<Self>,
8281    ) -> mask8x32<Self> {
8282        let int = i8x32 {
8283            val: crate::transmute::checked_transmute_copy(&a.val),
8284            simd: self,
8285        };
8286        let rotated = int.rotate_elements_left::<OFFSET>();
8287        mask8x32 {
8288            val: crate::transmute::checked_transmute_copy(&rotated.val),
8289            simd: self,
8290        }
8291    }
8292    #[inline(always)]
8293    fn rotate_elements_right_mask8x32<const OFFSET: usize>(
8294        self,
8295        a: mask8x32<Self>,
8296    ) -> mask8x32<Self> {
8297        let int = i8x32 {
8298            val: crate::transmute::checked_transmute_copy(&a.val),
8299            simd: self,
8300        };
8301        let rotated = int.rotate_elements_right::<OFFSET>();
8302        mask8x32 {
8303            val: crate::transmute::checked_transmute_copy(&rotated.val),
8304            simd: self,
8305        }
8306    }
8307    #[inline(always)]
8308    fn combine_mask8x32(self, a: mask8x32<Self>, b: mask8x32<Self>) -> mask8x64<Self> {
8309        mask8x64 {
8310            val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]),
8311            simd: self,
8312        }
8313    }
8314    #[inline(always)]
8315    fn split_mask8x32(self, a: mask8x32<Self>) -> (mask8x16<Self>, mask8x16<Self>) {
8316        (
8317            mask8x16 {
8318                val: crate::support::Aligned128(a.val.0[0]),
8319                simd: self,
8320            },
8321            mask8x16 {
8322                val: crate::support::Aligned128(a.val.0[1]),
8323                simd: self,
8324            },
8325        )
8326    }
8327    #[inline(always)]
8328    fn slide_i16x16<const SHIFT: usize>(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
8329        if SHIFT >= 16usize {
8330            return b;
8331        }
8332        let result = cross_block_alignr_128x2(
8333            self,
8334            Bytes::to_bytes(b).val.0,
8335            Bytes::to_bytes(a).val.0,
8336            SHIFT * 2usize,
8337        );
8338        Bytes::from_bytes(u8x32 {
8339            val: crate::support::Aligned256(result),
8340            simd: self,
8341        })
8342    }
8343    #[inline(always)]
8344    fn compress_i16x16(self, values: i16x16<Self>, mask: mask16x16<Self>) -> i16x16<Self> {
8345        let mask = mask8x32 {
8346            val: crate::transmute::checked_transmute_copy(&mask.val),
8347            simd: self,
8348        };
8349        Bytes::from_bytes(self.compress_u8x32(Bytes::to_bytes(values), mask))
8350    }
8351    #[inline(always)]
8352    fn compress_merge_i16x16(
8353        self,
8354        values: i16x16<Self>,
8355        mask: mask16x16<Self>,
8356        merge: i16x16<Self>,
8357    ) -> i16x16<Self> {
8358        let mask = mask8x32 {
8359            val: crate::transmute::checked_transmute_copy(&mask.val),
8360            simd: self,
8361        };
8362        Bytes::from_bytes(self.compress_merge_u8x32(
8363            Bytes::to_bytes(values),
8364            mask,
8365            Bytes::to_bytes(merge),
8366        ))
8367    }
8368    #[inline(always)]
8369    fn expand_i16x16(self, values: i16x16<Self>, mask: mask16x16<Self>) -> i16x16<Self> {
8370        let mask = mask8x32 {
8371            val: crate::transmute::checked_transmute_copy(&mask.val),
8372            simd: self,
8373        };
8374        Bytes::from_bytes(self.expand_u8x32(Bytes::to_bytes(values), mask))
8375    }
8376    #[inline(always)]
8377    fn expand_merge_i16x16(
8378        self,
8379        values: i16x16<Self>,
8380        mask: mask16x16<Self>,
8381        merge: i16x16<Self>,
8382    ) -> i16x16<Self> {
8383        let mask = mask8x32 {
8384            val: crate::transmute::checked_transmute_copy(&mask.val),
8385            simd: self,
8386        };
8387        Bytes::from_bytes(self.expand_merge_u8x32(
8388            Bytes::to_bytes(values),
8389            mask,
8390            Bytes::to_bytes(merge),
8391        ))
8392    }
8393    #[inline(always)]
8394    fn combine_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x32<Self> {
8395        i16x32 {
8396            val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]),
8397            simd: self,
8398        }
8399    }
8400    #[inline(always)]
8401    fn split_i16x16(self, a: i16x16<Self>) -> (i16x8<Self>, i16x8<Self>) {
8402        (
8403            i16x8 {
8404                val: crate::support::Aligned128(a.val.0[0]),
8405                simd: self,
8406            },
8407            i16x8 {
8408                val: crate::support::Aligned128(a.val.0[1]),
8409                simd: self,
8410            },
8411        )
8412    }
8413    #[inline(always)]
8414    fn slide_u16x16<const SHIFT: usize>(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
8415        if SHIFT >= 16usize {
8416            return b;
8417        }
8418        let result = cross_block_alignr_128x2(
8419            self,
8420            Bytes::to_bytes(b).val.0,
8421            Bytes::to_bytes(a).val.0,
8422            SHIFT * 2usize,
8423        );
8424        Bytes::from_bytes(u8x32 {
8425            val: crate::support::Aligned256(result),
8426            simd: self,
8427        })
8428    }
8429    #[inline(always)]
8430    fn compress_u16x16(self, values: u16x16<Self>, mask: mask16x16<Self>) -> u16x16<Self> {
8431        let mask = mask8x32 {
8432            val: crate::transmute::checked_transmute_copy(&mask.val),
8433            simd: self,
8434        };
8435        Bytes::from_bytes(self.compress_u8x32(Bytes::to_bytes(values), mask))
8436    }
8437    #[inline(always)]
8438    fn compress_merge_u16x16(
8439        self,
8440        values: u16x16<Self>,
8441        mask: mask16x16<Self>,
8442        merge: u16x16<Self>,
8443    ) -> u16x16<Self> {
8444        let mask = mask8x32 {
8445            val: crate::transmute::checked_transmute_copy(&mask.val),
8446            simd: self,
8447        };
8448        Bytes::from_bytes(self.compress_merge_u8x32(
8449            Bytes::to_bytes(values),
8450            mask,
8451            Bytes::to_bytes(merge),
8452        ))
8453    }
8454    #[inline(always)]
8455    fn expand_u16x16(self, values: u16x16<Self>, mask: mask16x16<Self>) -> u16x16<Self> {
8456        let mask = mask8x32 {
8457            val: crate::transmute::checked_transmute_copy(&mask.val),
8458            simd: self,
8459        };
8460        Bytes::from_bytes(self.expand_u8x32(Bytes::to_bytes(values), mask))
8461    }
8462    #[inline(always)]
8463    fn expand_merge_u16x16(
8464        self,
8465        values: u16x16<Self>,
8466        mask: mask16x16<Self>,
8467        merge: u16x16<Self>,
8468    ) -> u16x16<Self> {
8469        let mask = mask8x32 {
8470            val: crate::transmute::checked_transmute_copy(&mask.val),
8471            simd: self,
8472        };
8473        Bytes::from_bytes(self.expand_merge_u8x32(
8474            Bytes::to_bytes(values),
8475            mask,
8476            Bytes::to_bytes(merge),
8477        ))
8478    }
8479    #[inline(always)]
8480    fn combine_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x32<Self> {
8481        u16x32 {
8482            val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]),
8483            simd: self,
8484        }
8485    }
8486    #[inline(always)]
8487    fn split_u16x16(self, a: u16x16<Self>) -> (u16x8<Self>, u16x8<Self>) {
8488        (
8489            u16x8 {
8490                val: crate::support::Aligned128(a.val.0[0]),
8491                simd: self,
8492            },
8493            u16x8 {
8494                val: crate::support::Aligned128(a.val.0[1]),
8495                simd: self,
8496            },
8497        )
8498    }
8499    #[inline(always)]
8500    fn to_bitmask_mask16x16(self, a: mask16x16<Self>) -> u64 {
8501        crate::kernel!(
8502            #[inline(always)]
8503            fn kernel(token: Sse2, a: mask16x16<Sse2>) -> u64 {
8504                {
8505                    let packed = _mm_packs_epi16(a.val.0[0], a.val.0[1]);
8506                    _mm_movemask_epi8(packed) as u32 as u64
8507                }
8508            }
8509        );
8510        kernel(self, a)
8511    }
8512    #[inline(always)]
8513    fn from_vector_mask16x16(self, vector: i16x16<Self>) -> mask16x16<Self> {
8514        mask16x16 {
8515            val: vector.val,
8516            simd: self,
8517        }
8518    }
8519    #[inline(always)]
8520    fn to_vector_mask16x16(self, a: mask16x16<Self>) -> i16x16<Self> {
8521        i16x16 {
8522            val: a.val,
8523            simd: self,
8524        }
8525    }
8526    #[inline(always)]
8527    fn set_mask16x16(self, a: &mut mask16x16<Self>, index: usize, value: bool) -> () {
8528        assert!(
8529            index < 16usize,
8530            "mask lane index {index} is out of bounds for {} lanes",
8531            16usize
8532        );
8533        let mut lanes: [i16; 16usize] = (*a).into();
8534        lanes[index] = if value { !0 } else { 0 };
8535        *a = lanes.simd_into(self);
8536    }
8537    #[inline(always)]
8538    fn rotate_elements_left_mask16x16<const OFFSET: usize>(
8539        self,
8540        a: mask16x16<Self>,
8541    ) -> mask16x16<Self> {
8542        let int = i16x16 {
8543            val: crate::transmute::checked_transmute_copy(&a.val),
8544            simd: self,
8545        };
8546        let rotated = int.rotate_elements_left::<OFFSET>();
8547        mask16x16 {
8548            val: crate::transmute::checked_transmute_copy(&rotated.val),
8549            simd: self,
8550        }
8551    }
8552    #[inline(always)]
8553    fn rotate_elements_right_mask16x16<const OFFSET: usize>(
8554        self,
8555        a: mask16x16<Self>,
8556    ) -> mask16x16<Self> {
8557        let int = i16x16 {
8558            val: crate::transmute::checked_transmute_copy(&a.val),
8559            simd: self,
8560        };
8561        let rotated = int.rotate_elements_right::<OFFSET>();
8562        mask16x16 {
8563            val: crate::transmute::checked_transmute_copy(&rotated.val),
8564            simd: self,
8565        }
8566    }
8567    #[inline(always)]
8568    fn combine_mask16x16(self, a: mask16x16<Self>, b: mask16x16<Self>) -> mask16x32<Self> {
8569        mask16x32 {
8570            val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]),
8571            simd: self,
8572        }
8573    }
8574    #[inline(always)]
8575    fn split_mask16x16(self, a: mask16x16<Self>) -> (mask16x8<Self>, mask16x8<Self>) {
8576        (
8577            mask16x8 {
8578                val: crate::support::Aligned128(a.val.0[0]),
8579                simd: self,
8580            },
8581            mask16x8 {
8582                val: crate::support::Aligned128(a.val.0[1]),
8583                simd: self,
8584            },
8585        )
8586    }
8587    #[inline(always)]
8588    fn slide_i32x8<const SHIFT: usize>(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
8589        if SHIFT >= 8usize {
8590            return b;
8591        }
8592        let result = cross_block_alignr_128x2(
8593            self,
8594            Bytes::to_bytes(b).val.0,
8595            Bytes::to_bytes(a).val.0,
8596            SHIFT * 4usize,
8597        );
8598        Bytes::from_bytes(u8x32 {
8599            val: crate::support::Aligned256(result),
8600            simd: self,
8601        })
8602    }
8603    #[inline(always)]
8604    fn compress_i32x8(self, values: i32x8<Self>, mask: mask32x8<Self>) -> i32x8<Self> {
8605        let mask = mask8x32 {
8606            val: crate::transmute::checked_transmute_copy(&mask.val),
8607            simd: self,
8608        };
8609        Bytes::from_bytes(self.compress_u8x32(Bytes::to_bytes(values), mask))
8610    }
8611    #[inline(always)]
8612    fn compress_merge_i32x8(
8613        self,
8614        values: i32x8<Self>,
8615        mask: mask32x8<Self>,
8616        merge: i32x8<Self>,
8617    ) -> i32x8<Self> {
8618        let mask = mask8x32 {
8619            val: crate::transmute::checked_transmute_copy(&mask.val),
8620            simd: self,
8621        };
8622        Bytes::from_bytes(self.compress_merge_u8x32(
8623            Bytes::to_bytes(values),
8624            mask,
8625            Bytes::to_bytes(merge),
8626        ))
8627    }
8628    #[inline(always)]
8629    fn expand_i32x8(self, values: i32x8<Self>, mask: mask32x8<Self>) -> i32x8<Self> {
8630        let mask = mask8x32 {
8631            val: crate::transmute::checked_transmute_copy(&mask.val),
8632            simd: self,
8633        };
8634        Bytes::from_bytes(self.expand_u8x32(Bytes::to_bytes(values), mask))
8635    }
8636    #[inline(always)]
8637    fn expand_merge_i32x8(
8638        self,
8639        values: i32x8<Self>,
8640        mask: mask32x8<Self>,
8641        merge: i32x8<Self>,
8642    ) -> i32x8<Self> {
8643        let mask = mask8x32 {
8644            val: crate::transmute::checked_transmute_copy(&mask.val),
8645            simd: self,
8646        };
8647        Bytes::from_bytes(self.expand_merge_u8x32(
8648            Bytes::to_bytes(values),
8649            mask,
8650            Bytes::to_bytes(merge),
8651        ))
8652    }
8653    #[inline(always)]
8654    fn combine_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x16<Self> {
8655        i32x16 {
8656            val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]),
8657            simd: self,
8658        }
8659    }
8660    #[inline(always)]
8661    fn split_i32x8(self, a: i32x8<Self>) -> (i32x4<Self>, i32x4<Self>) {
8662        (
8663            i32x4 {
8664                val: crate::support::Aligned128(a.val.0[0]),
8665                simd: self,
8666            },
8667            i32x4 {
8668                val: crate::support::Aligned128(a.val.0[1]),
8669                simd: self,
8670            },
8671        )
8672    }
8673    #[inline(always)]
8674    fn slide_u32x8<const SHIFT: usize>(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
8675        if SHIFT >= 8usize {
8676            return b;
8677        }
8678        let result = cross_block_alignr_128x2(
8679            self,
8680            Bytes::to_bytes(b).val.0,
8681            Bytes::to_bytes(a).val.0,
8682            SHIFT * 4usize,
8683        );
8684        Bytes::from_bytes(u8x32 {
8685            val: crate::support::Aligned256(result),
8686            simd: self,
8687        })
8688    }
8689    #[inline(always)]
8690    fn compress_u32x8(self, values: u32x8<Self>, mask: mask32x8<Self>) -> u32x8<Self> {
8691        let mask = mask8x32 {
8692            val: crate::transmute::checked_transmute_copy(&mask.val),
8693            simd: self,
8694        };
8695        Bytes::from_bytes(self.compress_u8x32(Bytes::to_bytes(values), mask))
8696    }
8697    #[inline(always)]
8698    fn compress_merge_u32x8(
8699        self,
8700        values: u32x8<Self>,
8701        mask: mask32x8<Self>,
8702        merge: u32x8<Self>,
8703    ) -> u32x8<Self> {
8704        let mask = mask8x32 {
8705            val: crate::transmute::checked_transmute_copy(&mask.val),
8706            simd: self,
8707        };
8708        Bytes::from_bytes(self.compress_merge_u8x32(
8709            Bytes::to_bytes(values),
8710            mask,
8711            Bytes::to_bytes(merge),
8712        ))
8713    }
8714    #[inline(always)]
8715    fn expand_u32x8(self, values: u32x8<Self>, mask: mask32x8<Self>) -> u32x8<Self> {
8716        let mask = mask8x32 {
8717            val: crate::transmute::checked_transmute_copy(&mask.val),
8718            simd: self,
8719        };
8720        Bytes::from_bytes(self.expand_u8x32(Bytes::to_bytes(values), mask))
8721    }
8722    #[inline(always)]
8723    fn expand_merge_u32x8(
8724        self,
8725        values: u32x8<Self>,
8726        mask: mask32x8<Self>,
8727        merge: u32x8<Self>,
8728    ) -> u32x8<Self> {
8729        let mask = mask8x32 {
8730            val: crate::transmute::checked_transmute_copy(&mask.val),
8731            simd: self,
8732        };
8733        Bytes::from_bytes(self.expand_merge_u8x32(
8734            Bytes::to_bytes(values),
8735            mask,
8736            Bytes::to_bytes(merge),
8737        ))
8738    }
8739    #[inline(always)]
8740    fn combine_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x16<Self> {
8741        u32x16 {
8742            val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]),
8743            simd: self,
8744        }
8745    }
8746    #[inline(always)]
8747    fn split_u32x8(self, a: u32x8<Self>) -> (u32x4<Self>, u32x4<Self>) {
8748        (
8749            u32x4 {
8750                val: crate::support::Aligned128(a.val.0[0]),
8751                simd: self,
8752            },
8753            u32x4 {
8754                val: crate::support::Aligned128(a.val.0[1]),
8755                simd: self,
8756            },
8757        )
8758    }
8759    #[inline(always)]
8760    fn from_vector_mask32x8(self, vector: i32x8<Self>) -> mask32x8<Self> {
8761        mask32x8 {
8762            val: vector.val,
8763            simd: self,
8764        }
8765    }
8766    #[inline(always)]
8767    fn to_vector_mask32x8(self, a: mask32x8<Self>) -> i32x8<Self> {
8768        i32x8 {
8769            val: a.val,
8770            simd: self,
8771        }
8772    }
8773    #[inline(always)]
8774    fn set_mask32x8(self, a: &mut mask32x8<Self>, index: usize, value: bool) -> () {
8775        assert!(
8776            index < 8usize,
8777            "mask lane index {index} is out of bounds for {} lanes",
8778            8usize
8779        );
8780        let mut lanes: [i32; 8usize] = (*a).into();
8781        lanes[index] = if value { !0 } else { 0 };
8782        *a = lanes.simd_into(self);
8783    }
8784    #[inline(always)]
8785    fn rotate_elements_left_mask32x8<const OFFSET: usize>(
8786        self,
8787        a: mask32x8<Self>,
8788    ) -> mask32x8<Self> {
8789        let int = i32x8 {
8790            val: crate::transmute::checked_transmute_copy(&a.val),
8791            simd: self,
8792        };
8793        let rotated = int.rotate_elements_left::<OFFSET>();
8794        mask32x8 {
8795            val: crate::transmute::checked_transmute_copy(&rotated.val),
8796            simd: self,
8797        }
8798    }
8799    #[inline(always)]
8800    fn rotate_elements_right_mask32x8<const OFFSET: usize>(
8801        self,
8802        a: mask32x8<Self>,
8803    ) -> mask32x8<Self> {
8804        let int = i32x8 {
8805            val: crate::transmute::checked_transmute_copy(&a.val),
8806            simd: self,
8807        };
8808        let rotated = int.rotate_elements_right::<OFFSET>();
8809        mask32x8 {
8810            val: crate::transmute::checked_transmute_copy(&rotated.val),
8811            simd: self,
8812        }
8813    }
8814    #[inline(always)]
8815    fn combine_mask32x8(self, a: mask32x8<Self>, b: mask32x8<Self>) -> mask32x16<Self> {
8816        mask32x16 {
8817            val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]),
8818            simd: self,
8819        }
8820    }
8821    #[inline(always)]
8822    fn split_mask32x8(self, a: mask32x8<Self>) -> (mask32x4<Self>, mask32x4<Self>) {
8823        (
8824            mask32x4 {
8825                val: crate::support::Aligned128(a.val.0[0]),
8826                simd: self,
8827            },
8828            mask32x4 {
8829                val: crate::support::Aligned128(a.val.0[1]),
8830                simd: self,
8831            },
8832        )
8833    }
8834    #[inline(always)]
8835    fn slide_f64x4<const SHIFT: usize>(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x4<Self> {
8836        if SHIFT >= 4usize {
8837            return b;
8838        }
8839        let result = cross_block_alignr_128x2(
8840            self,
8841            Bytes::to_bytes(b).val.0,
8842            Bytes::to_bytes(a).val.0,
8843            SHIFT * 8usize,
8844        );
8845        Bytes::from_bytes(u8x32 {
8846            val: crate::support::Aligned256(result),
8847            simd: self,
8848        })
8849    }
8850    #[inline(always)]
8851    fn compress_f64x4(self, values: f64x4<Self>, mask: mask64x4<Self>) -> f64x4<Self> {
8852        let mask = mask8x32 {
8853            val: crate::transmute::checked_transmute_copy(&mask.val),
8854            simd: self,
8855        };
8856        Bytes::from_bytes(self.compress_u8x32(Bytes::to_bytes(values), mask))
8857    }
8858    #[inline(always)]
8859    fn compress_merge_f64x4(
8860        self,
8861        values: f64x4<Self>,
8862        mask: mask64x4<Self>,
8863        merge: f64x4<Self>,
8864    ) -> f64x4<Self> {
8865        let mask = mask8x32 {
8866            val: crate::transmute::checked_transmute_copy(&mask.val),
8867            simd: self,
8868        };
8869        Bytes::from_bytes(self.compress_merge_u8x32(
8870            Bytes::to_bytes(values),
8871            mask,
8872            Bytes::to_bytes(merge),
8873        ))
8874    }
8875    #[inline(always)]
8876    fn expand_f64x4(self, values: f64x4<Self>, mask: mask64x4<Self>) -> f64x4<Self> {
8877        let mask = mask8x32 {
8878            val: crate::transmute::checked_transmute_copy(&mask.val),
8879            simd: self,
8880        };
8881        Bytes::from_bytes(self.expand_u8x32(Bytes::to_bytes(values), mask))
8882    }
8883    #[inline(always)]
8884    fn expand_merge_f64x4(
8885        self,
8886        values: f64x4<Self>,
8887        mask: mask64x4<Self>,
8888        merge: f64x4<Self>,
8889    ) -> f64x4<Self> {
8890        let mask = mask8x32 {
8891            val: crate::transmute::checked_transmute_copy(&mask.val),
8892            simd: self,
8893        };
8894        Bytes::from_bytes(self.expand_merge_u8x32(
8895            Bytes::to_bytes(values),
8896            mask,
8897            Bytes::to_bytes(merge),
8898        ))
8899    }
8900    #[inline(always)]
8901    fn simd_ne_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> mask64x4<Self> {
8902        let (a0, a1) = self.split_f64x4(a);
8903        let (b0, b1) = self.split_f64x4(b);
8904        self.combine_mask64x2(self.simd_ne_f64x2(a0, b0), self.simd_ne_f64x2(a1, b1))
8905    }
8906    #[inline(always)]
8907    fn is_nan_f64x4(self, a: f64x4<Self>) -> mask64x4<Self> {
8908        a.simd_ne(a)
8909    }
8910    #[inline(always)]
8911    fn is_infinite_f64x4(self, a: f64x4<Self>) -> mask64x4<Self> {
8912        a.abs().simd_eq(f64::INFINITY)
8913    }
8914    #[inline(always)]
8915    fn is_finite_f64x4(self, a: f64x4<Self>) -> mask64x4<Self> {
8916        a.abs().simd_lt(f64::INFINITY)
8917    }
8918    #[inline(always)]
8919    fn is_subnormal_f64x4(self, a: f64x4<Self>) -> mask64x4<Self> {
8920        let i: i64x4<Self> = a.bitcast();
8921        (i & 0x7FF0_0000_0000_0000_i64).simd_eq(0) & (i & 0x000F_FFFF_FFFF_FFFF_i64).simd_ne(0)
8922    }
8923    #[inline(always)]
8924    fn is_normal_f64x4(self, a: f64x4<Self>) -> mask64x4<Self> {
8925        let i: i64x4<Self> = a.bitcast();
8926        let exp = i & 0x7FF0_0000_0000_0000_i64;
8927        exp.simd_ne(0) & exp.simd_ne(0x7FF0_0000_0000_0000_i64)
8928    }
8929    #[inline(always)]
8930    fn is_sign_positive_f64x4(self, a: f64x4<Self>) -> mask64x4<Self> {
8931        let i: i64x4<Self> = a.bitcast();
8932        (i & i64::MIN).simd_eq(0)
8933    }
8934    #[inline(always)]
8935    fn is_sign_negative_f64x4(self, a: f64x4<Self>) -> mask64x4<Self> {
8936        !a.is_sign_positive()
8937    }
8938    #[inline(always)]
8939    fn combine_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x8<Self> {
8940        f64x8 {
8941            val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]),
8942            simd: self,
8943        }
8944    }
8945    #[inline(always)]
8946    fn split_f64x4(self, a: f64x4<Self>) -> (f64x2<Self>, f64x2<Self>) {
8947        (
8948            f64x2 {
8949                val: crate::support::Aligned128(a.val.0[0]),
8950                simd: self,
8951            },
8952            f64x2 {
8953                val: crate::support::Aligned128(a.val.0[1]),
8954                simd: self,
8955            },
8956        )
8957    }
8958    #[inline(always)]
8959    fn slide_i64x4<const SHIFT: usize>(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
8960        if SHIFT >= 4usize {
8961            return b;
8962        }
8963        let result = cross_block_alignr_128x2(
8964            self,
8965            Bytes::to_bytes(b).val.0,
8966            Bytes::to_bytes(a).val.0,
8967            SHIFT * 8usize,
8968        );
8969        Bytes::from_bytes(u8x32 {
8970            val: crate::support::Aligned256(result),
8971            simd: self,
8972        })
8973    }
8974    #[inline(always)]
8975    fn compress_i64x4(self, values: i64x4<Self>, mask: mask64x4<Self>) -> i64x4<Self> {
8976        let mask = mask8x32 {
8977            val: crate::transmute::checked_transmute_copy(&mask.val),
8978            simd: self,
8979        };
8980        Bytes::from_bytes(self.compress_u8x32(Bytes::to_bytes(values), mask))
8981    }
8982    #[inline(always)]
8983    fn compress_merge_i64x4(
8984        self,
8985        values: i64x4<Self>,
8986        mask: mask64x4<Self>,
8987        merge: i64x4<Self>,
8988    ) -> i64x4<Self> {
8989        let mask = mask8x32 {
8990            val: crate::transmute::checked_transmute_copy(&mask.val),
8991            simd: self,
8992        };
8993        Bytes::from_bytes(self.compress_merge_u8x32(
8994            Bytes::to_bytes(values),
8995            mask,
8996            Bytes::to_bytes(merge),
8997        ))
8998    }
8999    #[inline(always)]
9000    fn expand_i64x4(self, values: i64x4<Self>, mask: mask64x4<Self>) -> i64x4<Self> {
9001        let mask = mask8x32 {
9002            val: crate::transmute::checked_transmute_copy(&mask.val),
9003            simd: self,
9004        };
9005        Bytes::from_bytes(self.expand_u8x32(Bytes::to_bytes(values), mask))
9006    }
9007    #[inline(always)]
9008    fn expand_merge_i64x4(
9009        self,
9010        values: i64x4<Self>,
9011        mask: mask64x4<Self>,
9012        merge: i64x4<Self>,
9013    ) -> i64x4<Self> {
9014        let mask = mask8x32 {
9015            val: crate::transmute::checked_transmute_copy(&mask.val),
9016            simd: self,
9017        };
9018        Bytes::from_bytes(self.expand_merge_u8x32(
9019            Bytes::to_bytes(values),
9020            mask,
9021            Bytes::to_bytes(merge),
9022        ))
9023    }
9024    #[inline(always)]
9025    fn combine_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x8<Self> {
9026        i64x8 {
9027            val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]),
9028            simd: self,
9029        }
9030    }
9031    #[inline(always)]
9032    fn split_i64x4(self, a: i64x4<Self>) -> (i64x2<Self>, i64x2<Self>) {
9033        (
9034            i64x2 {
9035                val: crate::support::Aligned128(a.val.0[0]),
9036                simd: self,
9037            },
9038            i64x2 {
9039                val: crate::support::Aligned128(a.val.0[1]),
9040                simd: self,
9041            },
9042        )
9043    }
9044    #[inline(always)]
9045    fn slide_u64x4<const SHIFT: usize>(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
9046        if SHIFT >= 4usize {
9047            return b;
9048        }
9049        let result = cross_block_alignr_128x2(
9050            self,
9051            Bytes::to_bytes(b).val.0,
9052            Bytes::to_bytes(a).val.0,
9053            SHIFT * 8usize,
9054        );
9055        Bytes::from_bytes(u8x32 {
9056            val: crate::support::Aligned256(result),
9057            simd: self,
9058        })
9059    }
9060    #[inline(always)]
9061    fn compress_u64x4(self, values: u64x4<Self>, mask: mask64x4<Self>) -> u64x4<Self> {
9062        let mask = mask8x32 {
9063            val: crate::transmute::checked_transmute_copy(&mask.val),
9064            simd: self,
9065        };
9066        Bytes::from_bytes(self.compress_u8x32(Bytes::to_bytes(values), mask))
9067    }
9068    #[inline(always)]
9069    fn compress_merge_u64x4(
9070        self,
9071        values: u64x4<Self>,
9072        mask: mask64x4<Self>,
9073        merge: u64x4<Self>,
9074    ) -> u64x4<Self> {
9075        let mask = mask8x32 {
9076            val: crate::transmute::checked_transmute_copy(&mask.val),
9077            simd: self,
9078        };
9079        Bytes::from_bytes(self.compress_merge_u8x32(
9080            Bytes::to_bytes(values),
9081            mask,
9082            Bytes::to_bytes(merge),
9083        ))
9084    }
9085    #[inline(always)]
9086    fn expand_u64x4(self, values: u64x4<Self>, mask: mask64x4<Self>) -> u64x4<Self> {
9087        let mask = mask8x32 {
9088            val: crate::transmute::checked_transmute_copy(&mask.val),
9089            simd: self,
9090        };
9091        Bytes::from_bytes(self.expand_u8x32(Bytes::to_bytes(values), mask))
9092    }
9093    #[inline(always)]
9094    fn expand_merge_u64x4(
9095        self,
9096        values: u64x4<Self>,
9097        mask: mask64x4<Self>,
9098        merge: u64x4<Self>,
9099    ) -> u64x4<Self> {
9100        let mask = mask8x32 {
9101            val: crate::transmute::checked_transmute_copy(&mask.val),
9102            simd: self,
9103        };
9104        Bytes::from_bytes(self.expand_merge_u8x32(
9105            Bytes::to_bytes(values),
9106            mask,
9107            Bytes::to_bytes(merge),
9108        ))
9109    }
9110    #[inline(always)]
9111    fn combine_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x8<Self> {
9112        u64x8 {
9113            val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]),
9114            simd: self,
9115        }
9116    }
9117    #[inline(always)]
9118    fn split_u64x4(self, a: u64x4<Self>) -> (u64x2<Self>, u64x2<Self>) {
9119        (
9120            u64x2 {
9121                val: crate::support::Aligned128(a.val.0[0]),
9122                simd: self,
9123            },
9124            u64x2 {
9125                val: crate::support::Aligned128(a.val.0[1]),
9126                simd: self,
9127            },
9128        )
9129    }
9130    #[inline(always)]
9131    fn from_vector_mask64x4(self, vector: i64x4<Self>) -> mask64x4<Self> {
9132        mask64x4 {
9133            val: vector.val,
9134            simd: self,
9135        }
9136    }
9137    #[inline(always)]
9138    fn to_vector_mask64x4(self, a: mask64x4<Self>) -> i64x4<Self> {
9139        i64x4 {
9140            val: a.val,
9141            simd: self,
9142        }
9143    }
9144    #[inline(always)]
9145    fn set_mask64x4(self, a: &mut mask64x4<Self>, index: usize, value: bool) -> () {
9146        assert!(
9147            index < 4usize,
9148            "mask lane index {index} is out of bounds for {} lanes",
9149            4usize
9150        );
9151        let mut lanes: [i64; 4usize] = (*a).into();
9152        lanes[index] = if value { !0 } else { 0 };
9153        *a = lanes.simd_into(self);
9154    }
9155    #[inline(always)]
9156    fn rotate_elements_left_mask64x4<const OFFSET: usize>(
9157        self,
9158        a: mask64x4<Self>,
9159    ) -> mask64x4<Self> {
9160        let int = i64x4 {
9161            val: crate::transmute::checked_transmute_copy(&a.val),
9162            simd: self,
9163        };
9164        let rotated = int.rotate_elements_left::<OFFSET>();
9165        mask64x4 {
9166            val: crate::transmute::checked_transmute_copy(&rotated.val),
9167            simd: self,
9168        }
9169    }
9170    #[inline(always)]
9171    fn rotate_elements_right_mask64x4<const OFFSET: usize>(
9172        self,
9173        a: mask64x4<Self>,
9174    ) -> mask64x4<Self> {
9175        let int = i64x4 {
9176            val: crate::transmute::checked_transmute_copy(&a.val),
9177            simd: self,
9178        };
9179        let rotated = int.rotate_elements_right::<OFFSET>();
9180        mask64x4 {
9181            val: crate::transmute::checked_transmute_copy(&rotated.val),
9182            simd: self,
9183        }
9184    }
9185    #[inline(always)]
9186    fn combine_mask64x4(self, a: mask64x4<Self>, b: mask64x4<Self>) -> mask64x8<Self> {
9187        mask64x8 {
9188            val: crate::support::Aligned512([a.val.0[0], a.val.0[1], b.val.0[0], b.val.0[1]]),
9189            simd: self,
9190        }
9191    }
9192    #[inline(always)]
9193    fn split_mask64x4(self, a: mask64x4<Self>) -> (mask64x2<Self>, mask64x2<Self>) {
9194        (
9195            mask64x2 {
9196                val: crate::support::Aligned128(a.val.0[0]),
9197                simd: self,
9198            },
9199            mask64x2 {
9200                val: crate::support::Aligned128(a.val.0[1]),
9201                simd: self,
9202            },
9203        )
9204    }
9205    #[inline(always)]
9206    fn slide_f32x16<const SHIFT: usize>(self, a: f32x16<Self>, b: f32x16<Self>) -> f32x16<Self> {
9207        if SHIFT >= 16usize {
9208            return b;
9209        }
9210        let result = cross_block_alignr_128x4(
9211            self,
9212            Bytes::to_bytes(b).val.0,
9213            Bytes::to_bytes(a).val.0,
9214            SHIFT * 4usize,
9215        );
9216        Bytes::from_bytes(u8x64 {
9217            val: crate::support::Aligned512(result),
9218            simd: self,
9219        })
9220    }
9221    #[inline(always)]
9222    fn compress_f32x16(self, values: f32x16<Self>, mask: mask32x16<Self>) -> f32x16<Self> {
9223        let mask = mask8x64 {
9224            val: crate::transmute::checked_transmute_copy(&mask.val),
9225            simd: self,
9226        };
9227        Bytes::from_bytes(self.compress_u8x64(Bytes::to_bytes(values), mask))
9228    }
9229    #[inline(always)]
9230    fn compress_merge_f32x16(
9231        self,
9232        values: f32x16<Self>,
9233        mask: mask32x16<Self>,
9234        merge: f32x16<Self>,
9235    ) -> f32x16<Self> {
9236        let mask = mask8x64 {
9237            val: crate::transmute::checked_transmute_copy(&mask.val),
9238            simd: self,
9239        };
9240        Bytes::from_bytes(self.compress_merge_u8x64(
9241            Bytes::to_bytes(values),
9242            mask,
9243            Bytes::to_bytes(merge),
9244        ))
9245    }
9246    #[inline(always)]
9247    fn expand_f32x16(self, values: f32x16<Self>, mask: mask32x16<Self>) -> f32x16<Self> {
9248        let mask = mask8x64 {
9249            val: crate::transmute::checked_transmute_copy(&mask.val),
9250            simd: self,
9251        };
9252        Bytes::from_bytes(self.expand_u8x64(Bytes::to_bytes(values), mask))
9253    }
9254    #[inline(always)]
9255    fn expand_merge_f32x16(
9256        self,
9257        values: f32x16<Self>,
9258        mask: mask32x16<Self>,
9259        merge: f32x16<Self>,
9260    ) -> f32x16<Self> {
9261        let mask = mask8x64 {
9262            val: crate::transmute::checked_transmute_copy(&mask.val),
9263            simd: self,
9264        };
9265        Bytes::from_bytes(self.expand_merge_u8x64(
9266            Bytes::to_bytes(values),
9267            mask,
9268            Bytes::to_bytes(merge),
9269        ))
9270    }
9271    #[inline(always)]
9272    fn simd_ne_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> mask32x16<Self> {
9273        let (a0, a1) = self.split_f32x16(a);
9274        let (b0, b1) = self.split_f32x16(b);
9275        self.combine_mask32x8(self.simd_ne_f32x8(a0, b0), self.simd_ne_f32x8(a1, b1))
9276    }
9277    #[inline(always)]
9278    fn is_nan_f32x16(self, a: f32x16<Self>) -> mask32x16<Self> {
9279        a.simd_ne(a)
9280    }
9281    #[inline(always)]
9282    fn is_infinite_f32x16(self, a: f32x16<Self>) -> mask32x16<Self> {
9283        a.abs().simd_eq(f32::INFINITY)
9284    }
9285    #[inline(always)]
9286    fn is_finite_f32x16(self, a: f32x16<Self>) -> mask32x16<Self> {
9287        a.abs().simd_lt(f32::INFINITY)
9288    }
9289    #[inline(always)]
9290    fn is_subnormal_f32x16(self, a: f32x16<Self>) -> mask32x16<Self> {
9291        let i: i32x16<Self> = a.bitcast();
9292        (i & 0x7F80_0000_i32).simd_eq(0) & (i & 0x007F_FFFF_i32).simd_ne(0)
9293    }
9294    #[inline(always)]
9295    fn is_normal_f32x16(self, a: f32x16<Self>) -> mask32x16<Self> {
9296        let i: i32x16<Self> = a.bitcast();
9297        let exp = i & 0x7F80_0000_i32;
9298        exp.simd_ne(0) & exp.simd_ne(0x7F80_0000_i32)
9299    }
9300    #[inline(always)]
9301    fn is_sign_positive_f32x16(self, a: f32x16<Self>) -> mask32x16<Self> {
9302        let i: i32x16<Self> = a.bitcast();
9303        (i & i32::MIN).simd_eq(0)
9304    }
9305    #[inline(always)]
9306    fn is_sign_negative_f32x16(self, a: f32x16<Self>) -> mask32x16<Self> {
9307        !a.is_sign_positive()
9308    }
9309    #[inline(always)]
9310    fn split_f32x16(self, a: f32x16<Self>) -> (f32x8<Self>, f32x8<Self>) {
9311        (
9312            f32x8 {
9313                val: crate::support::Aligned256([a.val.0[0], a.val.0[1]]),
9314                simd: self,
9315            },
9316            f32x8 {
9317                val: crate::support::Aligned256([a.val.0[2], a.val.0[3]]),
9318                simd: self,
9319            },
9320        )
9321    }
9322    #[inline(always)]
9323    fn slide_i8x64<const SHIFT: usize>(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
9324        if SHIFT >= 64usize {
9325            return b;
9326        }
9327        let result = cross_block_alignr_128x4(
9328            self,
9329            Bytes::to_bytes(b).val.0,
9330            Bytes::to_bytes(a).val.0,
9331            SHIFT,
9332        );
9333        Bytes::from_bytes(u8x64 {
9334            val: crate::support::Aligned512(result),
9335            simd: self,
9336        })
9337    }
9338    #[inline(always)]
9339    fn compress_i8x64(self, values: i8x64<Self>, mask: mask8x64<Self>) -> i8x64<Self> {
9340        let mask = mask8x64 {
9341            val: crate::transmute::checked_transmute_copy(&mask.val),
9342            simd: self,
9343        };
9344        Bytes::from_bytes(self.compress_u8x64(Bytes::to_bytes(values), mask))
9345    }
9346    #[inline(always)]
9347    fn compress_merge_i8x64(
9348        self,
9349        values: i8x64<Self>,
9350        mask: mask8x64<Self>,
9351        merge: i8x64<Self>,
9352    ) -> i8x64<Self> {
9353        let mask = mask8x64 {
9354            val: crate::transmute::checked_transmute_copy(&mask.val),
9355            simd: self,
9356        };
9357        Bytes::from_bytes(self.compress_merge_u8x64(
9358            Bytes::to_bytes(values),
9359            mask,
9360            Bytes::to_bytes(merge),
9361        ))
9362    }
9363    #[inline(always)]
9364    fn expand_i8x64(self, values: i8x64<Self>, mask: mask8x64<Self>) -> i8x64<Self> {
9365        let mask = mask8x64 {
9366            val: crate::transmute::checked_transmute_copy(&mask.val),
9367            simd: self,
9368        };
9369        Bytes::from_bytes(self.expand_u8x64(Bytes::to_bytes(values), mask))
9370    }
9371    #[inline(always)]
9372    fn expand_merge_i8x64(
9373        self,
9374        values: i8x64<Self>,
9375        mask: mask8x64<Self>,
9376        merge: i8x64<Self>,
9377    ) -> i8x64<Self> {
9378        let mask = mask8x64 {
9379            val: crate::transmute::checked_transmute_copy(&mask.val),
9380            simd: self,
9381        };
9382        Bytes::from_bytes(self.expand_merge_u8x64(
9383            Bytes::to_bytes(values),
9384            mask,
9385            Bytes::to_bytes(merge),
9386        ))
9387    }
9388    #[inline(always)]
9389    fn split_i8x64(self, a: i8x64<Self>) -> (i8x32<Self>, i8x32<Self>) {
9390        (
9391            i8x32 {
9392                val: crate::support::Aligned256([a.val.0[0], a.val.0[1]]),
9393                simd: self,
9394            },
9395            i8x32 {
9396                val: crate::support::Aligned256([a.val.0[2], a.val.0[3]]),
9397                simd: self,
9398            },
9399        )
9400    }
9401    #[inline(always)]
9402    fn slide_u8x64<const SHIFT: usize>(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
9403        if SHIFT >= 64usize {
9404            return b;
9405        }
9406        let result = cross_block_alignr_128x4(
9407            self,
9408            Bytes::to_bytes(b).val.0,
9409            Bytes::to_bytes(a).val.0,
9410            SHIFT,
9411        );
9412        Bytes::from_bytes(u8x64 {
9413            val: crate::support::Aligned512(result),
9414            simd: self,
9415        })
9416    }
9417    #[inline(always)]
9418    fn swizzle_dyn_u8x64(self, a: u8x64<Self>, indices: u8x64<Self>) -> u8x64<Self> {
9419        let bytes = Bytes::to_bytes(a);
9420        let mut output = [0u8; 64usize];
9421        for lane in 0..64usize {
9422            let index = indices[lane] as usize;
9423            output[lane] = bytes[index % 64usize];
9424        }
9425        let result: u8x64<Self> = output.simd_into(self);
9426        Bytes::from_bytes(result)
9427    }
9428    #[inline(always)]
9429    fn swizzle_dyn_precise_u8x64(self, a: u8x64<Self>, indices: u8x64<Self>) -> u8x64<Self> {
9430        let bytes = Bytes::to_bytes(a);
9431        let mut output = [0u8; 64usize];
9432        for lane in 0..64usize {
9433            let index = indices[lane] as usize;
9434            let value = bytes[index % 64usize];
9435            output[lane] = core::hint::select_unpredictable(index < 64usize, value, 0u8);
9436        }
9437        let result: u8x64<Self> = output.simd_into(self);
9438        Bytes::from_bytes(result)
9439    }
9440    #[inline(always)]
9441    fn concat_swizzle_dyn_u8x64(
9442        self,
9443        a: u8x64<Self>,
9444        b: u8x64<Self>,
9445        indices: u8x64<Self>,
9446    ) -> u8x64<Self> {
9447        let first_table = Bytes::to_bytes(a);
9448        let second_table = Bytes::to_bytes(b);
9449        let mut output = [0u8; 64usize];
9450        for lane in 0..64usize {
9451            let index = indices[lane] as usize % 128usize;
9452            output[lane] = if index < 64usize {
9453                first_table[index]
9454            } else {
9455                second_table[index - 64usize]
9456            };
9457        }
9458        let result: u8x64<Self> = output.simd_into(self);
9459        Bytes::from_bytes(result)
9460    }
9461    #[inline(always)]
9462    fn concat_swizzle_dyn_precise_u8x64(
9463        self,
9464        a: u8x64<Self>,
9465        b: u8x64<Self>,
9466        indices: u8x64<Self>,
9467    ) -> u8x64<Self> {
9468        let first_table = Bytes::to_bytes(a);
9469        let second_table = Bytes::to_bytes(b);
9470        let mut output = [0u8; 64usize];
9471        for lane in 0..64usize {
9472            let index = indices[lane] as usize;
9473            let table_index = index % 64usize;
9474            let value = if index < 64usize {
9475                first_table[table_index]
9476            } else {
9477                second_table[table_index]
9478            };
9479            output[lane] = if index < 128usize { value } else { 0 };
9480        }
9481        let result: u8x64<Self> = output.simd_into(self);
9482        Bytes::from_bytes(result)
9483    }
9484    #[inline(always)]
9485    fn compress_u8x64(self, values: u8x64<Self>, mask: mask8x64<Self>) -> u8x64<Self> {
9486        self.compress_merge_u8x64(values, mask, u8x64::splat(self, 0))
9487    }
9488    #[inline(always)]
9489    fn compress_merge_u8x64(
9490        self,
9491        values: u8x64<Self>,
9492        mask: mask8x64<Self>,
9493        merge: u8x64<Self>,
9494    ) -> u8x64<Self> {
9495        let mask = self.to_bitmask_mask8x64(mask);
9496        let mut merge_padded = [0u8; 64 + 1];
9497        merge_padded[..64].copy_from_slice(&*merge);
9498        let mut compacted = merge_padded;
9499        let mut output_lane = 0;
9500        for input_lane in 0..64 {
9501            compacted[output_lane] = values[input_lane];
9502            output_lane += ((mask >> input_lane) & 1) as usize;
9503        }
9504        compacted[output_lane] = merge_padded[output_lane];
9505        let mut result = merge;
9506        result.copy_from_slice(&compacted[..64]);
9507        result
9508    }
9509    #[inline(always)]
9510    fn expand_u8x64(self, values: u8x64<Self>, mask: mask8x64<Self>) -> u8x64<Self> {
9511        self.expand_merge_u8x64(values, mask, u8x64::splat(self, 0))
9512    }
9513    #[inline(always)]
9514    fn expand_merge_u8x64(
9515        self,
9516        values: u8x64<Self>,
9517        mask: mask8x64<Self>,
9518        merge: u8x64<Self>,
9519    ) -> u8x64<Self> {
9520        let mask = self.to_bitmask_mask8x64(mask);
9521        let mut result = merge;
9522        let mut input_lane = 0;
9523        for output_lane in 0..64 {
9524            let bit = ((mask >> output_lane) & 1) as u8;
9525            let keep = 0u8.wrapping_sub(bit);
9526            result[output_lane] = (values[input_lane] & keep) | (result[output_lane] & !keep);
9527            input_lane += usize::from(bit);
9528        }
9529        result
9530    }
9531    #[inline(always)]
9532    fn split_u8x64(self, a: u8x64<Self>) -> (u8x32<Self>, u8x32<Self>) {
9533        (
9534            u8x32 {
9535                val: crate::support::Aligned256([a.val.0[0], a.val.0[1]]),
9536                simd: self,
9537            },
9538            u8x32 {
9539                val: crate::support::Aligned256([a.val.0[2], a.val.0[3]]),
9540                simd: self,
9541            },
9542        )
9543    }
9544    #[inline(always)]
9545    fn from_vector_mask8x64(self, vector: i8x64<Self>) -> mask8x64<Self> {
9546        mask8x64 {
9547            val: vector.val,
9548            simd: self,
9549        }
9550    }
9551    #[inline(always)]
9552    fn to_vector_mask8x64(self, a: mask8x64<Self>) -> i8x64<Self> {
9553        i8x64 {
9554            val: a.val,
9555            simd: self,
9556        }
9557    }
9558    #[inline(always)]
9559    fn set_mask8x64(self, a: &mut mask8x64<Self>, index: usize, value: bool) -> () {
9560        assert!(
9561            index < 64usize,
9562            "mask lane index {index} is out of bounds for {} lanes",
9563            64usize
9564        );
9565        let mut lanes: [i8; 64usize] = (*a).into();
9566        lanes[index] = if value { !0 } else { 0 };
9567        *a = lanes.simd_into(self);
9568    }
9569    #[inline(always)]
9570    fn rotate_elements_left_mask8x64<const OFFSET: usize>(
9571        self,
9572        a: mask8x64<Self>,
9573    ) -> mask8x64<Self> {
9574        let int = i8x64 {
9575            val: crate::transmute::checked_transmute_copy(&a.val),
9576            simd: self,
9577        };
9578        let rotated = int.rotate_elements_left::<OFFSET>();
9579        mask8x64 {
9580            val: crate::transmute::checked_transmute_copy(&rotated.val),
9581            simd: self,
9582        }
9583    }
9584    #[inline(always)]
9585    fn rotate_elements_right_mask8x64<const OFFSET: usize>(
9586        self,
9587        a: mask8x64<Self>,
9588    ) -> mask8x64<Self> {
9589        let int = i8x64 {
9590            val: crate::transmute::checked_transmute_copy(&a.val),
9591            simd: self,
9592        };
9593        let rotated = int.rotate_elements_right::<OFFSET>();
9594        mask8x64 {
9595            val: crate::transmute::checked_transmute_copy(&rotated.val),
9596            simd: self,
9597        }
9598    }
9599    #[inline(always)]
9600    fn split_mask8x64(self, a: mask8x64<Self>) -> (mask8x32<Self>, mask8x32<Self>) {
9601        (
9602            mask8x32 {
9603                val: crate::support::Aligned256([a.val.0[0], a.val.0[1]]),
9604                simd: self,
9605            },
9606            mask8x32 {
9607                val: crate::support::Aligned256([a.val.0[2], a.val.0[3]]),
9608                simd: self,
9609            },
9610        )
9611    }
9612    #[inline(always)]
9613    fn slide_i16x32<const SHIFT: usize>(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
9614        if SHIFT >= 32usize {
9615            return b;
9616        }
9617        let result = cross_block_alignr_128x4(
9618            self,
9619            Bytes::to_bytes(b).val.0,
9620            Bytes::to_bytes(a).val.0,
9621            SHIFT * 2usize,
9622        );
9623        Bytes::from_bytes(u8x64 {
9624            val: crate::support::Aligned512(result),
9625            simd: self,
9626        })
9627    }
9628    #[inline(always)]
9629    fn compress_i16x32(self, values: i16x32<Self>, mask: mask16x32<Self>) -> i16x32<Self> {
9630        let mask = mask8x64 {
9631            val: crate::transmute::checked_transmute_copy(&mask.val),
9632            simd: self,
9633        };
9634        Bytes::from_bytes(self.compress_u8x64(Bytes::to_bytes(values), mask))
9635    }
9636    #[inline(always)]
9637    fn compress_merge_i16x32(
9638        self,
9639        values: i16x32<Self>,
9640        mask: mask16x32<Self>,
9641        merge: i16x32<Self>,
9642    ) -> i16x32<Self> {
9643        let mask = mask8x64 {
9644            val: crate::transmute::checked_transmute_copy(&mask.val),
9645            simd: self,
9646        };
9647        Bytes::from_bytes(self.compress_merge_u8x64(
9648            Bytes::to_bytes(values),
9649            mask,
9650            Bytes::to_bytes(merge),
9651        ))
9652    }
9653    #[inline(always)]
9654    fn expand_i16x32(self, values: i16x32<Self>, mask: mask16x32<Self>) -> i16x32<Self> {
9655        let mask = mask8x64 {
9656            val: crate::transmute::checked_transmute_copy(&mask.val),
9657            simd: self,
9658        };
9659        Bytes::from_bytes(self.expand_u8x64(Bytes::to_bytes(values), mask))
9660    }
9661    #[inline(always)]
9662    fn expand_merge_i16x32(
9663        self,
9664        values: i16x32<Self>,
9665        mask: mask16x32<Self>,
9666        merge: i16x32<Self>,
9667    ) -> i16x32<Self> {
9668        let mask = mask8x64 {
9669            val: crate::transmute::checked_transmute_copy(&mask.val),
9670            simd: self,
9671        };
9672        Bytes::from_bytes(self.expand_merge_u8x64(
9673            Bytes::to_bytes(values),
9674            mask,
9675            Bytes::to_bytes(merge),
9676        ))
9677    }
9678    #[inline(always)]
9679    fn split_i16x32(self, a: i16x32<Self>) -> (i16x16<Self>, i16x16<Self>) {
9680        (
9681            i16x16 {
9682                val: crate::support::Aligned256([a.val.0[0], a.val.0[1]]),
9683                simd: self,
9684            },
9685            i16x16 {
9686                val: crate::support::Aligned256([a.val.0[2], a.val.0[3]]),
9687                simd: self,
9688            },
9689        )
9690    }
9691    #[inline(always)]
9692    fn slide_u16x32<const SHIFT: usize>(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9693        if SHIFT >= 32usize {
9694            return b;
9695        }
9696        let result = cross_block_alignr_128x4(
9697            self,
9698            Bytes::to_bytes(b).val.0,
9699            Bytes::to_bytes(a).val.0,
9700            SHIFT * 2usize,
9701        );
9702        Bytes::from_bytes(u8x64 {
9703            val: crate::support::Aligned512(result),
9704            simd: self,
9705        })
9706    }
9707    #[inline(always)]
9708    fn compress_u16x32(self, values: u16x32<Self>, mask: mask16x32<Self>) -> u16x32<Self> {
9709        let mask = mask8x64 {
9710            val: crate::transmute::checked_transmute_copy(&mask.val),
9711            simd: self,
9712        };
9713        Bytes::from_bytes(self.compress_u8x64(Bytes::to_bytes(values), mask))
9714    }
9715    #[inline(always)]
9716    fn compress_merge_u16x32(
9717        self,
9718        values: u16x32<Self>,
9719        mask: mask16x32<Self>,
9720        merge: u16x32<Self>,
9721    ) -> u16x32<Self> {
9722        let mask = mask8x64 {
9723            val: crate::transmute::checked_transmute_copy(&mask.val),
9724            simd: self,
9725        };
9726        Bytes::from_bytes(self.compress_merge_u8x64(
9727            Bytes::to_bytes(values),
9728            mask,
9729            Bytes::to_bytes(merge),
9730        ))
9731    }
9732    #[inline(always)]
9733    fn expand_u16x32(self, values: u16x32<Self>, mask: mask16x32<Self>) -> u16x32<Self> {
9734        let mask = mask8x64 {
9735            val: crate::transmute::checked_transmute_copy(&mask.val),
9736            simd: self,
9737        };
9738        Bytes::from_bytes(self.expand_u8x64(Bytes::to_bytes(values), mask))
9739    }
9740    #[inline(always)]
9741    fn expand_merge_u16x32(
9742        self,
9743        values: u16x32<Self>,
9744        mask: mask16x32<Self>,
9745        merge: u16x32<Self>,
9746    ) -> u16x32<Self> {
9747        let mask = mask8x64 {
9748            val: crate::transmute::checked_transmute_copy(&mask.val),
9749            simd: self,
9750        };
9751        Bytes::from_bytes(self.expand_merge_u8x64(
9752            Bytes::to_bytes(values),
9753            mask,
9754            Bytes::to_bytes(merge),
9755        ))
9756    }
9757    #[inline(always)]
9758    fn split_u16x32(self, a: u16x32<Self>) -> (u16x16<Self>, u16x16<Self>) {
9759        (
9760            u16x16 {
9761                val: crate::support::Aligned256([a.val.0[0], a.val.0[1]]),
9762                simd: self,
9763            },
9764            u16x16 {
9765                val: crate::support::Aligned256([a.val.0[2], a.val.0[3]]),
9766                simd: self,
9767            },
9768        )
9769    }
9770    #[inline(always)]
9771    fn to_bitmask_mask16x32(self, a: mask16x32<Self>) -> u64 {
9772        crate::kernel!(
9773            #[inline(always)]
9774            fn kernel(token: Sse2, a: mask16x32<Sse2>) -> u64 {
9775                {
9776                    let lo = _mm_packs_epi16(a.val.0[0], a.val.0[1]);
9777                    let hi = _mm_packs_epi16(a.val.0[2], a.val.0[3]);
9778                    let lo = _mm_movemask_epi8(lo) as u32 as u64;
9779                    let hi = _mm_movemask_epi8(hi) as u32 as u64;
9780                    lo | (hi << 16usize)
9781                }
9782            }
9783        );
9784        kernel(self, a)
9785    }
9786    #[inline(always)]
9787    fn from_vector_mask16x32(self, vector: i16x32<Self>) -> mask16x32<Self> {
9788        mask16x32 {
9789            val: vector.val,
9790            simd: self,
9791        }
9792    }
9793    #[inline(always)]
9794    fn to_vector_mask16x32(self, a: mask16x32<Self>) -> i16x32<Self> {
9795        i16x32 {
9796            val: a.val,
9797            simd: self,
9798        }
9799    }
9800    #[inline(always)]
9801    fn set_mask16x32(self, a: &mut mask16x32<Self>, index: usize, value: bool) -> () {
9802        assert!(
9803            index < 32usize,
9804            "mask lane index {index} is out of bounds for {} lanes",
9805            32usize
9806        );
9807        let mut lanes: [i16; 32usize] = (*a).into();
9808        lanes[index] = if value { !0 } else { 0 };
9809        *a = lanes.simd_into(self);
9810    }
9811    #[inline(always)]
9812    fn rotate_elements_left_mask16x32<const OFFSET: usize>(
9813        self,
9814        a: mask16x32<Self>,
9815    ) -> mask16x32<Self> {
9816        let int = i16x32 {
9817            val: crate::transmute::checked_transmute_copy(&a.val),
9818            simd: self,
9819        };
9820        let rotated = int.rotate_elements_left::<OFFSET>();
9821        mask16x32 {
9822            val: crate::transmute::checked_transmute_copy(&rotated.val),
9823            simd: self,
9824        }
9825    }
9826    #[inline(always)]
9827    fn rotate_elements_right_mask16x32<const OFFSET: usize>(
9828        self,
9829        a: mask16x32<Self>,
9830    ) -> mask16x32<Self> {
9831        let int = i16x32 {
9832            val: crate::transmute::checked_transmute_copy(&a.val),
9833            simd: self,
9834        };
9835        let rotated = int.rotate_elements_right::<OFFSET>();
9836        mask16x32 {
9837            val: crate::transmute::checked_transmute_copy(&rotated.val),
9838            simd: self,
9839        }
9840    }
9841    #[inline(always)]
9842    fn split_mask16x32(self, a: mask16x32<Self>) -> (mask16x16<Self>, mask16x16<Self>) {
9843        (
9844            mask16x16 {
9845                val: crate::support::Aligned256([a.val.0[0], a.val.0[1]]),
9846                simd: self,
9847            },
9848            mask16x16 {
9849                val: crate::support::Aligned256([a.val.0[2], a.val.0[3]]),
9850                simd: self,
9851            },
9852        )
9853    }
9854    #[inline(always)]
9855    fn slide_i32x16<const SHIFT: usize>(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9856        if SHIFT >= 16usize {
9857            return b;
9858        }
9859        let result = cross_block_alignr_128x4(
9860            self,
9861            Bytes::to_bytes(b).val.0,
9862            Bytes::to_bytes(a).val.0,
9863            SHIFT * 4usize,
9864        );
9865        Bytes::from_bytes(u8x64 {
9866            val: crate::support::Aligned512(result),
9867            simd: self,
9868        })
9869    }
9870    #[inline(always)]
9871    fn compress_i32x16(self, values: i32x16<Self>, mask: mask32x16<Self>) -> i32x16<Self> {
9872        let mask = mask8x64 {
9873            val: crate::transmute::checked_transmute_copy(&mask.val),
9874            simd: self,
9875        };
9876        Bytes::from_bytes(self.compress_u8x64(Bytes::to_bytes(values), mask))
9877    }
9878    #[inline(always)]
9879    fn compress_merge_i32x16(
9880        self,
9881        values: i32x16<Self>,
9882        mask: mask32x16<Self>,
9883        merge: i32x16<Self>,
9884    ) -> i32x16<Self> {
9885        let mask = mask8x64 {
9886            val: crate::transmute::checked_transmute_copy(&mask.val),
9887            simd: self,
9888        };
9889        Bytes::from_bytes(self.compress_merge_u8x64(
9890            Bytes::to_bytes(values),
9891            mask,
9892            Bytes::to_bytes(merge),
9893        ))
9894    }
9895    #[inline(always)]
9896    fn expand_i32x16(self, values: i32x16<Self>, mask: mask32x16<Self>) -> i32x16<Self> {
9897        let mask = mask8x64 {
9898            val: crate::transmute::checked_transmute_copy(&mask.val),
9899            simd: self,
9900        };
9901        Bytes::from_bytes(self.expand_u8x64(Bytes::to_bytes(values), mask))
9902    }
9903    #[inline(always)]
9904    fn expand_merge_i32x16(
9905        self,
9906        values: i32x16<Self>,
9907        mask: mask32x16<Self>,
9908        merge: i32x16<Self>,
9909    ) -> i32x16<Self> {
9910        let mask = mask8x64 {
9911            val: crate::transmute::checked_transmute_copy(&mask.val),
9912            simd: self,
9913        };
9914        Bytes::from_bytes(self.expand_merge_u8x64(
9915            Bytes::to_bytes(values),
9916            mask,
9917            Bytes::to_bytes(merge),
9918        ))
9919    }
9920    #[inline(always)]
9921    fn split_i32x16(self, a: i32x16<Self>) -> (i32x8<Self>, i32x8<Self>) {
9922        (
9923            i32x8 {
9924                val: crate::support::Aligned256([a.val.0[0], a.val.0[1]]),
9925                simd: self,
9926            },
9927            i32x8 {
9928                val: crate::support::Aligned256([a.val.0[2], a.val.0[3]]),
9929                simd: self,
9930            },
9931        )
9932    }
9933    #[inline(always)]
9934    fn slide_u32x16<const SHIFT: usize>(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
9935        if SHIFT >= 16usize {
9936            return b;
9937        }
9938        let result = cross_block_alignr_128x4(
9939            self,
9940            Bytes::to_bytes(b).val.0,
9941            Bytes::to_bytes(a).val.0,
9942            SHIFT * 4usize,
9943        );
9944        Bytes::from_bytes(u8x64 {
9945            val: crate::support::Aligned512(result),
9946            simd: self,
9947        })
9948    }
9949    #[inline(always)]
9950    fn compress_u32x16(self, values: u32x16<Self>, mask: mask32x16<Self>) -> u32x16<Self> {
9951        let mask = mask8x64 {
9952            val: crate::transmute::checked_transmute_copy(&mask.val),
9953            simd: self,
9954        };
9955        Bytes::from_bytes(self.compress_u8x64(Bytes::to_bytes(values), mask))
9956    }
9957    #[inline(always)]
9958    fn compress_merge_u32x16(
9959        self,
9960        values: u32x16<Self>,
9961        mask: mask32x16<Self>,
9962        merge: u32x16<Self>,
9963    ) -> u32x16<Self> {
9964        let mask = mask8x64 {
9965            val: crate::transmute::checked_transmute_copy(&mask.val),
9966            simd: self,
9967        };
9968        Bytes::from_bytes(self.compress_merge_u8x64(
9969            Bytes::to_bytes(values),
9970            mask,
9971            Bytes::to_bytes(merge),
9972        ))
9973    }
9974    #[inline(always)]
9975    fn expand_u32x16(self, values: u32x16<Self>, mask: mask32x16<Self>) -> u32x16<Self> {
9976        let mask = mask8x64 {
9977            val: crate::transmute::checked_transmute_copy(&mask.val),
9978            simd: self,
9979        };
9980        Bytes::from_bytes(self.expand_u8x64(Bytes::to_bytes(values), mask))
9981    }
9982    #[inline(always)]
9983    fn expand_merge_u32x16(
9984        self,
9985        values: u32x16<Self>,
9986        mask: mask32x16<Self>,
9987        merge: u32x16<Self>,
9988    ) -> u32x16<Self> {
9989        let mask = mask8x64 {
9990            val: crate::transmute::checked_transmute_copy(&mask.val),
9991            simd: self,
9992        };
9993        Bytes::from_bytes(self.expand_merge_u8x64(
9994            Bytes::to_bytes(values),
9995            mask,
9996            Bytes::to_bytes(merge),
9997        ))
9998    }
9999    #[inline(always)]
10000    fn split_u32x16(self, a: u32x16<Self>) -> (u32x8<Self>, u32x8<Self>) {
10001        (
10002            u32x8 {
10003                val: crate::support::Aligned256([a.val.0[0], a.val.0[1]]),
10004                simd: self,
10005            },
10006            u32x8 {
10007                val: crate::support::Aligned256([a.val.0[2], a.val.0[3]]),
10008                simd: self,
10009            },
10010        )
10011    }
10012    #[inline(always)]
10013    fn from_vector_mask32x16(self, vector: i32x16<Self>) -> mask32x16<Self> {
10014        mask32x16 {
10015            val: vector.val,
10016            simd: self,
10017        }
10018    }
10019    #[inline(always)]
10020    fn to_vector_mask32x16(self, a: mask32x16<Self>) -> i32x16<Self> {
10021        i32x16 {
10022            val: a.val,
10023            simd: self,
10024        }
10025    }
10026    #[inline(always)]
10027    fn set_mask32x16(self, a: &mut mask32x16<Self>, index: usize, value: bool) -> () {
10028        assert!(
10029            index < 16usize,
10030            "mask lane index {index} is out of bounds for {} lanes",
10031            16usize
10032        );
10033        let mut lanes: [i32; 16usize] = (*a).into();
10034        lanes[index] = if value { !0 } else { 0 };
10035        *a = lanes.simd_into(self);
10036    }
10037    #[inline(always)]
10038    fn rotate_elements_left_mask32x16<const OFFSET: usize>(
10039        self,
10040        a: mask32x16<Self>,
10041    ) -> mask32x16<Self> {
10042        let int = i32x16 {
10043            val: crate::transmute::checked_transmute_copy(&a.val),
10044            simd: self,
10045        };
10046        let rotated = int.rotate_elements_left::<OFFSET>();
10047        mask32x16 {
10048            val: crate::transmute::checked_transmute_copy(&rotated.val),
10049            simd: self,
10050        }
10051    }
10052    #[inline(always)]
10053    fn rotate_elements_right_mask32x16<const OFFSET: usize>(
10054        self,
10055        a: mask32x16<Self>,
10056    ) -> mask32x16<Self> {
10057        let int = i32x16 {
10058            val: crate::transmute::checked_transmute_copy(&a.val),
10059            simd: self,
10060        };
10061        let rotated = int.rotate_elements_right::<OFFSET>();
10062        mask32x16 {
10063            val: crate::transmute::checked_transmute_copy(&rotated.val),
10064            simd: self,
10065        }
10066    }
10067    #[inline(always)]
10068    fn split_mask32x16(self, a: mask32x16<Self>) -> (mask32x8<Self>, mask32x8<Self>) {
10069        (
10070            mask32x8 {
10071                val: crate::support::Aligned256([a.val.0[0], a.val.0[1]]),
10072                simd: self,
10073            },
10074            mask32x8 {
10075                val: crate::support::Aligned256([a.val.0[2], a.val.0[3]]),
10076                simd: self,
10077            },
10078        )
10079    }
10080    #[inline(always)]
10081    fn slide_f64x8<const SHIFT: usize>(self, a: f64x8<Self>, b: f64x8<Self>) -> f64x8<Self> {
10082        if SHIFT >= 8usize {
10083            return b;
10084        }
10085        let result = cross_block_alignr_128x4(
10086            self,
10087            Bytes::to_bytes(b).val.0,
10088            Bytes::to_bytes(a).val.0,
10089            SHIFT * 8usize,
10090        );
10091        Bytes::from_bytes(u8x64 {
10092            val: crate::support::Aligned512(result),
10093            simd: self,
10094        })
10095    }
10096    #[inline(always)]
10097    fn compress_f64x8(self, values: f64x8<Self>, mask: mask64x8<Self>) -> f64x8<Self> {
10098        let mask = mask8x64 {
10099            val: crate::transmute::checked_transmute_copy(&mask.val),
10100            simd: self,
10101        };
10102        Bytes::from_bytes(self.compress_u8x64(Bytes::to_bytes(values), mask))
10103    }
10104    #[inline(always)]
10105    fn compress_merge_f64x8(
10106        self,
10107        values: f64x8<Self>,
10108        mask: mask64x8<Self>,
10109        merge: f64x8<Self>,
10110    ) -> f64x8<Self> {
10111        let mask = mask8x64 {
10112            val: crate::transmute::checked_transmute_copy(&mask.val),
10113            simd: self,
10114        };
10115        Bytes::from_bytes(self.compress_merge_u8x64(
10116            Bytes::to_bytes(values),
10117            mask,
10118            Bytes::to_bytes(merge),
10119        ))
10120    }
10121    #[inline(always)]
10122    fn expand_f64x8(self, values: f64x8<Self>, mask: mask64x8<Self>) -> f64x8<Self> {
10123        let mask = mask8x64 {
10124            val: crate::transmute::checked_transmute_copy(&mask.val),
10125            simd: self,
10126        };
10127        Bytes::from_bytes(self.expand_u8x64(Bytes::to_bytes(values), mask))
10128    }
10129    #[inline(always)]
10130    fn expand_merge_f64x8(
10131        self,
10132        values: f64x8<Self>,
10133        mask: mask64x8<Self>,
10134        merge: f64x8<Self>,
10135    ) -> f64x8<Self> {
10136        let mask = mask8x64 {
10137            val: crate::transmute::checked_transmute_copy(&mask.val),
10138            simd: self,
10139        };
10140        Bytes::from_bytes(self.expand_merge_u8x64(
10141            Bytes::to_bytes(values),
10142            mask,
10143            Bytes::to_bytes(merge),
10144        ))
10145    }
10146    #[inline(always)]
10147    fn simd_ne_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> mask64x8<Self> {
10148        let (a0, a1) = self.split_f64x8(a);
10149        let (b0, b1) = self.split_f64x8(b);
10150        self.combine_mask64x4(self.simd_ne_f64x4(a0, b0), self.simd_ne_f64x4(a1, b1))
10151    }
10152    #[inline(always)]
10153    fn is_nan_f64x8(self, a: f64x8<Self>) -> mask64x8<Self> {
10154        a.simd_ne(a)
10155    }
10156    #[inline(always)]
10157    fn is_infinite_f64x8(self, a: f64x8<Self>) -> mask64x8<Self> {
10158        a.abs().simd_eq(f64::INFINITY)
10159    }
10160    #[inline(always)]
10161    fn is_finite_f64x8(self, a: f64x8<Self>) -> mask64x8<Self> {
10162        a.abs().simd_lt(f64::INFINITY)
10163    }
10164    #[inline(always)]
10165    fn is_subnormal_f64x8(self, a: f64x8<Self>) -> mask64x8<Self> {
10166        let i: i64x8<Self> = a.bitcast();
10167        (i & 0x7FF0_0000_0000_0000_i64).simd_eq(0) & (i & 0x000F_FFFF_FFFF_FFFF_i64).simd_ne(0)
10168    }
10169    #[inline(always)]
10170    fn is_normal_f64x8(self, a: f64x8<Self>) -> mask64x8<Self> {
10171        let i: i64x8<Self> = a.bitcast();
10172        let exp = i & 0x7FF0_0000_0000_0000_i64;
10173        exp.simd_ne(0) & exp.simd_ne(0x7FF0_0000_0000_0000_i64)
10174    }
10175    #[inline(always)]
10176    fn is_sign_positive_f64x8(self, a: f64x8<Self>) -> mask64x8<Self> {
10177        let i: i64x8<Self> = a.bitcast();
10178        (i & i64::MIN).simd_eq(0)
10179    }
10180    #[inline(always)]
10181    fn is_sign_negative_f64x8(self, a: f64x8<Self>) -> mask64x8<Self> {
10182        !a.is_sign_positive()
10183    }
10184    #[inline(always)]
10185    fn split_f64x8(self, a: f64x8<Self>) -> (f64x4<Self>, f64x4<Self>) {
10186        (
10187            f64x4 {
10188                val: crate::support::Aligned256([a.val.0[0], a.val.0[1]]),
10189                simd: self,
10190            },
10191            f64x4 {
10192                val: crate::support::Aligned256([a.val.0[2], a.val.0[3]]),
10193                simd: self,
10194            },
10195        )
10196    }
10197    #[inline(always)]
10198    fn slide_i64x8<const SHIFT: usize>(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
10199        if SHIFT >= 8usize {
10200            return b;
10201        }
10202        let result = cross_block_alignr_128x4(
10203            self,
10204            Bytes::to_bytes(b).val.0,
10205            Bytes::to_bytes(a).val.0,
10206            SHIFT * 8usize,
10207        );
10208        Bytes::from_bytes(u8x64 {
10209            val: crate::support::Aligned512(result),
10210            simd: self,
10211        })
10212    }
10213    #[inline(always)]
10214    fn compress_i64x8(self, values: i64x8<Self>, mask: mask64x8<Self>) -> i64x8<Self> {
10215        let mask = mask8x64 {
10216            val: crate::transmute::checked_transmute_copy(&mask.val),
10217            simd: self,
10218        };
10219        Bytes::from_bytes(self.compress_u8x64(Bytes::to_bytes(values), mask))
10220    }
10221    #[inline(always)]
10222    fn compress_merge_i64x8(
10223        self,
10224        values: i64x8<Self>,
10225        mask: mask64x8<Self>,
10226        merge: i64x8<Self>,
10227    ) -> i64x8<Self> {
10228        let mask = mask8x64 {
10229            val: crate::transmute::checked_transmute_copy(&mask.val),
10230            simd: self,
10231        };
10232        Bytes::from_bytes(self.compress_merge_u8x64(
10233            Bytes::to_bytes(values),
10234            mask,
10235            Bytes::to_bytes(merge),
10236        ))
10237    }
10238    #[inline(always)]
10239    fn expand_i64x8(self, values: i64x8<Self>, mask: mask64x8<Self>) -> i64x8<Self> {
10240        let mask = mask8x64 {
10241            val: crate::transmute::checked_transmute_copy(&mask.val),
10242            simd: self,
10243        };
10244        Bytes::from_bytes(self.expand_u8x64(Bytes::to_bytes(values), mask))
10245    }
10246    #[inline(always)]
10247    fn expand_merge_i64x8(
10248        self,
10249        values: i64x8<Self>,
10250        mask: mask64x8<Self>,
10251        merge: i64x8<Self>,
10252    ) -> i64x8<Self> {
10253        let mask = mask8x64 {
10254            val: crate::transmute::checked_transmute_copy(&mask.val),
10255            simd: self,
10256        };
10257        Bytes::from_bytes(self.expand_merge_u8x64(
10258            Bytes::to_bytes(values),
10259            mask,
10260            Bytes::to_bytes(merge),
10261        ))
10262    }
10263    #[inline(always)]
10264    fn split_i64x8(self, a: i64x8<Self>) -> (i64x4<Self>, i64x4<Self>) {
10265        (
10266            i64x4 {
10267                val: crate::support::Aligned256([a.val.0[0], a.val.0[1]]),
10268                simd: self,
10269            },
10270            i64x4 {
10271                val: crate::support::Aligned256([a.val.0[2], a.val.0[3]]),
10272                simd: self,
10273            },
10274        )
10275    }
10276    #[inline(always)]
10277    fn slide_u64x8<const SHIFT: usize>(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
10278        if SHIFT >= 8usize {
10279            return b;
10280        }
10281        let result = cross_block_alignr_128x4(
10282            self,
10283            Bytes::to_bytes(b).val.0,
10284            Bytes::to_bytes(a).val.0,
10285            SHIFT * 8usize,
10286        );
10287        Bytes::from_bytes(u8x64 {
10288            val: crate::support::Aligned512(result),
10289            simd: self,
10290        })
10291    }
10292    #[inline(always)]
10293    fn compress_u64x8(self, values: u64x8<Self>, mask: mask64x8<Self>) -> u64x8<Self> {
10294        let mask = mask8x64 {
10295            val: crate::transmute::checked_transmute_copy(&mask.val),
10296            simd: self,
10297        };
10298        Bytes::from_bytes(self.compress_u8x64(Bytes::to_bytes(values), mask))
10299    }
10300    #[inline(always)]
10301    fn compress_merge_u64x8(
10302        self,
10303        values: u64x8<Self>,
10304        mask: mask64x8<Self>,
10305        merge: u64x8<Self>,
10306    ) -> u64x8<Self> {
10307        let mask = mask8x64 {
10308            val: crate::transmute::checked_transmute_copy(&mask.val),
10309            simd: self,
10310        };
10311        Bytes::from_bytes(self.compress_merge_u8x64(
10312            Bytes::to_bytes(values),
10313            mask,
10314            Bytes::to_bytes(merge),
10315        ))
10316    }
10317    #[inline(always)]
10318    fn expand_u64x8(self, values: u64x8<Self>, mask: mask64x8<Self>) -> u64x8<Self> {
10319        let mask = mask8x64 {
10320            val: crate::transmute::checked_transmute_copy(&mask.val),
10321            simd: self,
10322        };
10323        Bytes::from_bytes(self.expand_u8x64(Bytes::to_bytes(values), mask))
10324    }
10325    #[inline(always)]
10326    fn expand_merge_u64x8(
10327        self,
10328        values: u64x8<Self>,
10329        mask: mask64x8<Self>,
10330        merge: u64x8<Self>,
10331    ) -> u64x8<Self> {
10332        let mask = mask8x64 {
10333            val: crate::transmute::checked_transmute_copy(&mask.val),
10334            simd: self,
10335        };
10336        Bytes::from_bytes(self.expand_merge_u8x64(
10337            Bytes::to_bytes(values),
10338            mask,
10339            Bytes::to_bytes(merge),
10340        ))
10341    }
10342    #[inline(always)]
10343    fn split_u64x8(self, a: u64x8<Self>) -> (u64x4<Self>, u64x4<Self>) {
10344        (
10345            u64x4 {
10346                val: crate::support::Aligned256([a.val.0[0], a.val.0[1]]),
10347                simd: self,
10348            },
10349            u64x4 {
10350                val: crate::support::Aligned256([a.val.0[2], a.val.0[3]]),
10351                simd: self,
10352            },
10353        )
10354    }
10355    #[inline(always)]
10356    fn from_vector_mask64x8(self, vector: i64x8<Self>) -> mask64x8<Self> {
10357        mask64x8 {
10358            val: vector.val,
10359            simd: self,
10360        }
10361    }
10362    #[inline(always)]
10363    fn to_vector_mask64x8(self, a: mask64x8<Self>) -> i64x8<Self> {
10364        i64x8 {
10365            val: a.val,
10366            simd: self,
10367        }
10368    }
10369    #[inline(always)]
10370    fn set_mask64x8(self, a: &mut mask64x8<Self>, index: usize, value: bool) -> () {
10371        assert!(
10372            index < 8usize,
10373            "mask lane index {index} is out of bounds for {} lanes",
10374            8usize
10375        );
10376        let mut lanes: [i64; 8usize] = (*a).into();
10377        lanes[index] = if value { !0 } else { 0 };
10378        *a = lanes.simd_into(self);
10379    }
10380    #[inline(always)]
10381    fn rotate_elements_left_mask64x8<const OFFSET: usize>(
10382        self,
10383        a: mask64x8<Self>,
10384    ) -> mask64x8<Self> {
10385        let int = i64x8 {
10386            val: crate::transmute::checked_transmute_copy(&a.val),
10387            simd: self,
10388        };
10389        let rotated = int.rotate_elements_left::<OFFSET>();
10390        mask64x8 {
10391            val: crate::transmute::checked_transmute_copy(&rotated.val),
10392            simd: self,
10393        }
10394    }
10395    #[inline(always)]
10396    fn rotate_elements_right_mask64x8<const OFFSET: usize>(
10397        self,
10398        a: mask64x8<Self>,
10399    ) -> mask64x8<Self> {
10400        let int = i64x8 {
10401            val: crate::transmute::checked_transmute_copy(&a.val),
10402            simd: self,
10403        };
10404        let rotated = int.rotate_elements_right::<OFFSET>();
10405        mask64x8 {
10406            val: crate::transmute::checked_transmute_copy(&rotated.val),
10407            simd: self,
10408        }
10409    }
10410    #[inline(always)]
10411    fn split_mask64x8(self, a: mask64x8<Self>) -> (mask64x4<Self>, mask64x4<Self>) {
10412        (
10413            mask64x4 {
10414                val: crate::support::Aligned256([a.val.0[0], a.val.0[1]]),
10415                simd: self,
10416            },
10417            mask64x4 {
10418                val: crate::support::Aligned256([a.val.0[2], a.val.0[3]]),
10419                simd: self,
10420            },
10421        )
10422    }
10423}
10424impl<S: Simd> SimdFrom<__m128, S> for f32x4<S> {
10425    #[inline(always)]
10426    fn simd_from(simd: S, arch: __m128) -> Self {
10427        Self {
10428            val: crate::transmute::checked_transmute_copy(&arch),
10429            simd,
10430        }
10431    }
10432}
10433impl<S: Simd> From<f32x4<S>> for __m128 {
10434    #[inline(always)]
10435    fn from(value: f32x4<S>) -> Self {
10436        crate::transmute::checked_transmute_copy(&value.val)
10437    }
10438}
10439impl<S: Simd> SimdFrom<__m128i, S> for i8x16<S> {
10440    #[inline(always)]
10441    fn simd_from(simd: S, arch: __m128i) -> Self {
10442        Self {
10443            val: crate::transmute::checked_transmute_copy(&arch),
10444            simd,
10445        }
10446    }
10447}
10448impl<S: Simd> From<i8x16<S>> for __m128i {
10449    #[inline(always)]
10450    fn from(value: i8x16<S>) -> Self {
10451        crate::transmute::checked_transmute_copy(&value.val)
10452    }
10453}
10454impl<S: Simd> SimdFrom<__m128i, S> for u8x16<S> {
10455    #[inline(always)]
10456    fn simd_from(simd: S, arch: __m128i) -> Self {
10457        Self {
10458            val: crate::transmute::checked_transmute_copy(&arch),
10459            simd,
10460        }
10461    }
10462}
10463impl<S: Simd> From<u8x16<S>> for __m128i {
10464    #[inline(always)]
10465    fn from(value: u8x16<S>) -> Self {
10466        crate::transmute::checked_transmute_copy(&value.val)
10467    }
10468}
10469impl<S: Simd> SimdFrom<__m128i, S> for mask8x16<S> {
10470    #[inline(always)]
10471    fn simd_from(simd: S, arch: __m128i) -> Self {
10472        let lanes: [i8; 16usize] = crate::transmute::checked_transmute_copy(&arch);
10473        lanes.simd_into(simd)
10474    }
10475}
10476impl<S: Simd> From<mask8x16<S>> for __m128i {
10477    #[inline(always)]
10478    fn from(value: mask8x16<S>) -> Self {
10479        let lanes: [i8; 16usize] = value.into();
10480        crate::transmute::checked_transmute_copy(&lanes)
10481    }
10482}
10483impl<S: Simd> SimdFrom<__m128i, S> for i16x8<S> {
10484    #[inline(always)]
10485    fn simd_from(simd: S, arch: __m128i) -> Self {
10486        Self {
10487            val: crate::transmute::checked_transmute_copy(&arch),
10488            simd,
10489        }
10490    }
10491}
10492impl<S: Simd> From<i16x8<S>> for __m128i {
10493    #[inline(always)]
10494    fn from(value: i16x8<S>) -> Self {
10495        crate::transmute::checked_transmute_copy(&value.val)
10496    }
10497}
10498impl<S: Simd> SimdFrom<__m128i, S> for u16x8<S> {
10499    #[inline(always)]
10500    fn simd_from(simd: S, arch: __m128i) -> Self {
10501        Self {
10502            val: crate::transmute::checked_transmute_copy(&arch),
10503            simd,
10504        }
10505    }
10506}
10507impl<S: Simd> From<u16x8<S>> for __m128i {
10508    #[inline(always)]
10509    fn from(value: u16x8<S>) -> Self {
10510        crate::transmute::checked_transmute_copy(&value.val)
10511    }
10512}
10513impl<S: Simd> SimdFrom<__m128i, S> for mask16x8<S> {
10514    #[inline(always)]
10515    fn simd_from(simd: S, arch: __m128i) -> Self {
10516        let lanes: [i16; 8usize] = crate::transmute::checked_transmute_copy(&arch);
10517        lanes.simd_into(simd)
10518    }
10519}
10520impl<S: Simd> From<mask16x8<S>> for __m128i {
10521    #[inline(always)]
10522    fn from(value: mask16x8<S>) -> Self {
10523        let lanes: [i16; 8usize] = value.into();
10524        crate::transmute::checked_transmute_copy(&lanes)
10525    }
10526}
10527impl<S: Simd> SimdFrom<__m128i, S> for i32x4<S> {
10528    #[inline(always)]
10529    fn simd_from(simd: S, arch: __m128i) -> Self {
10530        Self {
10531            val: crate::transmute::checked_transmute_copy(&arch),
10532            simd,
10533        }
10534    }
10535}
10536impl<S: Simd> From<i32x4<S>> for __m128i {
10537    #[inline(always)]
10538    fn from(value: i32x4<S>) -> Self {
10539        crate::transmute::checked_transmute_copy(&value.val)
10540    }
10541}
10542impl<S: Simd> SimdFrom<__m128i, S> for u32x4<S> {
10543    #[inline(always)]
10544    fn simd_from(simd: S, arch: __m128i) -> Self {
10545        Self {
10546            val: crate::transmute::checked_transmute_copy(&arch),
10547            simd,
10548        }
10549    }
10550}
10551impl<S: Simd> From<u32x4<S>> for __m128i {
10552    #[inline(always)]
10553    fn from(value: u32x4<S>) -> Self {
10554        crate::transmute::checked_transmute_copy(&value.val)
10555    }
10556}
10557impl<S: Simd> SimdFrom<__m128i, S> for mask32x4<S> {
10558    #[inline(always)]
10559    fn simd_from(simd: S, arch: __m128i) -> Self {
10560        let lanes: [i32; 4usize] = crate::transmute::checked_transmute_copy(&arch);
10561        lanes.simd_into(simd)
10562    }
10563}
10564impl<S: Simd> From<mask32x4<S>> for __m128i {
10565    #[inline(always)]
10566    fn from(value: mask32x4<S>) -> Self {
10567        let lanes: [i32; 4usize] = value.into();
10568        crate::transmute::checked_transmute_copy(&lanes)
10569    }
10570}
10571impl<S: Simd> SimdFrom<__m128d, S> for f64x2<S> {
10572    #[inline(always)]
10573    fn simd_from(simd: S, arch: __m128d) -> Self {
10574        Self {
10575            val: crate::transmute::checked_transmute_copy(&arch),
10576            simd,
10577        }
10578    }
10579}
10580impl<S: Simd> From<f64x2<S>> for __m128d {
10581    #[inline(always)]
10582    fn from(value: f64x2<S>) -> Self {
10583        crate::transmute::checked_transmute_copy(&value.val)
10584    }
10585}
10586impl<S: Simd> SimdFrom<__m128i, S> for i64x2<S> {
10587    #[inline(always)]
10588    fn simd_from(simd: S, arch: __m128i) -> Self {
10589        Self {
10590            val: crate::transmute::checked_transmute_copy(&arch),
10591            simd,
10592        }
10593    }
10594}
10595impl<S: Simd> From<i64x2<S>> for __m128i {
10596    #[inline(always)]
10597    fn from(value: i64x2<S>) -> Self {
10598        crate::transmute::checked_transmute_copy(&value.val)
10599    }
10600}
10601impl<S: Simd> SimdFrom<__m128i, S> for u64x2<S> {
10602    #[inline(always)]
10603    fn simd_from(simd: S, arch: __m128i) -> Self {
10604        Self {
10605            val: crate::transmute::checked_transmute_copy(&arch),
10606            simd,
10607        }
10608    }
10609}
10610impl<S: Simd> From<u64x2<S>> for __m128i {
10611    #[inline(always)]
10612    fn from(value: u64x2<S>) -> Self {
10613        crate::transmute::checked_transmute_copy(&value.val)
10614    }
10615}
10616impl<S: Simd> SimdFrom<__m128i, S> for mask64x2<S> {
10617    #[inline(always)]
10618    fn simd_from(simd: S, arch: __m128i) -> Self {
10619        let lanes: [i64; 2usize] = crate::transmute::checked_transmute_copy(&arch);
10620        lanes.simd_into(simd)
10621    }
10622}
10623impl<S: Simd> From<mask64x2<S>> for __m128i {
10624    #[inline(always)]
10625    fn from(value: mask64x2<S>) -> Self {
10626        let lanes: [i64; 2usize] = value.into();
10627        crate::transmute::checked_transmute_copy(&lanes)
10628    }
10629}
10630crate::kernel!(
10631    #[doc = r" This is a version of the `alignr` intrinsic that takes a non-const shift argument. The shift is still"]
10632    #[doc = r" expected to be constant in practice, so the match statement will be optimized out. This exists because"]
10633    #[doc = r" Rust doesn't currently let you do math on const generics."]
10634    #[inline(always)]
10635    fn dyn_alignr_128(token: Sse2, a: __m128i, b: __m128i, shift: usize) -> __m128i {
10636        match shift {
10637            0usize => {
10638                let lo = _mm_srli_si128::<0i32>(b);
10639                let hi = _mm_slli_si128::<16i32>(a);
10640                _mm_or_si128(lo, hi)
10641            }
10642            1usize => {
10643                let lo = _mm_srli_si128::<1i32>(b);
10644                let hi = _mm_slli_si128::<15i32>(a);
10645                _mm_or_si128(lo, hi)
10646            }
10647            2usize => {
10648                let lo = _mm_srli_si128::<2i32>(b);
10649                let hi = _mm_slli_si128::<14i32>(a);
10650                _mm_or_si128(lo, hi)
10651            }
10652            3usize => {
10653                let lo = _mm_srli_si128::<3i32>(b);
10654                let hi = _mm_slli_si128::<13i32>(a);
10655                _mm_or_si128(lo, hi)
10656            }
10657            4usize => {
10658                let lo = _mm_srli_si128::<4i32>(b);
10659                let hi = _mm_slli_si128::<12i32>(a);
10660                _mm_or_si128(lo, hi)
10661            }
10662            5usize => {
10663                let lo = _mm_srli_si128::<5i32>(b);
10664                let hi = _mm_slli_si128::<11i32>(a);
10665                _mm_or_si128(lo, hi)
10666            }
10667            6usize => {
10668                let lo = _mm_srli_si128::<6i32>(b);
10669                let hi = _mm_slli_si128::<10i32>(a);
10670                _mm_or_si128(lo, hi)
10671            }
10672            7usize => {
10673                let lo = _mm_srli_si128::<7i32>(b);
10674                let hi = _mm_slli_si128::<9i32>(a);
10675                _mm_or_si128(lo, hi)
10676            }
10677            8usize => {
10678                let lo = _mm_srli_si128::<8i32>(b);
10679                let hi = _mm_slli_si128::<8i32>(a);
10680                _mm_or_si128(lo, hi)
10681            }
10682            9usize => {
10683                let lo = _mm_srli_si128::<9i32>(b);
10684                let hi = _mm_slli_si128::<7i32>(a);
10685                _mm_or_si128(lo, hi)
10686            }
10687            10usize => {
10688                let lo = _mm_srli_si128::<10i32>(b);
10689                let hi = _mm_slli_si128::<6i32>(a);
10690                _mm_or_si128(lo, hi)
10691            }
10692            11usize => {
10693                let lo = _mm_srli_si128::<11i32>(b);
10694                let hi = _mm_slli_si128::<5i32>(a);
10695                _mm_or_si128(lo, hi)
10696            }
10697            12usize => {
10698                let lo = _mm_srli_si128::<12i32>(b);
10699                let hi = _mm_slli_si128::<4i32>(a);
10700                _mm_or_si128(lo, hi)
10701            }
10702            13usize => {
10703                let lo = _mm_srli_si128::<13i32>(b);
10704                let hi = _mm_slli_si128::<3i32>(a);
10705                _mm_or_si128(lo, hi)
10706            }
10707            14usize => {
10708                let lo = _mm_srli_si128::<14i32>(b);
10709                let hi = _mm_slli_si128::<2i32>(a);
10710                _mm_or_si128(lo, hi)
10711            }
10712            15usize => {
10713                let lo = _mm_srli_si128::<15i32>(b);
10714                let hi = _mm_slli_si128::<1i32>(a);
10715                _mm_or_si128(lo, hi)
10716            }
10717            _ => unreachable!(),
10718        }
10719    }
10720);
10721crate::kernel!(
10722    #[doc = r" Concatenates `b` and `a` (each N blocks) and extracts N blocks starting at byte offset `shift_bytes`."]
10723    #[doc = r" Extracts from [b : a] (b in low bytes, a in high bytes), matching `alignr` semantics."]
10724    #[inline(always)]
10725    fn cross_block_alignr_128x2(
10726        token: Sse2,
10727        a: [__m128i; 2usize],
10728        b: [__m128i; 2usize],
10729        shift_bytes: usize,
10730    ) -> [__m128i; 2usize] {
10731        [
10732            {
10733                let [lo, hi] =
10734                    crate::support::cross_block_slide_blocks_at(&b, &a, 0usize, shift_bytes);
10735                dyn_alignr_128(token, hi, lo, shift_bytes % 16)
10736            },
10737            {
10738                let [lo, hi] =
10739                    crate::support::cross_block_slide_blocks_at(&b, &a, 1usize, shift_bytes);
10740                dyn_alignr_128(token, hi, lo, shift_bytes % 16)
10741            },
10742        ]
10743    }
10744);
10745crate::kernel!(
10746    #[doc = r" Concatenates `b` and `a` (each N blocks) and extracts N blocks starting at byte offset `shift_bytes`."]
10747    #[doc = r" Extracts from [b : a] (b in low bytes, a in high bytes), matching `alignr` semantics."]
10748    #[inline(always)]
10749    fn cross_block_alignr_128x4(
10750        token: Sse2,
10751        a: [__m128i; 4usize],
10752        b: [__m128i; 4usize],
10753        shift_bytes: usize,
10754    ) -> [__m128i; 4usize] {
10755        [
10756            {
10757                let [lo, hi] =
10758                    crate::support::cross_block_slide_blocks_at(&b, &a, 0usize, shift_bytes);
10759                dyn_alignr_128(token, hi, lo, shift_bytes % 16)
10760            },
10761            {
10762                let [lo, hi] =
10763                    crate::support::cross_block_slide_blocks_at(&b, &a, 1usize, shift_bytes);
10764                dyn_alignr_128(token, hi, lo, shift_bytes % 16)
10765            },
10766            {
10767                let [lo, hi] =
10768                    crate::support::cross_block_slide_blocks_at(&b, &a, 2usize, shift_bytes);
10769                dyn_alignr_128(token, hi, lo, shift_bytes % 16)
10770            },
10771            {
10772                let [lo, hi] =
10773                    crate::support::cross_block_slide_blocks_at(&b, &a, 3usize, shift_bytes);
10774                dyn_alignr_128(token, hi, lo, shift_bytes % 16)
10775            },
10776        ]
10777    }
10778);