Skip to main content

fearless_simd/generated/
simd_trait.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
6use crate::{
7    Bytes, ExtractToken, Level, MaskNarrow, MaskWiden, Select, SimdCvtFloat, SimdCvtTruncate,
8    SimdElement, SimdFloatElement, SimdFrom, SimdIntElement, SimdIntWiden, SimdInto, SimdNarrow,
9    SimdWiden, seal::Seal,
10};
11use crate::{
12    f32x4, f32x8, f32x16, f64x2, f64x4, f64x8, i8x16, i8x32, i8x64, i16x8, i16x16, i16x32, i32x4,
13    i32x8, i32x16, i64x2, i64x4, i64x8, mask8x16, mask8x32, mask8x64, mask16x8, mask16x16,
14    mask16x32, mask32x4, mask32x8, mask32x16, mask64x2, mask64x4, mask64x8, u8x16, u8x32, u8x64,
15    u16x8, u16x16, u16x32, u32x4, u32x8, u32x16, u64x2, u64x4, u64x8,
16};
17use core::fmt::Debug;
18#[doc = r" The main SIMD trait, implemented by all SIMD token types."]
19#[doc = r""]
20#[doc = r#" Each implementor of this trait (e.g. `Avx2`, `Sse4_2`, `Sse2`, `Neon`, `Fallback`) is a zero-sized "token" type"#]
21#[doc = r" representing a specific SIMD instruction set. These tokens are obtained at runtime via [`Level`] and the"]
22#[doc = r" [`dispatch!`](crate::dispatch) macro, which selects the best available backend for the current CPU."]
23#[doc = r""]
24#[doc = r" This trait defines all the low-level SIMD operations (e.g. [`add_f32x4`](Simd::add_f32x4),"]
25#[doc = r" [`mul_u32x4`](Simd::mul_u32x4)) that are implemented by each token type using platform-specific intrinsics."]
26#[doc = r" However, you typically won't call these methods directly. Instead, you'll probably be using the methods"]
27#[doc = r" defined on the vector types themselves, such as [`f32x4`] or [`u32x4`]."]
28#[doc = r""]
29#[doc = r" # Associated Types"]
30#[doc = r""]
31#[doc = r#" The trait defines associated types for the highest "native" vector width of each scalar type (e.g. `f32s`,"#]
32#[doc = r" `u32s`). These are always at least 128 bits, but may be larger. Currently, they are 128 bits on the"]
33#[doc = r" fallback, NEON, WASM, SSE2, and SSE4.2 backends, 256 bits on AVX2, and 512 bits on AVX-512."]
34#[doc = r""]
35#[doc = r" # Example"]
36#[doc = r""]
37#[doc = r" ```"]
38#[doc = r" # use fearless_simd::{prelude::*, f32x4, dispatch, Level};"]
39#[doc = r""]
40#[doc = r" #[inline(always)]"]
41#[doc = r" fn add_vectors<S: Simd>(simd: S, a: f32x4<S>, b: f32x4<S>) -> f32x4<S> {"]
42#[doc = r"     a + b  // Uses operator overloading, which calls simd.add_f32x4 internally"]
43#[doc = r" }"]
44#[doc = r""]
45#[doc = r" let level = Level::new();"]
46#[doc = r" dispatch!(level, simd => {"]
47#[doc = r"     let a = [1.0, 2.0, 3.0, 4.0].simd_into(simd);"]
48#[doc = r"     let b = [5.0, 6.0, 7.0, 8.0].simd_into(simd);"]
49#[doc = r"     let result = add_vectors(simd, a, b);"]
50#[doc = r"     # assert_eq!(*result, [6.0, 8.0, 10.0, 12.0]);"]
51#[doc = r" });"]
52#[doc = r" ```"]
53pub trait Simd:
54    ExtractToken<S = Self>
55    + Sized
56    + Clone
57    + Copy
58    + Send
59    + Sync
60    + Debug
61    + Seal
62    + arch_types::ArchTypes
63    + 'static
64{
65    #[doc = r" A native-width SIMD vector of [`f32`]s."]
66    type f32s: SimdFloat<
67            Self,
68            Element = f32,
69            Block = f32x4<Self>,
70            Mask = Self::mask32s,
71            ByteVector = Self::u8s,
72        > + SimdCvtFloat<Self::u32s>
73        + SimdCvtFloat<Self::i32s>
74        + SimdWiden<Self, Widened = Self::f64s>;
75    #[doc = r" A native-width SIMD vector of [`f64`]s."]
76    type f64s: SimdFloat<
77            Self,
78            Element = f64,
79            Block = f64x2<Self>,
80            Mask = Self::mask64s,
81            ByteVector = Self::u8s,
82        > + SimdCvtFloat<Self::u64s>
83        + SimdCvtFloat<Self::i64s>
84        + SimdNarrow<Self, Narrowed = Self::f32s>;
85    #[doc = r" A native-width SIMD vector of [`u8`]s."]
86    type u8s: SimdInt<
87            Self,
88            Element = u8,
89            Block = u8x16<Self>,
90            Mask = Self::mask8s,
91            ByteVector = Self::u8s,
92        > + SimdIntWiden<Self, Widened = Self::u16s>;
93    #[doc = r" A native-width SIMD vector of [`i8`]s."]
94    type i8s: SimdInt<
95            Self,
96            Element = i8,
97            Block = i8x16<Self>,
98            Mask = Self::mask8s,
99            ByteVector = Self::u8s,
100        > + SimdIntWiden<Self, Widened = Self::i16s>
101        + core::ops::Neg<Output = Self::i8s>;
102    #[doc = r" A native-width SIMD vector of [`u16`]s."]
103    type u16s: SimdInt<
104            Self,
105            Element = u16,
106            Block = u16x8<Self>,
107            Mask = Self::mask16s,
108            ByteVector = Self::u8s,
109        > + SimdNarrow<Self, Narrowed = Self::u8s>
110        + SimdIntWiden<Self, Widened = Self::u32s>;
111    #[doc = r" A native-width SIMD vector of [`i16`]s."]
112    type i16s: SimdInt<
113            Self,
114            Element = i16,
115            Block = i16x8<Self>,
116            Mask = Self::mask16s,
117            ByteVector = Self::u8s,
118        > + SimdNarrow<Self, Narrowed = Self::i8s>
119        + SimdIntWiden<Self, Widened = Self::i32s>
120        + core::ops::Neg<Output = Self::i16s>;
121    #[doc = r" A native-width SIMD vector of [`u32`]s."]
122    type u32s: SimdInt<
123            Self,
124            Element = u32,
125            Block = u32x4<Self>,
126            Mask = Self::mask32s,
127            ByteVector = Self::u8s,
128        > + SimdCvtTruncate<Self::f32s>
129        + SimdNarrow<Self, Narrowed = Self::u16s>
130        + SimdIntWiden<Self, Widened = Self::u64s>;
131    #[doc = r" A native-width SIMD vector of [`i32`]s."]
132    type i32s: SimdInt<
133            Self,
134            Element = i32,
135            Block = i32x4<Self>,
136            Mask = Self::mask32s,
137            ByteVector = Self::u8s,
138        > + SimdCvtTruncate<Self::f32s>
139        + SimdNarrow<Self, Narrowed = Self::i16s>
140        + SimdIntWiden<Self, Widened = Self::i64s>
141        + core::ops::Neg<Output = Self::i32s>;
142    #[doc = r" A native-width SIMD vector of [`u64`]s."]
143    type u64s: SimdInt<
144            Self,
145            Element = u64,
146            Block = u64x2<Self>,
147            Mask = Self::mask64s,
148            ByteVector = Self::u8s,
149        > + SimdCvtTruncate<Self::f64s>
150        + SimdNarrow<Self, Narrowed = Self::u32s>;
151    #[doc = r" A native-width SIMD vector of [`i64`]s."]
152    type i64s: SimdInt<
153            Self,
154            Element = i64,
155            Block = i64x2<Self>,
156            Mask = Self::mask64s,
157            ByteVector = Self::u8s,
158        > + SimdCvtTruncate<Self::f64s>
159        + SimdNarrow<Self, Narrowed = Self::i32s>
160        + core::ops::Neg<Output = Self::i64s>;
161    #[doc = r" A native-width SIMD mask with 8-bit lanes."]
162    type mask8s: SimdMask<Self, Element = i8, Ints = Self::i8s>
163        + Select<Self::u8s>
164        + Select<Self::i8s>
165        + Select<Self::mask8s>
166        + MaskWiden<Self, Widened = Self::mask16s>;
167    #[doc = r" A native-width SIMD mask with 16-bit lanes."]
168    type mask16s: SimdMask<Self, Element = i16, Ints = Self::i16s>
169        + Select<Self::u16s>
170        + Select<Self::i16s>
171        + Select<Self::mask16s>
172        + MaskNarrow<Self, Narrowed = Self::mask8s>
173        + MaskWiden<Self, Widened = Self::mask32s>;
174    #[doc = r" A native-width SIMD mask with 32-bit lanes."]
175    type mask32s: SimdMask<Self, Element = i32, Ints = Self::i32s>
176        + Select<Self::f32s>
177        + Select<Self::u32s>
178        + Select<Self::i32s>
179        + Select<Self::mask32s>
180        + MaskNarrow<Self, Narrowed = Self::mask16s>
181        + MaskWiden<Self, Widened = Self::mask64s>;
182    #[doc = r" A native-width SIMD mask with 64-bit lanes."]
183    type mask64s: SimdMask<Self, Element = i64, Ints = Self::i64s>
184        + Select<Self::f64s>
185        + Select<Self::u64s>
186        + Select<Self::i64s>
187        + Select<Self::mask64s>
188        + MaskNarrow<Self, Narrowed = Self::mask32s>;
189    #[doc = r" This SIMD token's feature level."]
190    fn level(self) -> Level;
191    #[doc = r" Call a closure with the instructions for this SIMD level enabled."]
192    #[doc = r""]
193    #[doc = r" `vectorize()` establishes the correct `#[target_feature]` context. The provided"]
194    #[doc = r" closure should be `#[inline(always)]` so that its body is incorporated into that"]
195    #[doc = r" context and can use all instructions supported by this SIMD level."]
196    #[doc = r""]
197    #[doc = r" The small wrappers used by `vectorize()` are eligible for inlining when the caller"]
198    #[doc = r" has a compatible target-feature context. A function containing the call does not"]
199    #[doc = r" itself need an `#[inline(always)]` annotation; a target-feature boundary is retained"]
200    #[doc = r" whenever one is required."]
201    #[doc = r""]
202    #[doc = r" The [`#[simd]`](https://docs.rs/fearless_simd_macros/latest/fearless_simd_macros/attr.simd.html)"]
203    #[doc = r" attribute from the separate `fearless_simd_macros` crate establishes this context"]
204    #[doc = r" automatically, passing ordinary function arguments separately to reduce capture"]
205    #[doc = r" overhead. Calling `vectorize()` manually avoids the procedural-macro dependency."]
206    #[doc = r""]
207    #[doc = r" # Example"]
208    #[doc = r""]
209    #[doc = r" `double_u32s` does not need to be marked `#[inline(always)]`; only the closure passed"]
210    #[doc = r" to `vectorize()` does."]
211    #[doc = r""]
212    #[doc = r" ```"]
213    #[doc = r" use fearless_simd::{dispatch, prelude::*, Level};"]
214    #[doc = r""]
215    #[doc = r" fn double_u32s<S: Simd>(simd: S, values: &mut [u32]) {"]
216    #[doc = r"     simd.vectorize("]
217    #[doc = r"         #[inline(always)]"]
218    #[doc = r"         || {"]
219    #[doc = r"             let mut chunks = values.chunks_exact_mut(S::u32s::LEN);"]
220    #[doc = r"             for chunk in &mut chunks {"]
221    #[doc = r"                 let value = S::u32s::from_slice(simd, chunk);"]
222    #[doc = r"                 (value * 2).store_slice(chunk);"]
223    #[doc = r"             }"]
224    #[doc = r"             for value in chunks.into_remainder() {"]
225    #[doc = r"                 *value *= 2;"]
226    #[doc = r"             }"]
227    #[doc = r"         },"]
228    #[doc = r"     );"]
229    #[doc = r" }"]
230    #[doc = r""]
231    #[doc = r" let mut values = [1, 2, 3, 4, 5];"]
232    #[doc = r" let level = Level::new();"]
233    #[doc = r" dispatch!(level, simd => double_u32s(simd, &mut values));"]
234    #[doc = r" assert_eq!(values, [2, 4, 6, 8, 10]);"]
235    #[doc = r" ```"]
236    fn vectorize<F: FnOnce() -> R, R>(self, f: F) -> R;
237    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
238    fn abs_f32x4(self, a: f32x4<Self>) -> f32x4<Self>;
239    #[doc = "Create a SIMD vector with all elements set to the given value."]
240    fn splat_f32x4(self, val: f32) -> f32x4<Self>;
241    #[doc = "Reverse the order of the vector's elements."]
242    fn reverse_f32x4(self, a: f32x4<Self>) -> f32x4<Self>;
243    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
244    fn slide_f32x4<const SHIFT: usize>(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self>;
245    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
246    #[inline(always)]
247    fn slide_within_blocks_f32x4<const SHIFT: usize>(
248        self,
249        a: f32x4<Self>,
250        b: f32x4<Self>,
251    ) -> f32x4<Self> {
252        self.slide_f32x4::<SHIFT>(a, b)
253    }
254    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
255    #[inline(always)]
256    fn swizzle_dyn_within_blocks_f32x4(self, a: f32x4<Self>, indices: u8x16<Self>) -> f32x4<Self> {
257        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x16(Bytes::to_bytes(a), indices))
258    }
259    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
260    #[inline(always)]
261    fn swizzle_dyn_f32x4(self, a: f32x4<Self>, indices: u8x16<Self>) -> f32x4<Self> {
262        Bytes::from_bytes(self.swizzle_dyn_u8x16(Bytes::to_bytes(a), indices))
263    }
264    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
265    #[inline(always)]
266    fn swizzle_dyn_precise_f32x4(self, a: f32x4<Self>, indices: u8x16<Self>) -> f32x4<Self> {
267        Bytes::from_bytes(self.swizzle_dyn_precise_u8x16(Bytes::to_bytes(a), indices))
268    }
269    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
270    #[inline(always)]
271    fn concat_swizzle_dyn_f32x4(
272        self,
273        a: f32x4<Self>,
274        b: f32x4<Self>,
275        indices: u8x16<Self>,
276    ) -> f32x4<Self> {
277        Bytes::from_bytes(self.concat_swizzle_dyn_u8x16(
278            Bytes::to_bytes(a),
279            Bytes::to_bytes(b),
280            indices,
281        ))
282    }
283    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
284    #[inline(always)]
285    fn concat_swizzle_dyn_precise_f32x4(
286        self,
287        a: f32x4<Self>,
288        b: f32x4<Self>,
289        indices: u8x16<Self>,
290    ) -> f32x4<Self> {
291        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x16(
292            Bytes::to_bytes(a),
293            Bytes::to_bytes(b),
294            indices,
295        ))
296    }
297    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
298    fn compress_f32x4(self, values: f32x4<Self>, mask: mask32x4<Self>) -> f32x4<Self>;
299    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
300    fn compress_merge_f32x4(
301        self,
302        values: f32x4<Self>,
303        mask: mask32x4<Self>,
304        merge: f32x4<Self>,
305    ) -> f32x4<Self>;
306    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
307    fn expand_f32x4(self, values: f32x4<Self>, mask: mask32x4<Self>) -> f32x4<Self>;
308    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
309    fn expand_merge_f32x4(
310        self,
311        values: f32x4<Self>,
312        mask: mask32x4<Self>,
313        merge: f32x4<Self>,
314    ) -> f32x4<Self>;
315    #[doc = "Negate each element of the vector."]
316    fn neg_f32x4(self, a: f32x4<Self>) -> f32x4<Self>;
317    #[doc = "Compute the square root of each element.\n\nNegative elements other than `-0.0` will become NaN."]
318    fn sqrt_f32x4(self, a: f32x4<Self>) -> f32x4<Self>;
319    #[doc = "Compute an approximate reciprocal (`1. / x`) for each element.\n\nThis uses a fast hardware estimate where available, and falls back to exact division otherwise.\n\nOn x86 for `f32`, this has a relative error less than `1.5 × 2^-12`. On `AArch64` (`f32` and `f64`), this has a relative error less than `2^-8`. The precision of this operation may change as new platform support is added."]
320    fn approximate_recip_f32x4(self, a: f32x4<Self>) -> f32x4<Self>;
321    #[doc = "Add two vectors element-wise."]
322    fn add_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self>;
323    #[doc = "Subtract two vectors element-wise."]
324    fn sub_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self>;
325    #[doc = "Multiply two vectors element-wise."]
326    fn mul_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self>;
327    #[doc = "Divide two vectors element-wise."]
328    fn div_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self>;
329    #[doc = "Return a vector with the magnitude of `a` and the sign of `b` for each element.\n\nThis operation copies the sign bit, so if an input element is NaN, the output element will be a NaN with the same payload and a copied sign bit."]
330    fn copysign_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self>;
331    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
332    fn reduce_max_f32x4(self, a: f32x4<Self>) -> f32;
333    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
334    fn reduce_min_f32x4(self, a: f32x4<Self>) -> f32;
335    #[doc = "Return the maximum element in the vector, ignoring quiet NaNs.\n\nFor integer vectors, this operation is the same as `reduce_max`.\n\nFor floating-point vectors, quiet NaNs are ignored. If there is at least one numeric lane, this returns the true maximum of the numeric lanes. If all lanes are quiet NaNs, this returns NaN, with an unspecified payload and sign.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned.\n\nIf any lane is a *signaling* NaN, the result is fully non-deterministic: it may be NaN or a numeric lane and is not guaranteed to be the true maximum.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
336    fn reduce_max_precise_f32x4(self, a: f32x4<Self>) -> f32;
337    #[doc = "Return the minimum element in the vector, ignoring quiet NaNs.\n\nFor integer vectors, this operation is the same as `reduce_min`.\n\nFor floating-point vectors, quiet NaNs are ignored. If there is at least one numeric lane, this returns the true minimum of the numeric lanes. If all lanes are quiet NaNs, this returns NaN, with an unspecified payload and sign.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned.\n\nIf any lane is a *signaling* NaN, the result is fully non-deterministic: it may be NaN or a numeric lane and is not guaranteed to be the true minimum.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
338    fn reduce_min_precise_f32x4(self, a: f32x4<Self>) -> f32;
339    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
340    fn reduce_sum_f32x4(self, a: f32x4<Self>) -> f32;
341    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
342    fn reduce_product_f32x4(self, a: f32x4<Self>) -> f32;
343    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
344    fn max_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self>;
345    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
346    fn min_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self>;
347    #[doc = "Return the element-wise maximum of two vectors.\n\nFor integer vectors, this operation is the same as `max`.\n\nFor floating-point vectors, if one operand is a quiet NaN and the other is not, this operation will choose the non-NaN operand.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\nIf a floating-point operand is a *signaling* NaN, the result is not just implementation-defined, but fully non-deterministic: it may be either NaN or the non-NaN operand.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
348    fn max_precise_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self>;
349    #[doc = "Return the element-wise minimum of two vectors.\n\nFor integer vectors, this operation is the same as `min`.\n\nFor floating-point vectors, if one operand is a quiet NaN and the other is not, this operation will choose the non-NaN operand.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\nIf a floating-point operand is a *signaling* NaN, the result is not just implementation-defined, but fully non-deterministic: it may be either NaN or the non-NaN operand.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
350    fn min_precise_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self>;
351    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
352    fn clamp_f32x4(self, a: f32x4<Self>, b: f32x4<Self>, c: f32x4<Self>) -> f32x4<Self>;
353    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
354    fn simd_eq_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> mask32x4<Self>;
355    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
356    #[inline(always)]
357    fn simd_ne_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> mask32x4<Self> {
358        self.not_mask32x4(self.simd_eq_f32x4(a, b))
359    }
360    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
361    fn simd_lt_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> mask32x4<Self>;
362    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
363    fn simd_le_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> mask32x4<Self>;
364    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
365    #[inline(always)]
366    fn simd_ge_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> mask32x4<Self> {
367        self.simd_le_f32x4(b, a)
368    }
369    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
370    #[inline(always)]
371    fn simd_gt_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> mask32x4<Self> {
372        self.simd_lt_f32x4(b, a)
373    }
374    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
375    fn zip_low_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self>;
376    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
377    fn zip_high_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self>;
378    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
379    fn unzip_low_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self>;
380    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
381    fn unzip_high_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x4<Self>;
382    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
383    fn interleave_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> (f32x4<Self>, f32x4<Self>);
384    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
385    fn deinterleave_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> (f32x4<Self>, f32x4<Self>);
386    #[doc = "Compute `(a * b) + c` (fused multiply-add) for each element.\n\nDepending on platform support, the result may be computed with only one rounding error, or may be implemented as a regular multiply followed by an add, which will result in two rounding errors."]
387    fn mul_add_f32x4(self, a: f32x4<Self>, b: f32x4<Self>, c: f32x4<Self>) -> f32x4<Self>;
388    #[doc = "Compute `(a * b) + c` for each element, with a single rounding at the end.\n\nThe result is the infinite-precision product-plus-add rounded once to the element type. This may be substantially slower than `mul_add` on platforms without fused multiply-add instructions, including WebAssembly.\n\n# Precision guarantees\n\nThis function is **not** susceptible to [the bug](https://github.com/rust-lang/compiler-builtins/issues/1262) in Rust standard library and in musl libc that causes incorrect rounding for near-zero values on CPUs without hardware support for this operation.\n\nOn the tier-2 i586-* targets, this function is correct if and only if SSE2 is available on the CPU.\n\nThe exact `NaN` payloads as well as signaling `NaN`s are not preserved."]
389    fn mul_add_precise_f32x4(self, a: f32x4<Self>, b: f32x4<Self>, c: f32x4<Self>) -> f32x4<Self>;
390    #[doc = "Compute `(a * b) - c` (fused multiply-subtract) for each element.\n\nDepending on platform support, the result may be computed with only one rounding error, or may be implemented as a regular multiply followed by a subtract, which will result in two rounding errors."]
391    fn mul_sub_f32x4(self, a: f32x4<Self>, b: f32x4<Self>, c: f32x4<Self>) -> f32x4<Self>;
392    #[doc = "Compute `(a * b) - c` for each element, with a single rounding at the end.\n\nThe result is the infinite-precision product-minus-subtrahend rounded once to the element type. This may be substantially slower than `mul_sub` on platforms without fused multiply-add instructions, including WebAssembly.\n        # Precision guarantees\n\nThis function is **not** susceptible to [the bug](https://github.com/rust-lang/compiler-builtins/issues/1262) in Rust standard library and in musl libc that causes incorrect rounding for near-zero values on CPUs without hardware support for this operation.\n\nOn the tier-2 i586-* targets, this function is correct if and only if SSE2 is available on the CPU.\n\nThe exact `NaN` payloads as well as signaling `NaN`s are not preserved."]
393    fn mul_sub_precise_f32x4(self, a: f32x4<Self>, b: f32x4<Self>, c: f32x4<Self>) -> f32x4<Self>;
394    #[doc = "Return the largest integer less than or equal to each element, that is, round towards negative infinity."]
395    fn floor_f32x4(self, a: f32x4<Self>) -> f32x4<Self>;
396    #[doc = "Return the smallest integer greater than or equal to each element, that is, round towards positive infinity."]
397    fn ceil_f32x4(self, a: f32x4<Self>) -> f32x4<Self>;
398    #[doc = "Round each element to the nearest integer, with ties rounding to the nearest even integer."]
399    fn round_ties_even_f32x4(self, a: f32x4<Self>) -> f32x4<Self>;
400    #[doc = "Round each element to the nearest integer, with ties rounding away from zero.\n\n## Performance considerations\n\nOnly `AArch64` has native instructions for this operation. `round` has to be emulated on all other platforms which is around 2-4x slower than `round_ties_even`. Prefer using [`round_ties_even`](SimdFloat::round_ties_even) if possible."]
401    fn round_f32x4(self, a: f32x4<Self>) -> f32x4<Self>;
402    #[doc = "Return the fractional part of each element.\n\nThis is equivalent to `a - a.trunc()`."]
403    fn fract_f32x4(self, a: f32x4<Self>) -> f32x4<Self>;
404    #[doc = "Return the integer part of each element, rounding towards zero."]
405    fn trunc_f32x4(self, a: f32x4<Self>) -> f32x4<Self>;
406    #[doc = "Converts radians to degrees.\n\nThe precision of this function is non-deterministic. This means it varies by platform, Rust version, and can even differ within the same execution from one invocation to the next."]
407    fn to_degrees_f32x4(self, a: f32x4<Self>) -> f32x4<Self>;
408    #[doc = "Converts degrees to radians.\n\nThe precision of this function is non-deterministic. This means it varies by platform, Rust version, and can even differ within the same execution from one invocation to the next."]
409    fn to_radians_f32x4(self, a: f32x4<Self>) -> f32x4<Self>;
410    #[doc = "Return a mask indicating which elements are NaN."]
411    fn is_nan_f32x4(self, a: f32x4<Self>) -> mask32x4<Self>;
412    #[doc = "Return a mask indicating which elements are positive or negative infinite."]
413    fn is_infinite_f32x4(self, a: f32x4<Self>) -> mask32x4<Self>;
414    #[doc = "Return a mask indicating which elements are neither infinite nor NaN."]
415    fn is_finite_f32x4(self, a: f32x4<Self>) -> mask32x4<Self>;
416    #[doc = "Return a mask indicating which elements are subnormal.\n\nThis classifies the stored bit pattern, even when floating-point operations treat subnormals as zero."]
417    fn is_subnormal_f32x4(self, a: f32x4<Self>) -> mask32x4<Self>;
418    #[doc = "Return a mask indicating which elements are neither zero, infinite, subnormal, or NaN."]
419    fn is_normal_f32x4(self, a: f32x4<Self>) -> mask32x4<Self>;
420    #[doc = "Return a mask indicating which elements have a positive sign, including `+0.0`, NaNs with positive sign bit and positive infinity.\n\nNaN inputs may produce an unexpected or non-portable result, see [`f32::is_sign_positive`] for details."]
421    fn is_sign_positive_f32x4(self, a: f32x4<Self>) -> mask32x4<Self>;
422    #[doc = "Return a mask indicating which elements have a negative sign, including `-0.0`, NaNs with negative sign bit and negative infinity.\n\nNaN inputs may produce an unexpected or non-portable result, see [`f32::is_sign_negative`] for details."]
423    fn is_sign_negative_f32x4(self, a: f32x4<Self>) -> mask32x4<Self>;
424    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
425    fn select_f32x4(self, a: mask32x4<Self>, b: f32x4<Self>, c: f32x4<Self>) -> f32x4<Self>;
426    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
427    fn combine_f32x4(self, a: f32x4<Self>, b: f32x4<Self>) -> f32x8<Self>;
428    #[doc = "Load four 128-bit vectors from an array with 4-way interleaving.\n\nThis is useful e.g. in image processing to turn interleaved RGBA pixels into vectors of each color component.\n\nFor example, with 32-bit lanes, memory laid out as`[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]` loads as`[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]`."]
429    #[doc(alias = "load_interleaved")]
430    fn load_four_interleaved_f32x4(self, src: &[f32; 16usize]) -> [f32x4<Self>; 4usize];
431    #[doc = "Store four 128-bit vectors to an array with 4-way interleaving.\n\nThis is the inverse of `load_four_interleaved`.\n\nThis is useful e.g. in image processing to turn vectors of each color component into interleaved RGBA pixels.\n\nFor example, with 32-bit lanes, vectors containing `[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]` get stored as `[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]`."]
432    #[doc(alias = "store_interleaved")]
433    fn store_four_interleaved_f32x4(
434        self,
435        vectors: [f32x4<Self>; 4usize],
436        dest: &mut [f32; 16usize],
437    ) -> ();
438    #[doc = "Widen every `f32` lane exactly into two same-width `f64` vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
439    fn widen_f32x4(self, a: f32x4<Self>) -> (f64x2<Self>, f64x2<Self>);
440    #[doc = "Convert each floating-point element to an unsigned 32-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results.\n\nOn x86 platforms below AVX-512, this operation will still be slower than converting to `i32`, because there is no native instruction for converting to `u32`.\nIf you know your values fit within range of an `i32`, you should convert to an `i32` and cast to your desired datatype afterwards."]
441    fn cvt_u32_f32x4(self, a: f32x4<Self>) -> u32x4<Self>;
442    #[doc = "Convert each floating-point element to an unsigned 32-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
443    fn cvt_u32_precise_f32x4(self, a: f32x4<Self>) -> u32x4<Self>;
444    #[doc = "Convert each floating-point element to a signed 32-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
445    fn cvt_i32_f32x4(self, a: f32x4<Self>) -> i32x4<Self>;
446    #[doc = "Convert each floating-point element to a signed 32-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
447    fn cvt_i32_precise_f32x4(self, a: f32x4<Self>) -> i32x4<Self>;
448    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
449    fn abs_i8x16(self, a: i8x16<Self>) -> i8x16<Self>;
450    #[doc = "Create a SIMD vector with all elements set to the given value."]
451    fn splat_i8x16(self, val: i8) -> i8x16<Self>;
452    #[doc = "Reverse the order of the vector's elements."]
453    fn reverse_i8x16(self, a: i8x16<Self>) -> i8x16<Self>;
454    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
455    fn slide_i8x16<const SHIFT: usize>(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
456    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
457    #[inline(always)]
458    fn slide_within_blocks_i8x16<const SHIFT: usize>(
459        self,
460        a: i8x16<Self>,
461        b: i8x16<Self>,
462    ) -> i8x16<Self> {
463        self.slide_i8x16::<SHIFT>(a, b)
464    }
465    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
466    #[inline(always)]
467    fn swizzle_dyn_within_blocks_i8x16(self, a: i8x16<Self>, indices: u8x16<Self>) -> i8x16<Self> {
468        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x16(Bytes::to_bytes(a), indices))
469    }
470    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
471    #[inline(always)]
472    fn swizzle_dyn_i8x16(self, a: i8x16<Self>, indices: u8x16<Self>) -> i8x16<Self> {
473        Bytes::from_bytes(self.swizzle_dyn_u8x16(Bytes::to_bytes(a), indices))
474    }
475    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
476    #[inline(always)]
477    fn swizzle_dyn_precise_i8x16(self, a: i8x16<Self>, indices: u8x16<Self>) -> i8x16<Self> {
478        Bytes::from_bytes(self.swizzle_dyn_precise_u8x16(Bytes::to_bytes(a), indices))
479    }
480    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
481    #[inline(always)]
482    fn concat_swizzle_dyn_i8x16(
483        self,
484        a: i8x16<Self>,
485        b: i8x16<Self>,
486        indices: u8x16<Self>,
487    ) -> i8x16<Self> {
488        Bytes::from_bytes(self.concat_swizzle_dyn_u8x16(
489            Bytes::to_bytes(a),
490            Bytes::to_bytes(b),
491            indices,
492        ))
493    }
494    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
495    #[inline(always)]
496    fn concat_swizzle_dyn_precise_i8x16(
497        self,
498        a: i8x16<Self>,
499        b: i8x16<Self>,
500        indices: u8x16<Self>,
501    ) -> i8x16<Self> {
502        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x16(
503            Bytes::to_bytes(a),
504            Bytes::to_bytes(b),
505            indices,
506        ))
507    }
508    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
509    fn compress_i8x16(self, values: i8x16<Self>, mask: mask8x16<Self>) -> i8x16<Self>;
510    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
511    fn compress_merge_i8x16(
512        self,
513        values: i8x16<Self>,
514        mask: mask8x16<Self>,
515        merge: i8x16<Self>,
516    ) -> i8x16<Self>;
517    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
518    fn expand_i8x16(self, values: i8x16<Self>, mask: mask8x16<Self>) -> i8x16<Self>;
519    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
520    fn expand_merge_i8x16(
521        self,
522        values: i8x16<Self>,
523        mask: mask8x16<Self>,
524        merge: i8x16<Self>,
525    ) -> i8x16<Self>;
526    #[doc = "Return the number of ones in the binary representation of each element."]
527    fn count_ones_i8x16(self, a: i8x16<Self>) -> i8x16<Self>;
528    #[doc = "Return the number of zeros in the binary representation of each element."]
529    fn count_zeros_i8x16(self, a: i8x16<Self>) -> i8x16<Self>;
530    #[doc = "Add two vectors element-wise, wrapping on overflow."]
531    fn add_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
532    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
533    fn saturating_add_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
534    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
535    fn sub_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
536    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
537    fn saturating_sub_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
538    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
539    fn mul_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
540    #[doc = "Compute the bitwise AND of two vectors."]
541    fn and_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
542    #[doc = "Compute the bitwise OR of two vectors."]
543    fn or_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
544    #[doc = "Compute the bitwise XOR of two vectors."]
545    fn xor_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
546    #[doc = "Compute the bitwise NOT of the vector."]
547    fn not_i8x16(self, a: i8x16<Self>) -> i8x16<Self>;
548    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
549    fn shl_i8x16(self, a: i8x16<Self>, shift: u32) -> i8x16<Self>;
550    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
551    fn shlv_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
552    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
553    fn shr_i8x16(self, a: i8x16<Self>, shift: u32) -> i8x16<Self>;
554    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
555    fn shrv_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
556    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
557    fn reduce_max_i8x16(self, a: i8x16<Self>) -> i8;
558    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
559    fn reduce_min_i8x16(self, a: i8x16<Self>) -> i8;
560    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
561    fn reduce_sum_i8x16(self, a: i8x16<Self>) -> i8;
562    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
563    fn reduce_product_i8x16(self, a: i8x16<Self>) -> i8;
564    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
565    fn max_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
566    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
567    fn min_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
568    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
569    fn clamp_i8x16(self, a: i8x16<Self>, b: i8x16<Self>, c: i8x16<Self>) -> i8x16<Self>;
570    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
571    fn simd_eq_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> mask8x16<Self>;
572    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
573    #[inline(always)]
574    fn simd_ne_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> mask8x16<Self> {
575        self.not_mask8x16(self.simd_eq_i8x16(a, b))
576    }
577    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
578    fn simd_lt_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> mask8x16<Self>;
579    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
580    fn simd_le_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> mask8x16<Self>;
581    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
582    #[inline(always)]
583    fn simd_ge_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> mask8x16<Self> {
584        self.simd_le_i8x16(b, a)
585    }
586    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
587    #[inline(always)]
588    fn simd_gt_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> mask8x16<Self> {
589        self.simd_lt_i8x16(b, a)
590    }
591    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
592    fn zip_low_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
593    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
594    fn zip_high_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
595    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
596    fn unzip_low_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
597    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
598    fn unzip_high_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x16<Self>;
599    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
600    fn interleave_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> (i8x16<Self>, i8x16<Self>);
601    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
602    fn deinterleave_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> (i8x16<Self>, i8x16<Self>);
603    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
604    fn select_i8x16(self, a: mask8x16<Self>, b: i8x16<Self>, c: i8x16<Self>) -> i8x16<Self>;
605    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
606    fn combine_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i8x32<Self>;
607    #[doc = "Negate each element of the vector, wrapping on overflow."]
608    fn neg_i8x16(self, a: i8x16<Self>) -> i8x16<Self>;
609    #[doc = "Load four 128-bit vectors from an array with 4-way interleaving.\n\nThis is useful e.g. in image processing to turn interleaved RGBA pixels into vectors of each color component.\n\nFor example, with 32-bit lanes, memory laid out as`[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]` loads as`[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]`."]
610    #[doc(alias = "load_interleaved")]
611    fn load_four_interleaved_i8x16(self, src: &[i8; 64usize]) -> [i8x16<Self>; 4usize];
612    #[doc = "Store four 128-bit vectors to an array with 4-way interleaving.\n\nThis is the inverse of `load_four_interleaved`.\n\nThis is useful e.g. in image processing to turn vectors of each color component into interleaved RGBA pixels.\n\nFor example, with 32-bit lanes, vectors containing `[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]` get stored as `[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]`."]
613    #[doc(alias = "store_interleaved")]
614    fn store_four_interleaved_i8x16(
615        self,
616        vectors: [i8x16<Self>; 4usize],
617        dest: &mut [i8; 64usize],
618    ) -> ();
619    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
620    fn widen_i8x16(self, a: i8x16<Self>) -> (i16x8<Self>, i16x8<Self>);
621    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
622    fn widening_mul_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> (i16x8<Self>, i16x8<Self>);
623    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
624    fn widening_add_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> (i16x8<Self>, i16x8<Self>);
625    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
626    fn pairwise_widening_add_i8x16(self, a: i8x16<Self>) -> i16x8<Self>;
627    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
628    fn pairwise_dot_product_i8x16(self, a: i8x16<Self>, b: i8x16<Self>) -> i16x8<Self>;
629    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
630    #[inline(always)]
631    fn abs_u8x16(self, a: u8x16<Self>) -> u8x16<Self> {
632        a
633    }
634    #[doc = "Create a SIMD vector with all elements set to the given value."]
635    fn splat_u8x16(self, val: u8) -> u8x16<Self>;
636    #[doc = "Reverse the order of the vector's elements."]
637    fn reverse_u8x16(self, a: u8x16<Self>) -> u8x16<Self>;
638    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
639    fn slide_u8x16<const SHIFT: usize>(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
640    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
641    #[inline(always)]
642    fn slide_within_blocks_u8x16<const SHIFT: usize>(
643        self,
644        a: u8x16<Self>,
645        b: u8x16<Self>,
646    ) -> u8x16<Self> {
647        self.slide_u8x16::<SHIFT>(a, b)
648    }
649    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
650    fn swizzle_dyn_within_blocks_u8x16(self, a: u8x16<Self>, indices: u8x16<Self>) -> u8x16<Self>;
651    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
652    fn swizzle_dyn_u8x16(self, a: u8x16<Self>, indices: u8x16<Self>) -> u8x16<Self>;
653    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
654    fn swizzle_dyn_precise_u8x16(self, a: u8x16<Self>, indices: u8x16<Self>) -> u8x16<Self>;
655    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
656    fn concat_swizzle_dyn_u8x16(
657        self,
658        a: u8x16<Self>,
659        b: u8x16<Self>,
660        indices: u8x16<Self>,
661    ) -> u8x16<Self>;
662    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
663    fn concat_swizzle_dyn_precise_u8x16(
664        self,
665        a: u8x16<Self>,
666        b: u8x16<Self>,
667        indices: u8x16<Self>,
668    ) -> u8x16<Self>;
669    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
670    fn compress_u8x16(self, values: u8x16<Self>, mask: mask8x16<Self>) -> u8x16<Self>;
671    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
672    fn compress_merge_u8x16(
673        self,
674        values: u8x16<Self>,
675        mask: mask8x16<Self>,
676        merge: u8x16<Self>,
677    ) -> u8x16<Self>;
678    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
679    fn expand_u8x16(self, values: u8x16<Self>, mask: mask8x16<Self>) -> u8x16<Self>;
680    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
681    fn expand_merge_u8x16(
682        self,
683        values: u8x16<Self>,
684        mask: mask8x16<Self>,
685        merge: u8x16<Self>,
686    ) -> u8x16<Self>;
687    #[doc = "Return the number of ones in the binary representation of each element."]
688    fn count_ones_u8x16(self, a: u8x16<Self>) -> u8x16<Self>;
689    #[doc = "Return the number of zeros in the binary representation of each element."]
690    fn count_zeros_u8x16(self, a: u8x16<Self>) -> u8x16<Self>;
691    #[doc = "Add two vectors element-wise, wrapping on overflow."]
692    fn add_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
693    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
694    fn saturating_add_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
695    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
696    fn sub_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
697    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
698    fn saturating_sub_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
699    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
700    fn mul_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
701    #[doc = "Compute the bitwise AND of two vectors."]
702    fn and_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
703    #[doc = "Compute the bitwise OR of two vectors."]
704    fn or_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
705    #[doc = "Compute the bitwise XOR of two vectors."]
706    fn xor_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
707    #[doc = "Compute the bitwise NOT of the vector."]
708    fn not_u8x16(self, a: u8x16<Self>) -> u8x16<Self>;
709    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
710    fn shl_u8x16(self, a: u8x16<Self>, shift: u32) -> u8x16<Self>;
711    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
712    fn shlv_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
713    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
714    fn shr_u8x16(self, a: u8x16<Self>, shift: u32) -> u8x16<Self>;
715    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
716    fn shrv_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
717    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
718    fn reduce_max_u8x16(self, a: u8x16<Self>) -> u8;
719    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
720    fn reduce_min_u8x16(self, a: u8x16<Self>) -> u8;
721    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
722    fn reduce_sum_u8x16(self, a: u8x16<Self>) -> u8;
723    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
724    fn reduce_product_u8x16(self, a: u8x16<Self>) -> u8;
725    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
726    fn max_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
727    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
728    fn min_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
729    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
730    fn clamp_u8x16(self, a: u8x16<Self>, b: u8x16<Self>, c: u8x16<Self>) -> u8x16<Self>;
731    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
732    fn simd_eq_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> mask8x16<Self>;
733    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
734    #[inline(always)]
735    fn simd_ne_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> mask8x16<Self> {
736        self.not_mask8x16(self.simd_eq_u8x16(a, b))
737    }
738    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
739    fn simd_lt_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> mask8x16<Self>;
740    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
741    fn simd_le_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> mask8x16<Self>;
742    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
743    #[inline(always)]
744    fn simd_ge_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> mask8x16<Self> {
745        self.simd_le_u8x16(b, a)
746    }
747    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
748    #[inline(always)]
749    fn simd_gt_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> mask8x16<Self> {
750        self.simd_lt_u8x16(b, a)
751    }
752    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
753    fn zip_low_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
754    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
755    fn zip_high_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
756    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
757    fn unzip_low_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
758    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
759    fn unzip_high_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x16<Self>;
760    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
761    fn interleave_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> (u8x16<Self>, u8x16<Self>);
762    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
763    fn deinterleave_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> (u8x16<Self>, u8x16<Self>);
764    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
765    fn select_u8x16(self, a: mask8x16<Self>, b: u8x16<Self>, c: u8x16<Self>) -> u8x16<Self>;
766    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
767    fn combine_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u8x32<Self>;
768    #[doc = "Load four 128-bit vectors from an array with 4-way interleaving.\n\nThis is useful e.g. in image processing to turn interleaved RGBA pixels into vectors of each color component.\n\nFor example, with 32-bit lanes, memory laid out as`[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]` loads as`[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]`."]
769    #[doc(alias = "load_interleaved")]
770    fn load_four_interleaved_u8x16(self, src: &[u8; 64usize]) -> [u8x16<Self>; 4usize];
771    #[doc = "Store four 128-bit vectors to an array with 4-way interleaving.\n\nThis is the inverse of `load_four_interleaved`.\n\nThis is useful e.g. in image processing to turn vectors of each color component into interleaved RGBA pixels.\n\nFor example, with 32-bit lanes, vectors containing `[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]` get stored as `[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]`."]
772    #[doc(alias = "store_interleaved")]
773    fn store_four_interleaved_u8x16(
774        self,
775        vectors: [u8x16<Self>; 4usize],
776        dest: &mut [u8; 64usize],
777    ) -> ();
778    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
779    fn widen_u8x16(self, a: u8x16<Self>) -> (u16x8<Self>, u16x8<Self>);
780    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
781    fn widening_mul_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> (u16x8<Self>, u16x8<Self>);
782    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
783    fn widening_add_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> (u16x8<Self>, u16x8<Self>);
784    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
785    fn pairwise_widening_add_u8x16(self, a: u8x16<Self>) -> u16x8<Self>;
786    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
787    fn pairwise_dot_product_u8x16(self, a: u8x16<Self>, b: u8x16<Self>) -> u16x8<Self>;
788    #[doc = "Create a SIMD mask with all lanes set from the given boolean value."]
789    fn splat_mask8x16(self, val: bool) -> mask8x16<Self>;
790    #[doc = "Create a SIMD mask from a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are ignored."]
791    fn from_bitmask_mask8x16(self, bits: u64) -> mask8x16<Self>;
792    #[doc = "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared."]
793    fn to_bitmask_mask8x16(self, a: mask8x16<Self>) -> u64;
794    #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."]
795    fn from_vector_mask8x16(self, vector: i8x16<Self>) -> mask8x16<Self>;
796    #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."]
797    fn to_vector_mask8x16(self, a: mask8x16<Self>) -> i8x16<Self>;
798    #[doc = "Set one logical lane of a SIMD mask."]
799    fn set_mask8x16(self, a: &mut mask8x16<Self>, index: usize, value: bool) -> ();
800    #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
801    fn rotate_elements_left_mask8x16<const OFFSET: usize>(
802        self,
803        a: mask8x16<Self>,
804    ) -> mask8x16<Self>;
805    #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
806    fn rotate_elements_right_mask8x16<const OFFSET: usize>(
807        self,
808        a: mask8x16<Self>,
809    ) -> mask8x16<Self>;
810    #[doc = "Compute the logical AND of two masks."]
811    fn and_mask8x16(self, a: mask8x16<Self>, b: mask8x16<Self>) -> mask8x16<Self>;
812    #[doc = "Compute the logical OR of two masks."]
813    fn or_mask8x16(self, a: mask8x16<Self>, b: mask8x16<Self>) -> mask8x16<Self>;
814    #[doc = "Compute the logical XOR of two masks."]
815    fn xor_mask8x16(self, a: mask8x16<Self>, b: mask8x16<Self>) -> mask8x16<Self>;
816    #[doc = "Compute the logical NOT of the mask."]
817    fn not_mask8x16(self, a: mask8x16<Self>) -> mask8x16<Self>;
818    #[doc = "Reverse the order of the mask's logical lanes."]
819    fn reverse_mask8x16(self, a: mask8x16<Self>) -> mask8x16<Self>;
820    #[doc = "Select elements from `b` and `c` based on the mask operand `a`.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
821    fn select_mask8x16(
822        self,
823        a: mask8x16<Self>,
824        b: mask8x16<Self>,
825        c: mask8x16<Self>,
826    ) -> mask8x16<Self>;
827    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
828    fn simd_eq_mask8x16(self, a: mask8x16<Self>, b: mask8x16<Self>) -> mask8x16<Self>;
829    #[doc = "Compare two masks element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
830    #[inline(always)]
831    fn simd_ne_mask8x16(self, a: mask8x16<Self>, b: mask8x16<Self>) -> mask8x16<Self> {
832        self.not_mask8x16(self.simd_eq_mask8x16(a, b))
833    }
834    #[doc = "Returns true if any logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
835    fn any_true_mask8x16(self, a: mask8x16<Self>) -> bool;
836    #[doc = "Returns true if all logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
837    fn all_true_mask8x16(self, a: mask8x16<Self>) -> bool;
838    #[doc = "Returns true if any logical lanes in this mask are false.\n\nThis is logically equivalent to `!all_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
839    fn any_false_mask8x16(self, a: mask8x16<Self>) -> bool;
840    #[doc = "Returns true if all logical lanes in this mask are false.\n\nThis is logically equivalent to `!any_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
841    fn all_false_mask8x16(self, a: mask8x16<Self>) -> bool;
842    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
843    fn combine_mask8x16(self, a: mask8x16<Self>, b: mask8x16<Self>) -> mask8x32<Self>;
844    #[doc = "Widen each boolean lane into two masks of the same logical width, preserving its value.\n\nThe first result contains the lower lanes and the second contains the upper lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
845    fn widen_mask8x16(self, a: mask8x16<Self>) -> (mask16x8<Self>, mask16x8<Self>);
846    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
847    fn abs_i16x8(self, a: i16x8<Self>) -> i16x8<Self>;
848    #[doc = "Create a SIMD vector with all elements set to the given value."]
849    fn splat_i16x8(self, val: i16) -> i16x8<Self>;
850    #[doc = "Reverse the order of the vector's elements."]
851    fn reverse_i16x8(self, a: i16x8<Self>) -> i16x8<Self>;
852    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
853    fn slide_i16x8<const SHIFT: usize>(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
854    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
855    #[inline(always)]
856    fn slide_within_blocks_i16x8<const SHIFT: usize>(
857        self,
858        a: i16x8<Self>,
859        b: i16x8<Self>,
860    ) -> i16x8<Self> {
861        self.slide_i16x8::<SHIFT>(a, b)
862    }
863    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
864    #[inline(always)]
865    fn swizzle_dyn_within_blocks_i16x8(self, a: i16x8<Self>, indices: u8x16<Self>) -> i16x8<Self> {
866        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x16(Bytes::to_bytes(a), indices))
867    }
868    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
869    #[inline(always)]
870    fn swizzle_dyn_i16x8(self, a: i16x8<Self>, indices: u8x16<Self>) -> i16x8<Self> {
871        Bytes::from_bytes(self.swizzle_dyn_u8x16(Bytes::to_bytes(a), indices))
872    }
873    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
874    #[inline(always)]
875    fn swizzle_dyn_precise_i16x8(self, a: i16x8<Self>, indices: u8x16<Self>) -> i16x8<Self> {
876        Bytes::from_bytes(self.swizzle_dyn_precise_u8x16(Bytes::to_bytes(a), indices))
877    }
878    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
879    #[inline(always)]
880    fn concat_swizzle_dyn_i16x8(
881        self,
882        a: i16x8<Self>,
883        b: i16x8<Self>,
884        indices: u8x16<Self>,
885    ) -> i16x8<Self> {
886        Bytes::from_bytes(self.concat_swizzle_dyn_u8x16(
887            Bytes::to_bytes(a),
888            Bytes::to_bytes(b),
889            indices,
890        ))
891    }
892    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
893    #[inline(always)]
894    fn concat_swizzle_dyn_precise_i16x8(
895        self,
896        a: i16x8<Self>,
897        b: i16x8<Self>,
898        indices: u8x16<Self>,
899    ) -> i16x8<Self> {
900        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x16(
901            Bytes::to_bytes(a),
902            Bytes::to_bytes(b),
903            indices,
904        ))
905    }
906    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
907    fn compress_i16x8(self, values: i16x8<Self>, mask: mask16x8<Self>) -> i16x8<Self>;
908    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
909    fn compress_merge_i16x8(
910        self,
911        values: i16x8<Self>,
912        mask: mask16x8<Self>,
913        merge: i16x8<Self>,
914    ) -> i16x8<Self>;
915    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
916    fn expand_i16x8(self, values: i16x8<Self>, mask: mask16x8<Self>) -> i16x8<Self>;
917    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
918    fn expand_merge_i16x8(
919        self,
920        values: i16x8<Self>,
921        mask: mask16x8<Self>,
922        merge: i16x8<Self>,
923    ) -> i16x8<Self>;
924    #[doc = "Return the number of ones in the binary representation of each element."]
925    fn count_ones_i16x8(self, a: i16x8<Self>) -> i16x8<Self>;
926    #[doc = "Return the number of zeros in the binary representation of each element."]
927    fn count_zeros_i16x8(self, a: i16x8<Self>) -> i16x8<Self>;
928    #[doc = "Add two vectors element-wise, wrapping on overflow."]
929    fn add_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
930    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
931    fn saturating_add_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
932    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
933    fn sub_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
934    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
935    fn saturating_sub_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
936    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
937    fn mul_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
938    #[doc = "Compute the bitwise AND of two vectors."]
939    fn and_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
940    #[doc = "Compute the bitwise OR of two vectors."]
941    fn or_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
942    #[doc = "Compute the bitwise XOR of two vectors."]
943    fn xor_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
944    #[doc = "Compute the bitwise NOT of the vector."]
945    fn not_i16x8(self, a: i16x8<Self>) -> i16x8<Self>;
946    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
947    fn shl_i16x8(self, a: i16x8<Self>, shift: u32) -> i16x8<Self>;
948    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
949    fn shlv_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
950    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
951    fn shr_i16x8(self, a: i16x8<Self>, shift: u32) -> i16x8<Self>;
952    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
953    fn shrv_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
954    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
955    fn reduce_max_i16x8(self, a: i16x8<Self>) -> i16;
956    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
957    fn reduce_min_i16x8(self, a: i16x8<Self>) -> i16;
958    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
959    fn reduce_sum_i16x8(self, a: i16x8<Self>) -> i16;
960    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
961    fn reduce_product_i16x8(self, a: i16x8<Self>) -> i16;
962    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
963    fn max_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
964    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
965    fn min_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
966    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
967    fn clamp_i16x8(self, a: i16x8<Self>, b: i16x8<Self>, c: i16x8<Self>) -> i16x8<Self>;
968    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
969    fn simd_eq_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> mask16x8<Self>;
970    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
971    #[inline(always)]
972    fn simd_ne_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> mask16x8<Self> {
973        self.not_mask16x8(self.simd_eq_i16x8(a, b))
974    }
975    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
976    fn simd_lt_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> mask16x8<Self>;
977    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
978    fn simd_le_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> mask16x8<Self>;
979    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
980    #[inline(always)]
981    fn simd_ge_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> mask16x8<Self> {
982        self.simd_le_i16x8(b, a)
983    }
984    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
985    #[inline(always)]
986    fn simd_gt_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> mask16x8<Self> {
987        self.simd_lt_i16x8(b, a)
988    }
989    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
990    fn zip_low_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
991    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
992    fn zip_high_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
993    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
994    fn unzip_low_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
995    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
996    fn unzip_high_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x8<Self>;
997    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
998    fn interleave_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> (i16x8<Self>, i16x8<Self>);
999    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
1000    fn deinterleave_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> (i16x8<Self>, i16x8<Self>);
1001    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
1002    fn select_i16x8(self, a: mask16x8<Self>, b: i16x8<Self>, c: i16x8<Self>) -> i16x8<Self>;
1003    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
1004    fn combine_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i16x16<Self>;
1005    #[doc = "Negate each element of the vector, wrapping on overflow."]
1006    fn neg_i16x8(self, a: i16x8<Self>) -> i16x8<Self>;
1007    #[doc = "Load four 128-bit vectors from an array with 4-way interleaving.\n\nThis is useful e.g. in image processing to turn interleaved RGBA pixels into vectors of each color component.\n\nFor example, with 32-bit lanes, memory laid out as`[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]` loads as`[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]`."]
1008    #[doc(alias = "load_interleaved")]
1009    fn load_four_interleaved_i16x8(self, src: &[i16; 32usize]) -> [i16x8<Self>; 4usize];
1010    #[doc = "Store four 128-bit vectors to an array with 4-way interleaving.\n\nThis is the inverse of `load_four_interleaved`.\n\nThis is useful e.g. in image processing to turn vectors of each color component into interleaved RGBA pixels.\n\nFor example, with 32-bit lanes, vectors containing `[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]` get stored as `[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]`."]
1011    #[doc(alias = "store_interleaved")]
1012    fn store_four_interleaved_i16x8(
1013        self,
1014        vectors: [i16x8<Self>; 4usize],
1015        dest: &mut [i16; 32usize],
1016    ) -> ();
1017    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
1018    fn widen_i16x8(self, a: i16x8<Self>) -> (i32x4<Self>, i32x4<Self>);
1019    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
1020    fn widening_mul_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> (i32x4<Self>, i32x4<Self>);
1021    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
1022    fn widening_add_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> (i32x4<Self>, i32x4<Self>);
1023    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
1024    fn pairwise_widening_add_i16x8(self, a: i16x8<Self>) -> i32x4<Self>;
1025    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
1026    fn pairwise_dot_product_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i32x4<Self>;
1027    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
1028    fn narrow_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i8x16<Self>;
1029    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
1030    fn saturating_narrow_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i8x16<Self>;
1031    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
1032    fn relaxed_narrow_i16x8(self, a: i16x8<Self>, b: i16x8<Self>) -> i8x16<Self>;
1033    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
1034    #[inline(always)]
1035    fn abs_u16x8(self, a: u16x8<Self>) -> u16x8<Self> {
1036        a
1037    }
1038    #[doc = "Create a SIMD vector with all elements set to the given value."]
1039    fn splat_u16x8(self, val: u16) -> u16x8<Self>;
1040    #[doc = "Reverse the order of the vector's elements."]
1041    fn reverse_u16x8(self, a: u16x8<Self>) -> u16x8<Self>;
1042    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
1043    fn slide_u16x8<const SHIFT: usize>(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1044    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
1045    #[inline(always)]
1046    fn slide_within_blocks_u16x8<const SHIFT: usize>(
1047        self,
1048        a: u16x8<Self>,
1049        b: u16x8<Self>,
1050    ) -> u16x8<Self> {
1051        self.slide_u16x8::<SHIFT>(a, b)
1052    }
1053    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
1054    #[inline(always)]
1055    fn swizzle_dyn_within_blocks_u16x8(self, a: u16x8<Self>, indices: u8x16<Self>) -> u16x8<Self> {
1056        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x16(Bytes::to_bytes(a), indices))
1057    }
1058    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
1059    #[inline(always)]
1060    fn swizzle_dyn_u16x8(self, a: u16x8<Self>, indices: u8x16<Self>) -> u16x8<Self> {
1061        Bytes::from_bytes(self.swizzle_dyn_u8x16(Bytes::to_bytes(a), indices))
1062    }
1063    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
1064    #[inline(always)]
1065    fn swizzle_dyn_precise_u16x8(self, a: u16x8<Self>, indices: u8x16<Self>) -> u16x8<Self> {
1066        Bytes::from_bytes(self.swizzle_dyn_precise_u8x16(Bytes::to_bytes(a), indices))
1067    }
1068    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
1069    #[inline(always)]
1070    fn concat_swizzle_dyn_u16x8(
1071        self,
1072        a: u16x8<Self>,
1073        b: u16x8<Self>,
1074        indices: u8x16<Self>,
1075    ) -> u16x8<Self> {
1076        Bytes::from_bytes(self.concat_swizzle_dyn_u8x16(
1077            Bytes::to_bytes(a),
1078            Bytes::to_bytes(b),
1079            indices,
1080        ))
1081    }
1082    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
1083    #[inline(always)]
1084    fn concat_swizzle_dyn_precise_u16x8(
1085        self,
1086        a: u16x8<Self>,
1087        b: u16x8<Self>,
1088        indices: u8x16<Self>,
1089    ) -> u16x8<Self> {
1090        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x16(
1091            Bytes::to_bytes(a),
1092            Bytes::to_bytes(b),
1093            indices,
1094        ))
1095    }
1096    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
1097    fn compress_u16x8(self, values: u16x8<Self>, mask: mask16x8<Self>) -> u16x8<Self>;
1098    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
1099    fn compress_merge_u16x8(
1100        self,
1101        values: u16x8<Self>,
1102        mask: mask16x8<Self>,
1103        merge: u16x8<Self>,
1104    ) -> u16x8<Self>;
1105    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
1106    fn expand_u16x8(self, values: u16x8<Self>, mask: mask16x8<Self>) -> u16x8<Self>;
1107    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
1108    fn expand_merge_u16x8(
1109        self,
1110        values: u16x8<Self>,
1111        mask: mask16x8<Self>,
1112        merge: u16x8<Self>,
1113    ) -> u16x8<Self>;
1114    #[doc = "Return the number of ones in the binary representation of each element."]
1115    fn count_ones_u16x8(self, a: u16x8<Self>) -> u16x8<Self>;
1116    #[doc = "Return the number of zeros in the binary representation of each element."]
1117    fn count_zeros_u16x8(self, a: u16x8<Self>) -> u16x8<Self>;
1118    #[doc = "Add two vectors element-wise, wrapping on overflow."]
1119    fn add_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1120    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
1121    fn saturating_add_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1122    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
1123    fn sub_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1124    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
1125    fn saturating_sub_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1126    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
1127    fn mul_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1128    #[doc = "Compute the bitwise AND of two vectors."]
1129    fn and_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1130    #[doc = "Compute the bitwise OR of two vectors."]
1131    fn or_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1132    #[doc = "Compute the bitwise XOR of two vectors."]
1133    fn xor_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1134    #[doc = "Compute the bitwise NOT of the vector."]
1135    fn not_u16x8(self, a: u16x8<Self>) -> u16x8<Self>;
1136    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
1137    fn shl_u16x8(self, a: u16x8<Self>, shift: u32) -> u16x8<Self>;
1138    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
1139    fn shlv_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1140    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
1141    fn shr_u16x8(self, a: u16x8<Self>, shift: u32) -> u16x8<Self>;
1142    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
1143    fn shrv_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1144    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
1145    fn reduce_max_u16x8(self, a: u16x8<Self>) -> u16;
1146    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
1147    fn reduce_min_u16x8(self, a: u16x8<Self>) -> u16;
1148    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
1149    fn reduce_sum_u16x8(self, a: u16x8<Self>) -> u16;
1150    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
1151    fn reduce_product_u16x8(self, a: u16x8<Self>) -> u16;
1152    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
1153    fn max_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1154    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
1155    fn min_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1156    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
1157    fn clamp_u16x8(self, a: u16x8<Self>, b: u16x8<Self>, c: u16x8<Self>) -> u16x8<Self>;
1158    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
1159    fn simd_eq_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> mask16x8<Self>;
1160    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
1161    #[inline(always)]
1162    fn simd_ne_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> mask16x8<Self> {
1163        self.not_mask16x8(self.simd_eq_u16x8(a, b))
1164    }
1165    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
1166    fn simd_lt_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> mask16x8<Self>;
1167    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
1168    fn simd_le_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> mask16x8<Self>;
1169    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
1170    #[inline(always)]
1171    fn simd_ge_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> mask16x8<Self> {
1172        self.simd_le_u16x8(b, a)
1173    }
1174    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
1175    #[inline(always)]
1176    fn simd_gt_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> mask16x8<Self> {
1177        self.simd_lt_u16x8(b, a)
1178    }
1179    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
1180    fn zip_low_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1181    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
1182    fn zip_high_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1183    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
1184    fn unzip_low_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1185    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
1186    fn unzip_high_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x8<Self>;
1187    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
1188    fn interleave_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> (u16x8<Self>, u16x8<Self>);
1189    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
1190    fn deinterleave_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> (u16x8<Self>, u16x8<Self>);
1191    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
1192    fn select_u16x8(self, a: mask16x8<Self>, b: u16x8<Self>, c: u16x8<Self>) -> u16x8<Self>;
1193    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
1194    fn combine_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u16x16<Self>;
1195    #[doc = "Load four 128-bit vectors from an array with 4-way interleaving.\n\nThis is useful e.g. in image processing to turn interleaved RGBA pixels into vectors of each color component.\n\nFor example, with 32-bit lanes, memory laid out as`[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]` loads as`[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]`."]
1196    #[doc(alias = "load_interleaved")]
1197    fn load_four_interleaved_u16x8(self, src: &[u16; 32usize]) -> [u16x8<Self>; 4usize];
1198    #[doc = "Store four 128-bit vectors to an array with 4-way interleaving.\n\nThis is the inverse of `load_four_interleaved`.\n\nThis is useful e.g. in image processing to turn vectors of each color component into interleaved RGBA pixels.\n\nFor example, with 32-bit lanes, vectors containing `[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]` get stored as `[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]`."]
1199    #[doc(alias = "store_interleaved")]
1200    fn store_four_interleaved_u16x8(
1201        self,
1202        vectors: [u16x8<Self>; 4usize],
1203        dest: &mut [u16; 32usize],
1204    ) -> ();
1205    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
1206    fn widen_u16x8(self, a: u16x8<Self>) -> (u32x4<Self>, u32x4<Self>);
1207    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
1208    fn widening_mul_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> (u32x4<Self>, u32x4<Self>);
1209    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
1210    fn widening_add_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> (u32x4<Self>, u32x4<Self>);
1211    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
1212    fn pairwise_widening_add_u16x8(self, a: u16x8<Self>) -> u32x4<Self>;
1213    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
1214    fn pairwise_dot_product_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u32x4<Self>;
1215    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
1216    fn narrow_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u8x16<Self>;
1217    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
1218    fn saturating_narrow_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u8x16<Self>;
1219    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
1220    fn relaxed_narrow_u16x8(self, a: u16x8<Self>, b: u16x8<Self>) -> u8x16<Self>;
1221    #[doc = "Create a SIMD mask with all lanes set from the given boolean value."]
1222    fn splat_mask16x8(self, val: bool) -> mask16x8<Self>;
1223    #[doc = "Create a SIMD mask from a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are ignored."]
1224    fn from_bitmask_mask16x8(self, bits: u64) -> mask16x8<Self>;
1225    #[doc = "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared."]
1226    fn to_bitmask_mask16x8(self, a: mask16x8<Self>) -> u64;
1227    #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."]
1228    fn from_vector_mask16x8(self, vector: i16x8<Self>) -> mask16x8<Self>;
1229    #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."]
1230    fn to_vector_mask16x8(self, a: mask16x8<Self>) -> i16x8<Self>;
1231    #[doc = "Set one logical lane of a SIMD mask."]
1232    fn set_mask16x8(self, a: &mut mask16x8<Self>, index: usize, value: bool) -> ();
1233    #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
1234    fn rotate_elements_left_mask16x8<const OFFSET: usize>(
1235        self,
1236        a: mask16x8<Self>,
1237    ) -> mask16x8<Self>;
1238    #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
1239    fn rotate_elements_right_mask16x8<const OFFSET: usize>(
1240        self,
1241        a: mask16x8<Self>,
1242    ) -> mask16x8<Self>;
1243    #[doc = "Compute the logical AND of two masks."]
1244    fn and_mask16x8(self, a: mask16x8<Self>, b: mask16x8<Self>) -> mask16x8<Self>;
1245    #[doc = "Compute the logical OR of two masks."]
1246    fn or_mask16x8(self, a: mask16x8<Self>, b: mask16x8<Self>) -> mask16x8<Self>;
1247    #[doc = "Compute the logical XOR of two masks."]
1248    fn xor_mask16x8(self, a: mask16x8<Self>, b: mask16x8<Self>) -> mask16x8<Self>;
1249    #[doc = "Compute the logical NOT of the mask."]
1250    fn not_mask16x8(self, a: mask16x8<Self>) -> mask16x8<Self>;
1251    #[doc = "Reverse the order of the mask's logical lanes."]
1252    fn reverse_mask16x8(self, a: mask16x8<Self>) -> mask16x8<Self>;
1253    #[doc = "Select elements from `b` and `c` based on the mask operand `a`.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
1254    fn select_mask16x8(
1255        self,
1256        a: mask16x8<Self>,
1257        b: mask16x8<Self>,
1258        c: mask16x8<Self>,
1259    ) -> mask16x8<Self>;
1260    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
1261    fn simd_eq_mask16x8(self, a: mask16x8<Self>, b: mask16x8<Self>) -> mask16x8<Self>;
1262    #[doc = "Compare two masks element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
1263    #[inline(always)]
1264    fn simd_ne_mask16x8(self, a: mask16x8<Self>, b: mask16x8<Self>) -> mask16x8<Self> {
1265        self.not_mask16x8(self.simd_eq_mask16x8(a, b))
1266    }
1267    #[doc = "Returns true if any logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
1268    fn any_true_mask16x8(self, a: mask16x8<Self>) -> bool;
1269    #[doc = "Returns true if all logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
1270    fn all_true_mask16x8(self, a: mask16x8<Self>) -> bool;
1271    #[doc = "Returns true if any logical lanes in this mask are false.\n\nThis is logically equivalent to `!all_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
1272    fn any_false_mask16x8(self, a: mask16x8<Self>) -> bool;
1273    #[doc = "Returns true if all logical lanes in this mask are false.\n\nThis is logically equivalent to `!any_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
1274    fn all_false_mask16x8(self, a: mask16x8<Self>) -> bool;
1275    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
1276    fn combine_mask16x8(self, a: mask16x8<Self>, b: mask16x8<Self>) -> mask16x16<Self>;
1277    #[doc = "Widen each boolean lane into two masks of the same logical width, preserving its value.\n\nThe first result contains the lower lanes and the second contains the upper lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
1278    fn widen_mask16x8(self, a: mask16x8<Self>) -> (mask32x4<Self>, mask32x4<Self>);
1279    #[doc = "Narrow each boolean lane of two masks and concatenate them into one mask of the same logical width, preserving each value.\n\n`a` supplies the lower result lanes and `b` supplies the upper result lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
1280    fn narrow_mask16x8(self, a: mask16x8<Self>, b: mask16x8<Self>) -> mask8x16<Self>;
1281    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
1282    fn abs_i32x4(self, a: i32x4<Self>) -> i32x4<Self>;
1283    #[doc = "Create a SIMD vector with all elements set to the given value."]
1284    fn splat_i32x4(self, val: i32) -> i32x4<Self>;
1285    #[doc = "Reverse the order of the vector's elements."]
1286    fn reverse_i32x4(self, a: i32x4<Self>) -> i32x4<Self>;
1287    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
1288    fn slide_i32x4<const SHIFT: usize>(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1289    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
1290    #[inline(always)]
1291    fn slide_within_blocks_i32x4<const SHIFT: usize>(
1292        self,
1293        a: i32x4<Self>,
1294        b: i32x4<Self>,
1295    ) -> i32x4<Self> {
1296        self.slide_i32x4::<SHIFT>(a, b)
1297    }
1298    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
1299    #[inline(always)]
1300    fn swizzle_dyn_within_blocks_i32x4(self, a: i32x4<Self>, indices: u8x16<Self>) -> i32x4<Self> {
1301        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x16(Bytes::to_bytes(a), indices))
1302    }
1303    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
1304    #[inline(always)]
1305    fn swizzle_dyn_i32x4(self, a: i32x4<Self>, indices: u8x16<Self>) -> i32x4<Self> {
1306        Bytes::from_bytes(self.swizzle_dyn_u8x16(Bytes::to_bytes(a), indices))
1307    }
1308    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
1309    #[inline(always)]
1310    fn swizzle_dyn_precise_i32x4(self, a: i32x4<Self>, indices: u8x16<Self>) -> i32x4<Self> {
1311        Bytes::from_bytes(self.swizzle_dyn_precise_u8x16(Bytes::to_bytes(a), indices))
1312    }
1313    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
1314    #[inline(always)]
1315    fn concat_swizzle_dyn_i32x4(
1316        self,
1317        a: i32x4<Self>,
1318        b: i32x4<Self>,
1319        indices: u8x16<Self>,
1320    ) -> i32x4<Self> {
1321        Bytes::from_bytes(self.concat_swizzle_dyn_u8x16(
1322            Bytes::to_bytes(a),
1323            Bytes::to_bytes(b),
1324            indices,
1325        ))
1326    }
1327    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
1328    #[inline(always)]
1329    fn concat_swizzle_dyn_precise_i32x4(
1330        self,
1331        a: i32x4<Self>,
1332        b: i32x4<Self>,
1333        indices: u8x16<Self>,
1334    ) -> i32x4<Self> {
1335        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x16(
1336            Bytes::to_bytes(a),
1337            Bytes::to_bytes(b),
1338            indices,
1339        ))
1340    }
1341    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
1342    fn compress_i32x4(self, values: i32x4<Self>, mask: mask32x4<Self>) -> i32x4<Self>;
1343    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
1344    fn compress_merge_i32x4(
1345        self,
1346        values: i32x4<Self>,
1347        mask: mask32x4<Self>,
1348        merge: i32x4<Self>,
1349    ) -> i32x4<Self>;
1350    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
1351    fn expand_i32x4(self, values: i32x4<Self>, mask: mask32x4<Self>) -> i32x4<Self>;
1352    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
1353    fn expand_merge_i32x4(
1354        self,
1355        values: i32x4<Self>,
1356        mask: mask32x4<Self>,
1357        merge: i32x4<Self>,
1358    ) -> i32x4<Self>;
1359    #[doc = "Return the number of ones in the binary representation of each element."]
1360    fn count_ones_i32x4(self, a: i32x4<Self>) -> i32x4<Self>;
1361    #[doc = "Return the number of zeros in the binary representation of each element."]
1362    fn count_zeros_i32x4(self, a: i32x4<Self>) -> i32x4<Self>;
1363    #[doc = "Add two vectors element-wise, wrapping on overflow."]
1364    fn add_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1365    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
1366    fn saturating_add_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1367    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
1368    fn sub_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1369    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
1370    fn saturating_sub_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1371    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
1372    fn mul_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1373    #[doc = "Compute the bitwise AND of two vectors."]
1374    fn and_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1375    #[doc = "Compute the bitwise OR of two vectors."]
1376    fn or_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1377    #[doc = "Compute the bitwise XOR of two vectors."]
1378    fn xor_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1379    #[doc = "Compute the bitwise NOT of the vector."]
1380    fn not_i32x4(self, a: i32x4<Self>) -> i32x4<Self>;
1381    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
1382    fn shl_i32x4(self, a: i32x4<Self>, shift: u32) -> i32x4<Self>;
1383    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
1384    fn shlv_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1385    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
1386    fn shr_i32x4(self, a: i32x4<Self>, shift: u32) -> i32x4<Self>;
1387    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
1388    fn shrv_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1389    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
1390    fn reduce_max_i32x4(self, a: i32x4<Self>) -> i32;
1391    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
1392    fn reduce_min_i32x4(self, a: i32x4<Self>) -> i32;
1393    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
1394    fn reduce_sum_i32x4(self, a: i32x4<Self>) -> i32;
1395    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
1396    fn reduce_product_i32x4(self, a: i32x4<Self>) -> i32;
1397    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
1398    fn max_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1399    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
1400    fn min_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1401    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
1402    fn clamp_i32x4(self, a: i32x4<Self>, b: i32x4<Self>, c: i32x4<Self>) -> i32x4<Self>;
1403    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
1404    fn simd_eq_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> mask32x4<Self>;
1405    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
1406    #[inline(always)]
1407    fn simd_ne_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> mask32x4<Self> {
1408        self.not_mask32x4(self.simd_eq_i32x4(a, b))
1409    }
1410    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
1411    fn simd_lt_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> mask32x4<Self>;
1412    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
1413    fn simd_le_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> mask32x4<Self>;
1414    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
1415    #[inline(always)]
1416    fn simd_ge_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> mask32x4<Self> {
1417        self.simd_le_i32x4(b, a)
1418    }
1419    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
1420    #[inline(always)]
1421    fn simd_gt_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> mask32x4<Self> {
1422        self.simd_lt_i32x4(b, a)
1423    }
1424    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
1425    fn zip_low_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1426    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
1427    fn zip_high_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1428    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
1429    fn unzip_low_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1430    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
1431    fn unzip_high_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x4<Self>;
1432    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
1433    fn interleave_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> (i32x4<Self>, i32x4<Self>);
1434    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
1435    fn deinterleave_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> (i32x4<Self>, i32x4<Self>);
1436    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
1437    fn select_i32x4(self, a: mask32x4<Self>, b: i32x4<Self>, c: i32x4<Self>) -> i32x4<Self>;
1438    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
1439    fn combine_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i32x8<Self>;
1440    #[doc = "Negate each element of the vector, wrapping on overflow."]
1441    fn neg_i32x4(self, a: i32x4<Self>) -> i32x4<Self>;
1442    #[doc = "Load four 128-bit vectors from an array with 4-way interleaving.\n\nThis is useful e.g. in image processing to turn interleaved RGBA pixels into vectors of each color component.\n\nFor example, with 32-bit lanes, memory laid out as`[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]` loads as`[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]`."]
1443    #[doc(alias = "load_interleaved")]
1444    fn load_four_interleaved_i32x4(self, src: &[i32; 16usize]) -> [i32x4<Self>; 4usize];
1445    #[doc = "Store four 128-bit vectors to an array with 4-way interleaving.\n\nThis is the inverse of `load_four_interleaved`.\n\nThis is useful e.g. in image processing to turn vectors of each color component into interleaved RGBA pixels.\n\nFor example, with 32-bit lanes, vectors containing `[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]` get stored as `[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]`."]
1446    #[doc(alias = "store_interleaved")]
1447    fn store_four_interleaved_i32x4(
1448        self,
1449        vectors: [i32x4<Self>; 4usize],
1450        dest: &mut [i32; 16usize],
1451    ) -> ();
1452    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
1453    fn widen_i32x4(self, a: i32x4<Self>) -> (i64x2<Self>, i64x2<Self>);
1454    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
1455    fn widening_mul_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> (i64x2<Self>, i64x2<Self>);
1456    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
1457    fn widening_add_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> (i64x2<Self>, i64x2<Self>);
1458    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
1459    fn pairwise_widening_add_i32x4(self, a: i32x4<Self>) -> i64x2<Self>;
1460    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
1461    fn pairwise_dot_product_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i64x2<Self>;
1462    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
1463    fn narrow_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i16x8<Self>;
1464    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
1465    fn saturating_narrow_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i16x8<Self>;
1466    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
1467    fn relaxed_narrow_i32x4(self, a: i32x4<Self>, b: i32x4<Self>) -> i16x8<Self>;
1468    #[doc = "Convert each signed 32-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
1469    fn cvt_f32_i32x4(self, a: i32x4<Self>) -> f32x4<Self>;
1470    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
1471    #[inline(always)]
1472    fn abs_u32x4(self, a: u32x4<Self>) -> u32x4<Self> {
1473        a
1474    }
1475    #[doc = "Create a SIMD vector with all elements set to the given value."]
1476    fn splat_u32x4(self, val: u32) -> u32x4<Self>;
1477    #[doc = "Reverse the order of the vector's elements."]
1478    fn reverse_u32x4(self, a: u32x4<Self>) -> u32x4<Self>;
1479    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
1480    fn slide_u32x4<const SHIFT: usize>(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1481    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
1482    #[inline(always)]
1483    fn slide_within_blocks_u32x4<const SHIFT: usize>(
1484        self,
1485        a: u32x4<Self>,
1486        b: u32x4<Self>,
1487    ) -> u32x4<Self> {
1488        self.slide_u32x4::<SHIFT>(a, b)
1489    }
1490    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
1491    #[inline(always)]
1492    fn swizzle_dyn_within_blocks_u32x4(self, a: u32x4<Self>, indices: u8x16<Self>) -> u32x4<Self> {
1493        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x16(Bytes::to_bytes(a), indices))
1494    }
1495    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
1496    #[inline(always)]
1497    fn swizzle_dyn_u32x4(self, a: u32x4<Self>, indices: u8x16<Self>) -> u32x4<Self> {
1498        Bytes::from_bytes(self.swizzle_dyn_u8x16(Bytes::to_bytes(a), indices))
1499    }
1500    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
1501    #[inline(always)]
1502    fn swizzle_dyn_precise_u32x4(self, a: u32x4<Self>, indices: u8x16<Self>) -> u32x4<Self> {
1503        Bytes::from_bytes(self.swizzle_dyn_precise_u8x16(Bytes::to_bytes(a), indices))
1504    }
1505    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
1506    #[inline(always)]
1507    fn concat_swizzle_dyn_u32x4(
1508        self,
1509        a: u32x4<Self>,
1510        b: u32x4<Self>,
1511        indices: u8x16<Self>,
1512    ) -> u32x4<Self> {
1513        Bytes::from_bytes(self.concat_swizzle_dyn_u8x16(
1514            Bytes::to_bytes(a),
1515            Bytes::to_bytes(b),
1516            indices,
1517        ))
1518    }
1519    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
1520    #[inline(always)]
1521    fn concat_swizzle_dyn_precise_u32x4(
1522        self,
1523        a: u32x4<Self>,
1524        b: u32x4<Self>,
1525        indices: u8x16<Self>,
1526    ) -> u32x4<Self> {
1527        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x16(
1528            Bytes::to_bytes(a),
1529            Bytes::to_bytes(b),
1530            indices,
1531        ))
1532    }
1533    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
1534    fn compress_u32x4(self, values: u32x4<Self>, mask: mask32x4<Self>) -> u32x4<Self>;
1535    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
1536    fn compress_merge_u32x4(
1537        self,
1538        values: u32x4<Self>,
1539        mask: mask32x4<Self>,
1540        merge: u32x4<Self>,
1541    ) -> u32x4<Self>;
1542    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
1543    fn expand_u32x4(self, values: u32x4<Self>, mask: mask32x4<Self>) -> u32x4<Self>;
1544    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
1545    fn expand_merge_u32x4(
1546        self,
1547        values: u32x4<Self>,
1548        mask: mask32x4<Self>,
1549        merge: u32x4<Self>,
1550    ) -> u32x4<Self>;
1551    #[doc = "Return the number of ones in the binary representation of each element."]
1552    fn count_ones_u32x4(self, a: u32x4<Self>) -> u32x4<Self>;
1553    #[doc = "Return the number of zeros in the binary representation of each element."]
1554    fn count_zeros_u32x4(self, a: u32x4<Self>) -> u32x4<Self>;
1555    #[doc = "Add two vectors element-wise, wrapping on overflow."]
1556    fn add_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1557    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
1558    fn saturating_add_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1559    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
1560    fn sub_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1561    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
1562    fn saturating_sub_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1563    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
1564    fn mul_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1565    #[doc = "Compute the bitwise AND of two vectors."]
1566    fn and_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1567    #[doc = "Compute the bitwise OR of two vectors."]
1568    fn or_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1569    #[doc = "Compute the bitwise XOR of two vectors."]
1570    fn xor_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1571    #[doc = "Compute the bitwise NOT of the vector."]
1572    fn not_u32x4(self, a: u32x4<Self>) -> u32x4<Self>;
1573    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
1574    fn shl_u32x4(self, a: u32x4<Self>, shift: u32) -> u32x4<Self>;
1575    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
1576    fn shlv_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1577    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
1578    fn shr_u32x4(self, a: u32x4<Self>, shift: u32) -> u32x4<Self>;
1579    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
1580    fn shrv_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1581    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
1582    fn reduce_max_u32x4(self, a: u32x4<Self>) -> u32;
1583    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
1584    fn reduce_min_u32x4(self, a: u32x4<Self>) -> u32;
1585    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
1586    fn reduce_sum_u32x4(self, a: u32x4<Self>) -> u32;
1587    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
1588    fn reduce_product_u32x4(self, a: u32x4<Self>) -> u32;
1589    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
1590    fn max_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1591    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
1592    fn min_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1593    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
1594    fn clamp_u32x4(self, a: u32x4<Self>, b: u32x4<Self>, c: u32x4<Self>) -> u32x4<Self>;
1595    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
1596    fn simd_eq_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> mask32x4<Self>;
1597    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
1598    #[inline(always)]
1599    fn simd_ne_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> mask32x4<Self> {
1600        self.not_mask32x4(self.simd_eq_u32x4(a, b))
1601    }
1602    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
1603    fn simd_lt_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> mask32x4<Self>;
1604    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
1605    fn simd_le_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> mask32x4<Self>;
1606    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
1607    #[inline(always)]
1608    fn simd_ge_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> mask32x4<Self> {
1609        self.simd_le_u32x4(b, a)
1610    }
1611    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
1612    #[inline(always)]
1613    fn simd_gt_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> mask32x4<Self> {
1614        self.simd_lt_u32x4(b, a)
1615    }
1616    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
1617    fn zip_low_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1618    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
1619    fn zip_high_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1620    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
1621    fn unzip_low_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1622    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
1623    fn unzip_high_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x4<Self>;
1624    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
1625    fn interleave_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> (u32x4<Self>, u32x4<Self>);
1626    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
1627    fn deinterleave_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> (u32x4<Self>, u32x4<Self>);
1628    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
1629    fn select_u32x4(self, a: mask32x4<Self>, b: u32x4<Self>, c: u32x4<Self>) -> u32x4<Self>;
1630    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
1631    fn combine_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u32x8<Self>;
1632    #[doc = "Load four 128-bit vectors from an array with 4-way interleaving.\n\nThis is useful e.g. in image processing to turn interleaved RGBA pixels into vectors of each color component.\n\nFor example, with 32-bit lanes, memory laid out as`[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]` loads as`[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]`."]
1633    #[doc(alias = "load_interleaved")]
1634    fn load_four_interleaved_u32x4(self, src: &[u32; 16usize]) -> [u32x4<Self>; 4usize];
1635    #[doc = "Store four 128-bit vectors to an array with 4-way interleaving.\n\nThis is the inverse of `load_four_interleaved`.\n\nThis is useful e.g. in image processing to turn vectors of each color component into interleaved RGBA pixels.\n\nFor example, with 32-bit lanes, vectors containing `[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]` get stored as `[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]`."]
1636    #[doc(alias = "store_interleaved")]
1637    fn store_four_interleaved_u32x4(
1638        self,
1639        vectors: [u32x4<Self>; 4usize],
1640        dest: &mut [u32; 16usize],
1641    ) -> ();
1642    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
1643    fn widen_u32x4(self, a: u32x4<Self>) -> (u64x2<Self>, u64x2<Self>);
1644    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
1645    fn widening_mul_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> (u64x2<Self>, u64x2<Self>);
1646    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
1647    fn widening_add_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> (u64x2<Self>, u64x2<Self>);
1648    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
1649    fn pairwise_widening_add_u32x4(self, a: u32x4<Self>) -> u64x2<Self>;
1650    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
1651    fn pairwise_dot_product_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u64x2<Self>;
1652    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
1653    fn narrow_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u16x8<Self>;
1654    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
1655    fn saturating_narrow_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u16x8<Self>;
1656    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
1657    fn relaxed_narrow_u32x4(self, a: u32x4<Self>, b: u32x4<Self>) -> u16x8<Self>;
1658    #[doc = "Convert each unsigned 32-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
1659    fn cvt_f32_u32x4(self, a: u32x4<Self>) -> f32x4<Self>;
1660    #[doc = "Create a SIMD mask with all lanes set from the given boolean value."]
1661    fn splat_mask32x4(self, val: bool) -> mask32x4<Self>;
1662    #[doc = "Create a SIMD mask from a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are ignored."]
1663    fn from_bitmask_mask32x4(self, bits: u64) -> mask32x4<Self>;
1664    #[doc = "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared."]
1665    fn to_bitmask_mask32x4(self, a: mask32x4<Self>) -> u64;
1666    #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."]
1667    fn from_vector_mask32x4(self, vector: i32x4<Self>) -> mask32x4<Self>;
1668    #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."]
1669    fn to_vector_mask32x4(self, a: mask32x4<Self>) -> i32x4<Self>;
1670    #[doc = "Set one logical lane of a SIMD mask."]
1671    fn set_mask32x4(self, a: &mut mask32x4<Self>, index: usize, value: bool) -> ();
1672    #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
1673    fn rotate_elements_left_mask32x4<const OFFSET: usize>(
1674        self,
1675        a: mask32x4<Self>,
1676    ) -> mask32x4<Self>;
1677    #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
1678    fn rotate_elements_right_mask32x4<const OFFSET: usize>(
1679        self,
1680        a: mask32x4<Self>,
1681    ) -> mask32x4<Self>;
1682    #[doc = "Compute the logical AND of two masks."]
1683    fn and_mask32x4(self, a: mask32x4<Self>, b: mask32x4<Self>) -> mask32x4<Self>;
1684    #[doc = "Compute the logical OR of two masks."]
1685    fn or_mask32x4(self, a: mask32x4<Self>, b: mask32x4<Self>) -> mask32x4<Self>;
1686    #[doc = "Compute the logical XOR of two masks."]
1687    fn xor_mask32x4(self, a: mask32x4<Self>, b: mask32x4<Self>) -> mask32x4<Self>;
1688    #[doc = "Compute the logical NOT of the mask."]
1689    fn not_mask32x4(self, a: mask32x4<Self>) -> mask32x4<Self>;
1690    #[doc = "Reverse the order of the mask's logical lanes."]
1691    fn reverse_mask32x4(self, a: mask32x4<Self>) -> mask32x4<Self>;
1692    #[doc = "Select elements from `b` and `c` based on the mask operand `a`.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
1693    fn select_mask32x4(
1694        self,
1695        a: mask32x4<Self>,
1696        b: mask32x4<Self>,
1697        c: mask32x4<Self>,
1698    ) -> mask32x4<Self>;
1699    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
1700    fn simd_eq_mask32x4(self, a: mask32x4<Self>, b: mask32x4<Self>) -> mask32x4<Self>;
1701    #[doc = "Compare two masks element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
1702    #[inline(always)]
1703    fn simd_ne_mask32x4(self, a: mask32x4<Self>, b: mask32x4<Self>) -> mask32x4<Self> {
1704        self.not_mask32x4(self.simd_eq_mask32x4(a, b))
1705    }
1706    #[doc = "Returns true if any logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
1707    fn any_true_mask32x4(self, a: mask32x4<Self>) -> bool;
1708    #[doc = "Returns true if all logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
1709    fn all_true_mask32x4(self, a: mask32x4<Self>) -> bool;
1710    #[doc = "Returns true if any logical lanes in this mask are false.\n\nThis is logically equivalent to `!all_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
1711    fn any_false_mask32x4(self, a: mask32x4<Self>) -> bool;
1712    #[doc = "Returns true if all logical lanes in this mask are false.\n\nThis is logically equivalent to `!any_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
1713    fn all_false_mask32x4(self, a: mask32x4<Self>) -> bool;
1714    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
1715    fn combine_mask32x4(self, a: mask32x4<Self>, b: mask32x4<Self>) -> mask32x8<Self>;
1716    #[doc = "Widen each boolean lane into two masks of the same logical width, preserving its value.\n\nThe first result contains the lower lanes and the second contains the upper lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
1717    fn widen_mask32x4(self, a: mask32x4<Self>) -> (mask64x2<Self>, mask64x2<Self>);
1718    #[doc = "Narrow each boolean lane of two masks and concatenate them into one mask of the same logical width, preserving each value.\n\n`a` supplies the lower result lanes and `b` supplies the upper result lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
1719    fn narrow_mask32x4(self, a: mask32x4<Self>, b: mask32x4<Self>) -> mask16x8<Self>;
1720    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
1721    fn abs_f64x2(self, a: f64x2<Self>) -> f64x2<Self>;
1722    #[doc = "Create a SIMD vector with all elements set to the given value."]
1723    fn splat_f64x2(self, val: f64) -> f64x2<Self>;
1724    #[doc = "Reverse the order of the vector's elements."]
1725    fn reverse_f64x2(self, a: f64x2<Self>) -> f64x2<Self>;
1726    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
1727    fn slide_f64x2<const SHIFT: usize>(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self>;
1728    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
1729    #[inline(always)]
1730    fn slide_within_blocks_f64x2<const SHIFT: usize>(
1731        self,
1732        a: f64x2<Self>,
1733        b: f64x2<Self>,
1734    ) -> f64x2<Self> {
1735        self.slide_f64x2::<SHIFT>(a, b)
1736    }
1737    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
1738    #[inline(always)]
1739    fn swizzle_dyn_within_blocks_f64x2(self, a: f64x2<Self>, indices: u8x16<Self>) -> f64x2<Self> {
1740        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x16(Bytes::to_bytes(a), indices))
1741    }
1742    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
1743    #[inline(always)]
1744    fn swizzle_dyn_f64x2(self, a: f64x2<Self>, indices: u8x16<Self>) -> f64x2<Self> {
1745        Bytes::from_bytes(self.swizzle_dyn_u8x16(Bytes::to_bytes(a), indices))
1746    }
1747    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
1748    #[inline(always)]
1749    fn swizzle_dyn_precise_f64x2(self, a: f64x2<Self>, indices: u8x16<Self>) -> f64x2<Self> {
1750        Bytes::from_bytes(self.swizzle_dyn_precise_u8x16(Bytes::to_bytes(a), indices))
1751    }
1752    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
1753    #[inline(always)]
1754    fn concat_swizzle_dyn_f64x2(
1755        self,
1756        a: f64x2<Self>,
1757        b: f64x2<Self>,
1758        indices: u8x16<Self>,
1759    ) -> f64x2<Self> {
1760        Bytes::from_bytes(self.concat_swizzle_dyn_u8x16(
1761            Bytes::to_bytes(a),
1762            Bytes::to_bytes(b),
1763            indices,
1764        ))
1765    }
1766    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
1767    #[inline(always)]
1768    fn concat_swizzle_dyn_precise_f64x2(
1769        self,
1770        a: f64x2<Self>,
1771        b: f64x2<Self>,
1772        indices: u8x16<Self>,
1773    ) -> f64x2<Self> {
1774        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x16(
1775            Bytes::to_bytes(a),
1776            Bytes::to_bytes(b),
1777            indices,
1778        ))
1779    }
1780    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
1781    fn compress_f64x2(self, values: f64x2<Self>, mask: mask64x2<Self>) -> f64x2<Self>;
1782    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
1783    fn compress_merge_f64x2(
1784        self,
1785        values: f64x2<Self>,
1786        mask: mask64x2<Self>,
1787        merge: f64x2<Self>,
1788    ) -> f64x2<Self>;
1789    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
1790    fn expand_f64x2(self, values: f64x2<Self>, mask: mask64x2<Self>) -> f64x2<Self>;
1791    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
1792    fn expand_merge_f64x2(
1793        self,
1794        values: f64x2<Self>,
1795        mask: mask64x2<Self>,
1796        merge: f64x2<Self>,
1797    ) -> f64x2<Self>;
1798    #[doc = "Negate each element of the vector."]
1799    fn neg_f64x2(self, a: f64x2<Self>) -> f64x2<Self>;
1800    #[doc = "Compute the square root of each element.\n\nNegative elements other than `-0.0` will become NaN."]
1801    fn sqrt_f64x2(self, a: f64x2<Self>) -> f64x2<Self>;
1802    #[doc = "Compute an approximate reciprocal (`1. / x`) for each element.\n\nThis uses a fast hardware estimate where available, and falls back to exact division otherwise.\n\nOn x86 for `f32`, this has a relative error less than `1.5 × 2^-12`. On `AArch64` (`f32` and `f64`), this has a relative error less than `2^-8`. The precision of this operation may change as new platform support is added."]
1803    fn approximate_recip_f64x2(self, a: f64x2<Self>) -> f64x2<Self>;
1804    #[doc = "Add two vectors element-wise."]
1805    fn add_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self>;
1806    #[doc = "Subtract two vectors element-wise."]
1807    fn sub_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self>;
1808    #[doc = "Multiply two vectors element-wise."]
1809    fn mul_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self>;
1810    #[doc = "Divide two vectors element-wise."]
1811    fn div_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self>;
1812    #[doc = "Return a vector with the magnitude of `a` and the sign of `b` for each element.\n\nThis operation copies the sign bit, so if an input element is NaN, the output element will be a NaN with the same payload and a copied sign bit."]
1813    fn copysign_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self>;
1814    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
1815    fn reduce_max_f64x2(self, a: f64x2<Self>) -> f64;
1816    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
1817    fn reduce_min_f64x2(self, a: f64x2<Self>) -> f64;
1818    #[doc = "Return the maximum element in the vector, ignoring quiet NaNs.\n\nFor integer vectors, this operation is the same as `reduce_max`.\n\nFor floating-point vectors, quiet NaNs are ignored. If there is at least one numeric lane, this returns the true maximum of the numeric lanes. If all lanes are quiet NaNs, this returns NaN, with an unspecified payload and sign.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned.\n\nIf any lane is a *signaling* NaN, the result is fully non-deterministic: it may be NaN or a numeric lane and is not guaranteed to be the true maximum.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
1819    fn reduce_max_precise_f64x2(self, a: f64x2<Self>) -> f64;
1820    #[doc = "Return the minimum element in the vector, ignoring quiet NaNs.\n\nFor integer vectors, this operation is the same as `reduce_min`.\n\nFor floating-point vectors, quiet NaNs are ignored. If there is at least one numeric lane, this returns the true minimum of the numeric lanes. If all lanes are quiet NaNs, this returns NaN, with an unspecified payload and sign.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned.\n\nIf any lane is a *signaling* NaN, the result is fully non-deterministic: it may be NaN or a numeric lane and is not guaranteed to be the true minimum.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
1821    fn reduce_min_precise_f64x2(self, a: f64x2<Self>) -> f64;
1822    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
1823    fn reduce_sum_f64x2(self, a: f64x2<Self>) -> f64;
1824    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
1825    fn reduce_product_f64x2(self, a: f64x2<Self>) -> f64;
1826    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
1827    fn max_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self>;
1828    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
1829    fn min_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self>;
1830    #[doc = "Return the element-wise maximum of two vectors.\n\nFor integer vectors, this operation is the same as `max`.\n\nFor floating-point vectors, if one operand is a quiet NaN and the other is not, this operation will choose the non-NaN operand.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\nIf a floating-point operand is a *signaling* NaN, the result is not just implementation-defined, but fully non-deterministic: it may be either NaN or the non-NaN operand.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
1831    fn max_precise_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self>;
1832    #[doc = "Return the element-wise minimum of two vectors.\n\nFor integer vectors, this operation is the same as `min`.\n\nFor floating-point vectors, if one operand is a quiet NaN and the other is not, this operation will choose the non-NaN operand.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\nIf a floating-point operand is a *signaling* NaN, the result is not just implementation-defined, but fully non-deterministic: it may be either NaN or the non-NaN operand.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
1833    fn min_precise_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self>;
1834    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
1835    fn clamp_f64x2(self, a: f64x2<Self>, b: f64x2<Self>, c: f64x2<Self>) -> f64x2<Self>;
1836    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
1837    fn simd_eq_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> mask64x2<Self>;
1838    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
1839    #[inline(always)]
1840    fn simd_ne_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> mask64x2<Self> {
1841        self.not_mask64x2(self.simd_eq_f64x2(a, b))
1842    }
1843    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
1844    fn simd_lt_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> mask64x2<Self>;
1845    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
1846    fn simd_le_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> mask64x2<Self>;
1847    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
1848    #[inline(always)]
1849    fn simd_ge_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> mask64x2<Self> {
1850        self.simd_le_f64x2(b, a)
1851    }
1852    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
1853    #[inline(always)]
1854    fn simd_gt_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> mask64x2<Self> {
1855        self.simd_lt_f64x2(b, a)
1856    }
1857    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
1858    fn zip_low_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self>;
1859    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
1860    fn zip_high_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self>;
1861    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
1862    fn unzip_low_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self>;
1863    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
1864    fn unzip_high_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x2<Self>;
1865    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
1866    fn interleave_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> (f64x2<Self>, f64x2<Self>);
1867    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
1868    fn deinterleave_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> (f64x2<Self>, f64x2<Self>);
1869    #[doc = "Compute `(a * b) + c` (fused multiply-add) for each element.\n\nDepending on platform support, the result may be computed with only one rounding error, or may be implemented as a regular multiply followed by an add, which will result in two rounding errors."]
1870    fn mul_add_f64x2(self, a: f64x2<Self>, b: f64x2<Self>, c: f64x2<Self>) -> f64x2<Self>;
1871    #[doc = "Compute `(a * b) + c` for each element, with a single rounding at the end.\n\nThe result is the infinite-precision product-plus-add rounded once to the element type. This may be substantially slower than `mul_add` on platforms without fused multiply-add instructions, including WebAssembly.\n\n# Precision guarantees\n\nThis function is **not** susceptible to [the bug](https://github.com/rust-lang/compiler-builtins/issues/1262) in Rust standard library and in musl libc that causes incorrect rounding for near-zero values on CPUs without hardware support for this operation.\n\nOn the tier-2 i586-* targets, this function is correct if and only if SSE2 is available on the CPU.\n\nThe exact `NaN` payloads as well as signaling `NaN`s are not preserved."]
1872    fn mul_add_precise_f64x2(self, a: f64x2<Self>, b: f64x2<Self>, c: f64x2<Self>) -> f64x2<Self>;
1873    #[doc = "Compute `(a * b) - c` (fused multiply-subtract) for each element.\n\nDepending on platform support, the result may be computed with only one rounding error, or may be implemented as a regular multiply followed by a subtract, which will result in two rounding errors."]
1874    fn mul_sub_f64x2(self, a: f64x2<Self>, b: f64x2<Self>, c: f64x2<Self>) -> f64x2<Self>;
1875    #[doc = "Compute `(a * b) - c` for each element, with a single rounding at the end.\n\nThe result is the infinite-precision product-minus-subtrahend rounded once to the element type. This may be substantially slower than `mul_sub` on platforms without fused multiply-add instructions, including WebAssembly.\n        # Precision guarantees\n\nThis function is **not** susceptible to [the bug](https://github.com/rust-lang/compiler-builtins/issues/1262) in Rust standard library and in musl libc that causes incorrect rounding for near-zero values on CPUs without hardware support for this operation.\n\nOn the tier-2 i586-* targets, this function is correct if and only if SSE2 is available on the CPU.\n\nThe exact `NaN` payloads as well as signaling `NaN`s are not preserved."]
1876    fn mul_sub_precise_f64x2(self, a: f64x2<Self>, b: f64x2<Self>, c: f64x2<Self>) -> f64x2<Self>;
1877    #[doc = "Return the largest integer less than or equal to each element, that is, round towards negative infinity."]
1878    fn floor_f64x2(self, a: f64x2<Self>) -> f64x2<Self>;
1879    #[doc = "Return the smallest integer greater than or equal to each element, that is, round towards positive infinity."]
1880    fn ceil_f64x2(self, a: f64x2<Self>) -> f64x2<Self>;
1881    #[doc = "Round each element to the nearest integer, with ties rounding to the nearest even integer."]
1882    fn round_ties_even_f64x2(self, a: f64x2<Self>) -> f64x2<Self>;
1883    #[doc = "Round each element to the nearest integer, with ties rounding away from zero.\n\n## Performance considerations\n\nOnly `AArch64` has native instructions for this operation. `round` has to be emulated on all other platforms which is around 2-4x slower than `round_ties_even`. Prefer using [`round_ties_even`](SimdFloat::round_ties_even) if possible."]
1884    fn round_f64x2(self, a: f64x2<Self>) -> f64x2<Self>;
1885    #[doc = "Return the fractional part of each element.\n\nThis is equivalent to `a - a.trunc()`."]
1886    fn fract_f64x2(self, a: f64x2<Self>) -> f64x2<Self>;
1887    #[doc = "Return the integer part of each element, rounding towards zero."]
1888    fn trunc_f64x2(self, a: f64x2<Self>) -> f64x2<Self>;
1889    #[doc = "Converts radians to degrees.\n\nThe precision of this function is non-deterministic. This means it varies by platform, Rust version, and can even differ within the same execution from one invocation to the next."]
1890    fn to_degrees_f64x2(self, a: f64x2<Self>) -> f64x2<Self>;
1891    #[doc = "Converts degrees to radians.\n\nThe precision of this function is non-deterministic. This means it varies by platform, Rust version, and can even differ within the same execution from one invocation to the next."]
1892    fn to_radians_f64x2(self, a: f64x2<Self>) -> f64x2<Self>;
1893    #[doc = "Return a mask indicating which elements are NaN."]
1894    fn is_nan_f64x2(self, a: f64x2<Self>) -> mask64x2<Self>;
1895    #[doc = "Return a mask indicating which elements are positive or negative infinite."]
1896    fn is_infinite_f64x2(self, a: f64x2<Self>) -> mask64x2<Self>;
1897    #[doc = "Return a mask indicating which elements are neither infinite nor NaN."]
1898    fn is_finite_f64x2(self, a: f64x2<Self>) -> mask64x2<Self>;
1899    #[doc = "Return a mask indicating which elements are subnormal.\n\nThis classifies the stored bit pattern, even when floating-point operations treat subnormals as zero."]
1900    fn is_subnormal_f64x2(self, a: f64x2<Self>) -> mask64x2<Self>;
1901    #[doc = "Return a mask indicating which elements are neither zero, infinite, subnormal, or NaN."]
1902    fn is_normal_f64x2(self, a: f64x2<Self>) -> mask64x2<Self>;
1903    #[doc = "Return a mask indicating which elements have a positive sign, including `+0.0`, NaNs with positive sign bit and positive infinity.\n\nNaN inputs may produce an unexpected or non-portable result, see [`f32::is_sign_positive`] for details."]
1904    fn is_sign_positive_f64x2(self, a: f64x2<Self>) -> mask64x2<Self>;
1905    #[doc = "Return a mask indicating which elements have a negative sign, including `-0.0`, NaNs with negative sign bit and negative infinity.\n\nNaN inputs may produce an unexpected or non-portable result, see [`f32::is_sign_negative`] for details."]
1906    fn is_sign_negative_f64x2(self, a: f64x2<Self>) -> mask64x2<Self>;
1907    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
1908    fn select_f64x2(self, a: mask64x2<Self>, b: f64x2<Self>, c: f64x2<Self>) -> f64x2<Self>;
1909    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
1910    fn combine_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f64x4<Self>;
1911    #[doc = "Load four 128-bit vectors from an array with 4-way interleaving.\n\nThis is useful e.g. in image processing to turn interleaved RGBA pixels into vectors of each color component.\n\nFor example, with 32-bit lanes, memory laid out as`[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]` loads as`[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]`."]
1912    #[doc(alias = "load_interleaved")]
1913    fn load_four_interleaved_f64x2(self, src: &[f64; 8usize]) -> [f64x2<Self>; 4usize];
1914    #[doc = "Store four 128-bit vectors to an array with 4-way interleaving.\n\nThis is the inverse of `load_four_interleaved`.\n\nThis is useful e.g. in image processing to turn vectors of each color component into interleaved RGBA pixels.\n\nFor example, with 32-bit lanes, vectors containing `[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]` get stored as `[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]`."]
1915    #[doc(alias = "store_interleaved")]
1916    fn store_four_interleaved_f64x2(
1917        self,
1918        vectors: [f64x2<Self>; 4usize],
1919        dest: &mut [f64; 8usize],
1920    ) -> ();
1921    #[doc = "Convert the lanes of two `f64` vectors to `f32` and concatenate them into one same-width vector.\n\nValues are rounded to the nearest representable `f32`, with ties resolved to even; overflow produces signed infinity.This is the same as the `as` operator, and follows the IEEE 754 narrowing behavior in round-to-even mode.\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
1922    fn narrow_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f32x4<Self>;
1923    #[doc = "Convert the lanes of two `f64` vectors to `f32` and concatenate them into one same-width vector.\n\nFor floating-point vectors this is identical to `narrow`, including its rounding and overflow behavior.\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
1924    fn saturating_narrow_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f32x4<Self>;
1925    #[doc = "Convert the lanes of two `f64` vectors to `f32` and concatenate them into one same-width vector.\n\nFor floating-point vectors this is identical to `narrow`, including its rounding and overflow behavior.\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
1926    fn relaxed_narrow_f64x2(self, a: f64x2<Self>, b: f64x2<Self>) -> f32x4<Self>;
1927    #[doc = "Convert each floating-point element to an unsigned 64-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
1928    fn cvt_u64_f64x2(self, a: f64x2<Self>) -> u64x2<Self>;
1929    #[doc = "Convert each floating-point element to an unsigned 64-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
1930    fn cvt_u64_precise_f64x2(self, a: f64x2<Self>) -> u64x2<Self>;
1931    #[doc = "Convert each floating-point element to a signed 64-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
1932    fn cvt_i64_f64x2(self, a: f64x2<Self>) -> i64x2<Self>;
1933    #[doc = "Convert each floating-point element to a signed 64-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
1934    fn cvt_i64_precise_f64x2(self, a: f64x2<Self>) -> i64x2<Self>;
1935    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
1936    fn abs_i64x2(self, a: i64x2<Self>) -> i64x2<Self>;
1937    #[doc = "Create a SIMD vector with all elements set to the given value."]
1938    fn splat_i64x2(self, val: i64) -> i64x2<Self>;
1939    #[doc = "Reverse the order of the vector's elements."]
1940    fn reverse_i64x2(self, a: i64x2<Self>) -> i64x2<Self>;
1941    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
1942    fn slide_i64x2<const SHIFT: usize>(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
1943    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
1944    #[inline(always)]
1945    fn slide_within_blocks_i64x2<const SHIFT: usize>(
1946        self,
1947        a: i64x2<Self>,
1948        b: i64x2<Self>,
1949    ) -> i64x2<Self> {
1950        self.slide_i64x2::<SHIFT>(a, b)
1951    }
1952    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
1953    #[inline(always)]
1954    fn swizzle_dyn_within_blocks_i64x2(self, a: i64x2<Self>, indices: u8x16<Self>) -> i64x2<Self> {
1955        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x16(Bytes::to_bytes(a), indices))
1956    }
1957    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
1958    #[inline(always)]
1959    fn swizzle_dyn_i64x2(self, a: i64x2<Self>, indices: u8x16<Self>) -> i64x2<Self> {
1960        Bytes::from_bytes(self.swizzle_dyn_u8x16(Bytes::to_bytes(a), indices))
1961    }
1962    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
1963    #[inline(always)]
1964    fn swizzle_dyn_precise_i64x2(self, a: i64x2<Self>, indices: u8x16<Self>) -> i64x2<Self> {
1965        Bytes::from_bytes(self.swizzle_dyn_precise_u8x16(Bytes::to_bytes(a), indices))
1966    }
1967    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
1968    #[inline(always)]
1969    fn concat_swizzle_dyn_i64x2(
1970        self,
1971        a: i64x2<Self>,
1972        b: i64x2<Self>,
1973        indices: u8x16<Self>,
1974    ) -> i64x2<Self> {
1975        Bytes::from_bytes(self.concat_swizzle_dyn_u8x16(
1976            Bytes::to_bytes(a),
1977            Bytes::to_bytes(b),
1978            indices,
1979        ))
1980    }
1981    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
1982    #[inline(always)]
1983    fn concat_swizzle_dyn_precise_i64x2(
1984        self,
1985        a: i64x2<Self>,
1986        b: i64x2<Self>,
1987        indices: u8x16<Self>,
1988    ) -> i64x2<Self> {
1989        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x16(
1990            Bytes::to_bytes(a),
1991            Bytes::to_bytes(b),
1992            indices,
1993        ))
1994    }
1995    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
1996    fn compress_i64x2(self, values: i64x2<Self>, mask: mask64x2<Self>) -> i64x2<Self>;
1997    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
1998    fn compress_merge_i64x2(
1999        self,
2000        values: i64x2<Self>,
2001        mask: mask64x2<Self>,
2002        merge: i64x2<Self>,
2003    ) -> i64x2<Self>;
2004    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
2005    fn expand_i64x2(self, values: i64x2<Self>, mask: mask64x2<Self>) -> i64x2<Self>;
2006    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
2007    fn expand_merge_i64x2(
2008        self,
2009        values: i64x2<Self>,
2010        mask: mask64x2<Self>,
2011        merge: i64x2<Self>,
2012    ) -> i64x2<Self>;
2013    #[doc = "Return the number of ones in the binary representation of each element."]
2014    fn count_ones_i64x2(self, a: i64x2<Self>) -> i64x2<Self>;
2015    #[doc = "Return the number of zeros in the binary representation of each element."]
2016    fn count_zeros_i64x2(self, a: i64x2<Self>) -> i64x2<Self>;
2017    #[doc = "Add two vectors element-wise, wrapping on overflow."]
2018    fn add_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
2019    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
2020    fn saturating_add_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
2021    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
2022    fn sub_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
2023    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
2024    fn saturating_sub_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
2025    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
2026    fn mul_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
2027    #[doc = "Compute the bitwise AND of two vectors."]
2028    fn and_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
2029    #[doc = "Compute the bitwise OR of two vectors."]
2030    fn or_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
2031    #[doc = "Compute the bitwise XOR of two vectors."]
2032    fn xor_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
2033    #[doc = "Compute the bitwise NOT of the vector."]
2034    fn not_i64x2(self, a: i64x2<Self>) -> i64x2<Self>;
2035    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
2036    fn shl_i64x2(self, a: i64x2<Self>, shift: u32) -> i64x2<Self>;
2037    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
2038    fn shlv_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
2039    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
2040    fn shr_i64x2(self, a: i64x2<Self>, shift: u32) -> i64x2<Self>;
2041    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
2042    fn shrv_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
2043    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
2044    fn reduce_max_i64x2(self, a: i64x2<Self>) -> i64;
2045    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
2046    fn reduce_min_i64x2(self, a: i64x2<Self>) -> i64;
2047    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
2048    fn reduce_sum_i64x2(self, a: i64x2<Self>) -> i64;
2049    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
2050    fn reduce_product_i64x2(self, a: i64x2<Self>) -> i64;
2051    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
2052    fn max_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
2053    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
2054    fn min_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
2055    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
2056    fn clamp_i64x2(self, a: i64x2<Self>, b: i64x2<Self>, c: i64x2<Self>) -> i64x2<Self>;
2057    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
2058    fn simd_eq_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> mask64x2<Self>;
2059    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
2060    #[inline(always)]
2061    fn simd_ne_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> mask64x2<Self> {
2062        self.not_mask64x2(self.simd_eq_i64x2(a, b))
2063    }
2064    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
2065    fn simd_lt_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> mask64x2<Self>;
2066    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
2067    fn simd_le_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> mask64x2<Self>;
2068    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
2069    #[inline(always)]
2070    fn simd_ge_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> mask64x2<Self> {
2071        self.simd_le_i64x2(b, a)
2072    }
2073    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
2074    #[inline(always)]
2075    fn simd_gt_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> mask64x2<Self> {
2076        self.simd_lt_i64x2(b, a)
2077    }
2078    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
2079    fn zip_low_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
2080    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
2081    fn zip_high_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
2082    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
2083    fn unzip_low_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
2084    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
2085    fn unzip_high_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x2<Self>;
2086    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
2087    fn interleave_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> (i64x2<Self>, i64x2<Self>);
2088    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
2089    fn deinterleave_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> (i64x2<Self>, i64x2<Self>);
2090    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
2091    fn select_i64x2(self, a: mask64x2<Self>, b: i64x2<Self>, c: i64x2<Self>) -> i64x2<Self>;
2092    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
2093    fn combine_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i64x4<Self>;
2094    #[doc = "Negate each element of the vector, wrapping on overflow."]
2095    fn neg_i64x2(self, a: i64x2<Self>) -> i64x2<Self>;
2096    #[doc = "Load four 128-bit vectors from an array with 4-way interleaving.\n\nThis is useful e.g. in image processing to turn interleaved RGBA pixels into vectors of each color component.\n\nFor example, with 32-bit lanes, memory laid out as`[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]` loads as`[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]`."]
2097    #[doc(alias = "load_interleaved")]
2098    fn load_four_interleaved_i64x2(self, src: &[i64; 8usize]) -> [i64x2<Self>; 4usize];
2099    #[doc = "Store four 128-bit vectors to an array with 4-way interleaving.\n\nThis is the inverse of `load_four_interleaved`.\n\nThis is useful e.g. in image processing to turn vectors of each color component into interleaved RGBA pixels.\n\nFor example, with 32-bit lanes, vectors containing `[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]` get stored as `[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]`."]
2100    #[doc(alias = "store_interleaved")]
2101    fn store_four_interleaved_i64x2(
2102        self,
2103        vectors: [i64x2<Self>; 4usize],
2104        dest: &mut [i64; 8usize],
2105    ) -> ();
2106    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
2107    fn narrow_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i32x4<Self>;
2108    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
2109    fn saturating_narrow_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i32x4<Self>;
2110    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
2111    fn relaxed_narrow_i64x2(self, a: i64x2<Self>, b: i64x2<Self>) -> i32x4<Self>;
2112    #[doc = "Convert each signed 64-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
2113    fn cvt_f64_i64x2(self, a: i64x2<Self>) -> f64x2<Self>;
2114    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
2115    #[inline(always)]
2116    fn abs_u64x2(self, a: u64x2<Self>) -> u64x2<Self> {
2117        a
2118    }
2119    #[doc = "Create a SIMD vector with all elements set to the given value."]
2120    fn splat_u64x2(self, val: u64) -> u64x2<Self>;
2121    #[doc = "Reverse the order of the vector's elements."]
2122    fn reverse_u64x2(self, a: u64x2<Self>) -> u64x2<Self>;
2123    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
2124    fn slide_u64x2<const SHIFT: usize>(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2125    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
2126    #[inline(always)]
2127    fn slide_within_blocks_u64x2<const SHIFT: usize>(
2128        self,
2129        a: u64x2<Self>,
2130        b: u64x2<Self>,
2131    ) -> u64x2<Self> {
2132        self.slide_u64x2::<SHIFT>(a, b)
2133    }
2134    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
2135    #[inline(always)]
2136    fn swizzle_dyn_within_blocks_u64x2(self, a: u64x2<Self>, indices: u8x16<Self>) -> u64x2<Self> {
2137        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x16(Bytes::to_bytes(a), indices))
2138    }
2139    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
2140    #[inline(always)]
2141    fn swizzle_dyn_u64x2(self, a: u64x2<Self>, indices: u8x16<Self>) -> u64x2<Self> {
2142        Bytes::from_bytes(self.swizzle_dyn_u8x16(Bytes::to_bytes(a), indices))
2143    }
2144    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
2145    #[inline(always)]
2146    fn swizzle_dyn_precise_u64x2(self, a: u64x2<Self>, indices: u8x16<Self>) -> u64x2<Self> {
2147        Bytes::from_bytes(self.swizzle_dyn_precise_u8x16(Bytes::to_bytes(a), indices))
2148    }
2149    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
2150    #[inline(always)]
2151    fn concat_swizzle_dyn_u64x2(
2152        self,
2153        a: u64x2<Self>,
2154        b: u64x2<Self>,
2155        indices: u8x16<Self>,
2156    ) -> u64x2<Self> {
2157        Bytes::from_bytes(self.concat_swizzle_dyn_u8x16(
2158            Bytes::to_bytes(a),
2159            Bytes::to_bytes(b),
2160            indices,
2161        ))
2162    }
2163    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
2164    #[inline(always)]
2165    fn concat_swizzle_dyn_precise_u64x2(
2166        self,
2167        a: u64x2<Self>,
2168        b: u64x2<Self>,
2169        indices: u8x16<Self>,
2170    ) -> u64x2<Self> {
2171        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x16(
2172            Bytes::to_bytes(a),
2173            Bytes::to_bytes(b),
2174            indices,
2175        ))
2176    }
2177    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
2178    fn compress_u64x2(self, values: u64x2<Self>, mask: mask64x2<Self>) -> u64x2<Self>;
2179    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
2180    fn compress_merge_u64x2(
2181        self,
2182        values: u64x2<Self>,
2183        mask: mask64x2<Self>,
2184        merge: u64x2<Self>,
2185    ) -> u64x2<Self>;
2186    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
2187    fn expand_u64x2(self, values: u64x2<Self>, mask: mask64x2<Self>) -> u64x2<Self>;
2188    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
2189    fn expand_merge_u64x2(
2190        self,
2191        values: u64x2<Self>,
2192        mask: mask64x2<Self>,
2193        merge: u64x2<Self>,
2194    ) -> u64x2<Self>;
2195    #[doc = "Return the number of ones in the binary representation of each element."]
2196    fn count_ones_u64x2(self, a: u64x2<Self>) -> u64x2<Self>;
2197    #[doc = "Return the number of zeros in the binary representation of each element."]
2198    fn count_zeros_u64x2(self, a: u64x2<Self>) -> u64x2<Self>;
2199    #[doc = "Add two vectors element-wise, wrapping on overflow."]
2200    fn add_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2201    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
2202    fn saturating_add_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2203    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
2204    fn sub_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2205    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
2206    fn saturating_sub_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2207    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
2208    fn mul_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2209    #[doc = "Compute the bitwise AND of two vectors."]
2210    fn and_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2211    #[doc = "Compute the bitwise OR of two vectors."]
2212    fn or_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2213    #[doc = "Compute the bitwise XOR of two vectors."]
2214    fn xor_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2215    #[doc = "Compute the bitwise NOT of the vector."]
2216    fn not_u64x2(self, a: u64x2<Self>) -> u64x2<Self>;
2217    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
2218    fn shl_u64x2(self, a: u64x2<Self>, shift: u32) -> u64x2<Self>;
2219    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
2220    fn shlv_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2221    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
2222    fn shr_u64x2(self, a: u64x2<Self>, shift: u32) -> u64x2<Self>;
2223    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
2224    fn shrv_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2225    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
2226    fn reduce_max_u64x2(self, a: u64x2<Self>) -> u64;
2227    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
2228    fn reduce_min_u64x2(self, a: u64x2<Self>) -> u64;
2229    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
2230    fn reduce_sum_u64x2(self, a: u64x2<Self>) -> u64;
2231    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
2232    fn reduce_product_u64x2(self, a: u64x2<Self>) -> u64;
2233    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
2234    fn max_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2235    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
2236    fn min_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2237    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
2238    fn clamp_u64x2(self, a: u64x2<Self>, b: u64x2<Self>, c: u64x2<Self>) -> u64x2<Self>;
2239    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
2240    fn simd_eq_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> mask64x2<Self>;
2241    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
2242    #[inline(always)]
2243    fn simd_ne_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> mask64x2<Self> {
2244        self.not_mask64x2(self.simd_eq_u64x2(a, b))
2245    }
2246    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
2247    fn simd_lt_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> mask64x2<Self>;
2248    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
2249    fn simd_le_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> mask64x2<Self>;
2250    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
2251    #[inline(always)]
2252    fn simd_ge_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> mask64x2<Self> {
2253        self.simd_le_u64x2(b, a)
2254    }
2255    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
2256    #[inline(always)]
2257    fn simd_gt_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> mask64x2<Self> {
2258        self.simd_lt_u64x2(b, a)
2259    }
2260    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
2261    fn zip_low_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2262    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
2263    fn zip_high_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2264    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
2265    fn unzip_low_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2266    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
2267    fn unzip_high_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x2<Self>;
2268    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
2269    fn interleave_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> (u64x2<Self>, u64x2<Self>);
2270    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
2271    fn deinterleave_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> (u64x2<Self>, u64x2<Self>);
2272    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
2273    fn select_u64x2(self, a: mask64x2<Self>, b: u64x2<Self>, c: u64x2<Self>) -> u64x2<Self>;
2274    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
2275    fn combine_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u64x4<Self>;
2276    #[doc = "Load four 128-bit vectors from an array with 4-way interleaving.\n\nThis is useful e.g. in image processing to turn interleaved RGBA pixels into vectors of each color component.\n\nFor example, with 32-bit lanes, memory laid out as`[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]` loads as`[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]`."]
2277    #[doc(alias = "load_interleaved")]
2278    fn load_four_interleaved_u64x2(self, src: &[u64; 8usize]) -> [u64x2<Self>; 4usize];
2279    #[doc = "Store four 128-bit vectors to an array with 4-way interleaving.\n\nThis is the inverse of `load_four_interleaved`.\n\nThis is useful e.g. in image processing to turn vectors of each color component into interleaved RGBA pixels.\n\nFor example, with 32-bit lanes, vectors containing `[[r0, r1, r2, r3], [g0, g1, g2, g3], [b0, b1, b2, b3], [a0, a1, a2, a3]]` get stored as `[r0, g0, b0, a0, r1, g1, b1, a1, r2, g2, b2, a2, r3, g3, b3, a3]`."]
2280    #[doc(alias = "store_interleaved")]
2281    fn store_four_interleaved_u64x2(
2282        self,
2283        vectors: [u64x2<Self>; 4usize],
2284        dest: &mut [u64; 8usize],
2285    ) -> ();
2286    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
2287    fn narrow_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u32x4<Self>;
2288    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
2289    fn saturating_narrow_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u32x4<Self>;
2290    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
2291    fn relaxed_narrow_u64x2(self, a: u64x2<Self>, b: u64x2<Self>) -> u32x4<Self>;
2292    #[doc = "Convert each unsigned 64-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
2293    fn cvt_f64_u64x2(self, a: u64x2<Self>) -> f64x2<Self>;
2294    #[doc = "Create a SIMD mask with all lanes set from the given boolean value."]
2295    fn splat_mask64x2(self, val: bool) -> mask64x2<Self>;
2296    #[doc = "Create a SIMD mask from a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are ignored."]
2297    fn from_bitmask_mask64x2(self, bits: u64) -> mask64x2<Self>;
2298    #[doc = "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared."]
2299    fn to_bitmask_mask64x2(self, a: mask64x2<Self>) -> u64;
2300    #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."]
2301    fn from_vector_mask64x2(self, vector: i64x2<Self>) -> mask64x2<Self>;
2302    #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."]
2303    fn to_vector_mask64x2(self, a: mask64x2<Self>) -> i64x2<Self>;
2304    #[doc = "Set one logical lane of a SIMD mask."]
2305    fn set_mask64x2(self, a: &mut mask64x2<Self>, index: usize, value: bool) -> ();
2306    #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
2307    fn rotate_elements_left_mask64x2<const OFFSET: usize>(
2308        self,
2309        a: mask64x2<Self>,
2310    ) -> mask64x2<Self>;
2311    #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
2312    fn rotate_elements_right_mask64x2<const OFFSET: usize>(
2313        self,
2314        a: mask64x2<Self>,
2315    ) -> mask64x2<Self>;
2316    #[doc = "Compute the logical AND of two masks."]
2317    fn and_mask64x2(self, a: mask64x2<Self>, b: mask64x2<Self>) -> mask64x2<Self>;
2318    #[doc = "Compute the logical OR of two masks."]
2319    fn or_mask64x2(self, a: mask64x2<Self>, b: mask64x2<Self>) -> mask64x2<Self>;
2320    #[doc = "Compute the logical XOR of two masks."]
2321    fn xor_mask64x2(self, a: mask64x2<Self>, b: mask64x2<Self>) -> mask64x2<Self>;
2322    #[doc = "Compute the logical NOT of the mask."]
2323    fn not_mask64x2(self, a: mask64x2<Self>) -> mask64x2<Self>;
2324    #[doc = "Reverse the order of the mask's logical lanes."]
2325    fn reverse_mask64x2(self, a: mask64x2<Self>) -> mask64x2<Self>;
2326    #[doc = "Select elements from `b` and `c` based on the mask operand `a`.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
2327    fn select_mask64x2(
2328        self,
2329        a: mask64x2<Self>,
2330        b: mask64x2<Self>,
2331        c: mask64x2<Self>,
2332    ) -> mask64x2<Self>;
2333    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
2334    fn simd_eq_mask64x2(self, a: mask64x2<Self>, b: mask64x2<Self>) -> mask64x2<Self>;
2335    #[doc = "Compare two masks element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
2336    #[inline(always)]
2337    fn simd_ne_mask64x2(self, a: mask64x2<Self>, b: mask64x2<Self>) -> mask64x2<Self> {
2338        self.not_mask64x2(self.simd_eq_mask64x2(a, b))
2339    }
2340    #[doc = "Returns true if any logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
2341    fn any_true_mask64x2(self, a: mask64x2<Self>) -> bool;
2342    #[doc = "Returns true if all logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
2343    fn all_true_mask64x2(self, a: mask64x2<Self>) -> bool;
2344    #[doc = "Returns true if any logical lanes in this mask are false.\n\nThis is logically equivalent to `!all_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
2345    fn any_false_mask64x2(self, a: mask64x2<Self>) -> bool;
2346    #[doc = "Returns true if all logical lanes in this mask are false.\n\nThis is logically equivalent to `!any_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
2347    fn all_false_mask64x2(self, a: mask64x2<Self>) -> bool;
2348    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
2349    fn combine_mask64x2(self, a: mask64x2<Self>, b: mask64x2<Self>) -> mask64x4<Self>;
2350    #[doc = "Narrow each boolean lane of two masks and concatenate them into one mask of the same logical width, preserving each value.\n\n`a` supplies the lower result lanes and `b` supplies the upper result lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
2351    fn narrow_mask64x2(self, a: mask64x2<Self>, b: mask64x2<Self>) -> mask32x4<Self>;
2352    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
2353    #[inline(always)]
2354    fn abs_f32x8(self, a: f32x8<Self>) -> f32x8<Self> {
2355        let (a0, a1) = self.split_f32x8(a);
2356        self.combine_f32x4(self.abs_f32x4(a0), self.abs_f32x4(a1))
2357    }
2358    #[doc = "Create a SIMD vector with all elements set to the given value."]
2359    #[inline(always)]
2360    fn splat_f32x8(self, val: f32) -> f32x8<Self> {
2361        let half = self.splat_f32x4(val);
2362        self.combine_f32x4(half, half)
2363    }
2364    #[doc = "Reverse the order of the vector's elements."]
2365    #[inline(always)]
2366    fn reverse_f32x8(self, a: f32x8<Self>) -> f32x8<Self> {
2367        let (a0, a1) = self.split_f32x8(a);
2368        self.combine_f32x4(self.reverse_f32x4(a1), self.reverse_f32x4(a0))
2369    }
2370    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
2371    fn slide_f32x8<const SHIFT: usize>(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x8<Self>;
2372    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
2373    #[inline(always)]
2374    fn slide_within_blocks_f32x8<const SHIFT: usize>(
2375        self,
2376        a: f32x8<Self>,
2377        b: f32x8<Self>,
2378    ) -> f32x8<Self> {
2379        let (a0, a1) = self.split_f32x8(a);
2380        let (b0, b1) = self.split_f32x8(b);
2381        self.combine_f32x4(
2382            self.slide_within_blocks_f32x4::<SHIFT>(a0, b0),
2383            self.slide_within_blocks_f32x4::<SHIFT>(a1, b1),
2384        )
2385    }
2386    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
2387    #[inline(always)]
2388    fn swizzle_dyn_within_blocks_f32x8(self, a: f32x8<Self>, indices: u8x32<Self>) -> f32x8<Self> {
2389        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x32(Bytes::to_bytes(a), indices))
2390    }
2391    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
2392    #[inline(always)]
2393    fn swizzle_dyn_f32x8(self, a: f32x8<Self>, indices: u8x32<Self>) -> f32x8<Self> {
2394        Bytes::from_bytes(self.swizzle_dyn_u8x32(Bytes::to_bytes(a), indices))
2395    }
2396    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
2397    #[inline(always)]
2398    fn swizzle_dyn_precise_f32x8(self, a: f32x8<Self>, indices: u8x32<Self>) -> f32x8<Self> {
2399        Bytes::from_bytes(self.swizzle_dyn_precise_u8x32(Bytes::to_bytes(a), indices))
2400    }
2401    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
2402    #[inline(always)]
2403    fn concat_swizzle_dyn_f32x8(
2404        self,
2405        a: f32x8<Self>,
2406        b: f32x8<Self>,
2407        indices: u8x32<Self>,
2408    ) -> f32x8<Self> {
2409        Bytes::from_bytes(self.concat_swizzle_dyn_u8x32(
2410            Bytes::to_bytes(a),
2411            Bytes::to_bytes(b),
2412            indices,
2413        ))
2414    }
2415    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
2416    #[inline(always)]
2417    fn concat_swizzle_dyn_precise_f32x8(
2418        self,
2419        a: f32x8<Self>,
2420        b: f32x8<Self>,
2421        indices: u8x32<Self>,
2422    ) -> f32x8<Self> {
2423        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x32(
2424            Bytes::to_bytes(a),
2425            Bytes::to_bytes(b),
2426            indices,
2427        ))
2428    }
2429    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
2430    fn compress_f32x8(self, values: f32x8<Self>, mask: mask32x8<Self>) -> f32x8<Self>;
2431    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
2432    fn compress_merge_f32x8(
2433        self,
2434        values: f32x8<Self>,
2435        mask: mask32x8<Self>,
2436        merge: f32x8<Self>,
2437    ) -> f32x8<Self>;
2438    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
2439    fn expand_f32x8(self, values: f32x8<Self>, mask: mask32x8<Self>) -> f32x8<Self>;
2440    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
2441    fn expand_merge_f32x8(
2442        self,
2443        values: f32x8<Self>,
2444        mask: mask32x8<Self>,
2445        merge: f32x8<Self>,
2446    ) -> f32x8<Self>;
2447    #[doc = "Negate each element of the vector."]
2448    #[inline(always)]
2449    fn neg_f32x8(self, a: f32x8<Self>) -> f32x8<Self> {
2450        let (a0, a1) = self.split_f32x8(a);
2451        self.combine_f32x4(self.neg_f32x4(a0), self.neg_f32x4(a1))
2452    }
2453    #[doc = "Compute the square root of each element.\n\nNegative elements other than `-0.0` will become NaN."]
2454    #[inline(always)]
2455    fn sqrt_f32x8(self, a: f32x8<Self>) -> f32x8<Self> {
2456        let (a0, a1) = self.split_f32x8(a);
2457        self.combine_f32x4(self.sqrt_f32x4(a0), self.sqrt_f32x4(a1))
2458    }
2459    #[doc = "Compute an approximate reciprocal (`1. / x`) for each element.\n\nThis uses a fast hardware estimate where available, and falls back to exact division otherwise.\n\nOn x86 for `f32`, this has a relative error less than `1.5 × 2^-12`. On `AArch64` (`f32` and `f64`), this has a relative error less than `2^-8`. The precision of this operation may change as new platform support is added."]
2460    #[inline(always)]
2461    fn approximate_recip_f32x8(self, a: f32x8<Self>) -> f32x8<Self> {
2462        let (a0, a1) = self.split_f32x8(a);
2463        self.combine_f32x4(
2464            self.approximate_recip_f32x4(a0),
2465            self.approximate_recip_f32x4(a1),
2466        )
2467    }
2468    #[doc = "Add two vectors element-wise."]
2469    #[inline(always)]
2470    fn add_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x8<Self> {
2471        let (a0, a1) = self.split_f32x8(a);
2472        let (b0, b1) = self.split_f32x8(b);
2473        self.combine_f32x4(self.add_f32x4(a0, b0), self.add_f32x4(a1, b1))
2474    }
2475    #[doc = "Subtract two vectors element-wise."]
2476    #[inline(always)]
2477    fn sub_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x8<Self> {
2478        let (a0, a1) = self.split_f32x8(a);
2479        let (b0, b1) = self.split_f32x8(b);
2480        self.combine_f32x4(self.sub_f32x4(a0, b0), self.sub_f32x4(a1, b1))
2481    }
2482    #[doc = "Multiply two vectors element-wise."]
2483    #[inline(always)]
2484    fn mul_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x8<Self> {
2485        let (a0, a1) = self.split_f32x8(a);
2486        let (b0, b1) = self.split_f32x8(b);
2487        self.combine_f32x4(self.mul_f32x4(a0, b0), self.mul_f32x4(a1, b1))
2488    }
2489    #[doc = "Divide two vectors element-wise."]
2490    #[inline(always)]
2491    fn div_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x8<Self> {
2492        let (a0, a1) = self.split_f32x8(a);
2493        let (b0, b1) = self.split_f32x8(b);
2494        self.combine_f32x4(self.div_f32x4(a0, b0), self.div_f32x4(a1, b1))
2495    }
2496    #[doc = "Return a vector with the magnitude of `a` and the sign of `b` for each element.\n\nThis operation copies the sign bit, so if an input element is NaN, the output element will be a NaN with the same payload and a copied sign bit."]
2497    #[inline(always)]
2498    fn copysign_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x8<Self> {
2499        let (a0, a1) = self.split_f32x8(a);
2500        let (b0, b1) = self.split_f32x8(b);
2501        self.combine_f32x4(self.copysign_f32x4(a0, b0), self.copysign_f32x4(a1, b1))
2502    }
2503    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
2504    #[inline(always)]
2505    fn reduce_max_f32x8(self, a: f32x8<Self>) -> f32 {
2506        let (a0, a1) = self.split_f32x8(a);
2507        self.reduce_max_f32x4(self.max_f32x4(a0, a1))
2508    }
2509    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
2510    #[inline(always)]
2511    fn reduce_min_f32x8(self, a: f32x8<Self>) -> f32 {
2512        let (a0, a1) = self.split_f32x8(a);
2513        self.reduce_min_f32x4(self.min_f32x4(a0, a1))
2514    }
2515    #[doc = "Return the maximum element in the vector, ignoring quiet NaNs.\n\nFor integer vectors, this operation is the same as `reduce_max`.\n\nFor floating-point vectors, quiet NaNs are ignored. If there is at least one numeric lane, this returns the true maximum of the numeric lanes. If all lanes are quiet NaNs, this returns NaN, with an unspecified payload and sign.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned.\n\nIf any lane is a *signaling* NaN, the result is fully non-deterministic: it may be NaN or a numeric lane and is not guaranteed to be the true maximum.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
2516    #[inline(always)]
2517    fn reduce_max_precise_f32x8(self, a: f32x8<Self>) -> f32 {
2518        let (a0, a1) = self.split_f32x8(a);
2519        self.reduce_max_precise_f32x4(self.max_precise_f32x4(a0, a1))
2520    }
2521    #[doc = "Return the minimum element in the vector, ignoring quiet NaNs.\n\nFor integer vectors, this operation is the same as `reduce_min`.\n\nFor floating-point vectors, quiet NaNs are ignored. If there is at least one numeric lane, this returns the true minimum of the numeric lanes. If all lanes are quiet NaNs, this returns NaN, with an unspecified payload and sign.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned.\n\nIf any lane is a *signaling* NaN, the result is fully non-deterministic: it may be NaN or a numeric lane and is not guaranteed to be the true minimum.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
2522    #[inline(always)]
2523    fn reduce_min_precise_f32x8(self, a: f32x8<Self>) -> f32 {
2524        let (a0, a1) = self.split_f32x8(a);
2525        self.reduce_min_precise_f32x4(self.min_precise_f32x4(a0, a1))
2526    }
2527    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
2528    #[inline(always)]
2529    fn reduce_sum_f32x8(self, a: f32x8<Self>) -> f32 {
2530        let (a0, a1) = self.split_f32x8(a);
2531        self.reduce_sum_f32x4(self.add_f32x4(a0, a1))
2532    }
2533    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
2534    #[inline(always)]
2535    fn reduce_product_f32x8(self, a: f32x8<Self>) -> f32 {
2536        let (a0, a1) = self.split_f32x8(a);
2537        self.reduce_product_f32x4(self.mul_f32x4(a0, a1))
2538    }
2539    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
2540    #[inline(always)]
2541    fn max_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x8<Self> {
2542        let (a0, a1) = self.split_f32x8(a);
2543        let (b0, b1) = self.split_f32x8(b);
2544        self.combine_f32x4(self.max_f32x4(a0, b0), self.max_f32x4(a1, b1))
2545    }
2546    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
2547    #[inline(always)]
2548    fn min_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x8<Self> {
2549        let (a0, a1) = self.split_f32x8(a);
2550        let (b0, b1) = self.split_f32x8(b);
2551        self.combine_f32x4(self.min_f32x4(a0, b0), self.min_f32x4(a1, b1))
2552    }
2553    #[doc = "Return the element-wise maximum of two vectors.\n\nFor integer vectors, this operation is the same as `max`.\n\nFor floating-point vectors, if one operand is a quiet NaN and the other is not, this operation will choose the non-NaN operand.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\nIf a floating-point operand is a *signaling* NaN, the result is not just implementation-defined, but fully non-deterministic: it may be either NaN or the non-NaN operand.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
2554    #[inline(always)]
2555    fn max_precise_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x8<Self> {
2556        let (a0, a1) = self.split_f32x8(a);
2557        let (b0, b1) = self.split_f32x8(b);
2558        self.combine_f32x4(
2559            self.max_precise_f32x4(a0, b0),
2560            self.max_precise_f32x4(a1, b1),
2561        )
2562    }
2563    #[doc = "Return the element-wise minimum of two vectors.\n\nFor integer vectors, this operation is the same as `min`.\n\nFor floating-point vectors, if one operand is a quiet NaN and the other is not, this operation will choose the non-NaN operand.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\nIf a floating-point operand is a *signaling* NaN, the result is not just implementation-defined, but fully non-deterministic: it may be either NaN or the non-NaN operand.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
2564    #[inline(always)]
2565    fn min_precise_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x8<Self> {
2566        let (a0, a1) = self.split_f32x8(a);
2567        let (b0, b1) = self.split_f32x8(b);
2568        self.combine_f32x4(
2569            self.min_precise_f32x4(a0, b0),
2570            self.min_precise_f32x4(a1, b1),
2571        )
2572    }
2573    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
2574    #[inline(always)]
2575    fn clamp_f32x8(self, a: f32x8<Self>, b: f32x8<Self>, c: f32x8<Self>) -> f32x8<Self> {
2576        let (a0, a1) = self.split_f32x8(a);
2577        let (b0, b1) = self.split_f32x8(b);
2578        let (c0, c1) = self.split_f32x8(c);
2579        self.combine_f32x4(self.clamp_f32x4(a0, b0, c0), self.clamp_f32x4(a1, b1, c1))
2580    }
2581    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
2582    #[inline(always)]
2583    fn simd_eq_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> mask32x8<Self> {
2584        let (a0, a1) = self.split_f32x8(a);
2585        let (b0, b1) = self.split_f32x8(b);
2586        self.combine_mask32x4(self.simd_eq_f32x4(a0, b0), self.simd_eq_f32x4(a1, b1))
2587    }
2588    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
2589    #[inline(always)]
2590    fn simd_ne_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> mask32x8<Self> {
2591        self.not_mask32x8(self.simd_eq_f32x8(a, b))
2592    }
2593    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
2594    #[inline(always)]
2595    fn simd_lt_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> mask32x8<Self> {
2596        let (a0, a1) = self.split_f32x8(a);
2597        let (b0, b1) = self.split_f32x8(b);
2598        self.combine_mask32x4(self.simd_lt_f32x4(a0, b0), self.simd_lt_f32x4(a1, b1))
2599    }
2600    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
2601    #[inline(always)]
2602    fn simd_le_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> mask32x8<Self> {
2603        let (a0, a1) = self.split_f32x8(a);
2604        let (b0, b1) = self.split_f32x8(b);
2605        self.combine_mask32x4(self.simd_le_f32x4(a0, b0), self.simd_le_f32x4(a1, b1))
2606    }
2607    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
2608    #[inline(always)]
2609    fn simd_ge_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> mask32x8<Self> {
2610        self.simd_le_f32x8(b, a)
2611    }
2612    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
2613    #[inline(always)]
2614    fn simd_gt_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> mask32x8<Self> {
2615        self.simd_lt_f32x8(b, a)
2616    }
2617    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
2618    #[inline(always)]
2619    fn zip_low_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x8<Self> {
2620        let (a0, _) = self.split_f32x8(a);
2621        let (b0, _) = self.split_f32x8(b);
2622        self.combine_f32x4(self.zip_low_f32x4(a0, b0), self.zip_high_f32x4(a0, b0))
2623    }
2624    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
2625    #[inline(always)]
2626    fn zip_high_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x8<Self> {
2627        let (_, a1) = self.split_f32x8(a);
2628        let (_, b1) = self.split_f32x8(b);
2629        self.combine_f32x4(self.zip_low_f32x4(a1, b1), self.zip_high_f32x4(a1, b1))
2630    }
2631    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
2632    #[inline(always)]
2633    fn unzip_low_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x8<Self> {
2634        let (a0, a1) = self.split_f32x8(a);
2635        let (b0, b1) = self.split_f32x8(b);
2636        self.combine_f32x4(self.unzip_low_f32x4(a0, a1), self.unzip_low_f32x4(b0, b1))
2637    }
2638    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
2639    #[inline(always)]
2640    fn unzip_high_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x8<Self> {
2641        let (a0, a1) = self.split_f32x8(a);
2642        let (b0, b1) = self.split_f32x8(b);
2643        self.combine_f32x4(self.unzip_high_f32x4(a0, a1), self.unzip_high_f32x4(b0, b1))
2644    }
2645    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
2646    #[inline(always)]
2647    fn interleave_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> (f32x8<Self>, f32x8<Self>) {
2648        let (a0, a1) = self.split_f32x8(a);
2649        let (b0, b1) = self.split_f32x8(b);
2650        let lo_lo = self.zip_low_f32x4(a0, b0);
2651        let lo_hi = self.zip_high_f32x4(a0, b0);
2652        let hi_lo = self.zip_low_f32x4(a1, b1);
2653        let hi_hi = self.zip_high_f32x4(a1, b1);
2654        (
2655            self.combine_f32x4(lo_lo, lo_hi),
2656            self.combine_f32x4(hi_lo, hi_hi),
2657        )
2658    }
2659    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
2660    #[inline(always)]
2661    fn deinterleave_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> (f32x8<Self>, f32x8<Self>) {
2662        let (a0, a1) = self.split_f32x8(a);
2663        let (b0, b1) = self.split_f32x8(b);
2664        let lo_even = self.unzip_low_f32x4(a0, a1);
2665        let lo_odd = self.unzip_high_f32x4(a0, a1);
2666        let hi_even = self.unzip_low_f32x4(b0, b1);
2667        let hi_odd = self.unzip_high_f32x4(b0, b1);
2668        (
2669            self.combine_f32x4(lo_even, hi_even),
2670            self.combine_f32x4(lo_odd, hi_odd),
2671        )
2672    }
2673    #[doc = "Compute `(a * b) + c` (fused multiply-add) for each element.\n\nDepending on platform support, the result may be computed with only one rounding error, or may be implemented as a regular multiply followed by an add, which will result in two rounding errors."]
2674    #[inline(always)]
2675    fn mul_add_f32x8(self, a: f32x8<Self>, b: f32x8<Self>, c: f32x8<Self>) -> f32x8<Self> {
2676        let (a0, a1) = self.split_f32x8(a);
2677        let (b0, b1) = self.split_f32x8(b);
2678        let (c0, c1) = self.split_f32x8(c);
2679        self.combine_f32x4(
2680            self.mul_add_f32x4(a0, b0, c0),
2681            self.mul_add_f32x4(a1, b1, c1),
2682        )
2683    }
2684    #[doc = "Compute `(a * b) + c` for each element, with a single rounding at the end.\n\nThe result is the infinite-precision product-plus-add rounded once to the element type. This may be substantially slower than `mul_add` on platforms without fused multiply-add instructions, including WebAssembly.\n\n# Precision guarantees\n\nThis function is **not** susceptible to [the bug](https://github.com/rust-lang/compiler-builtins/issues/1262) in Rust standard library and in musl libc that causes incorrect rounding for near-zero values on CPUs without hardware support for this operation.\n\nOn the tier-2 i586-* targets, this function is correct if and only if SSE2 is available on the CPU.\n\nThe exact `NaN` payloads as well as signaling `NaN`s are not preserved."]
2685    #[inline(always)]
2686    fn mul_add_precise_f32x8(self, a: f32x8<Self>, b: f32x8<Self>, c: f32x8<Self>) -> f32x8<Self> {
2687        let (a0, a1) = self.split_f32x8(a);
2688        let (b0, b1) = self.split_f32x8(b);
2689        let (c0, c1) = self.split_f32x8(c);
2690        self.combine_f32x4(
2691            self.mul_add_precise_f32x4(a0, b0, c0),
2692            self.mul_add_precise_f32x4(a1, b1, c1),
2693        )
2694    }
2695    #[doc = "Compute `(a * b) - c` (fused multiply-subtract) for each element.\n\nDepending on platform support, the result may be computed with only one rounding error, or may be implemented as a regular multiply followed by a subtract, which will result in two rounding errors."]
2696    #[inline(always)]
2697    fn mul_sub_f32x8(self, a: f32x8<Self>, b: f32x8<Self>, c: f32x8<Self>) -> f32x8<Self> {
2698        let (a0, a1) = self.split_f32x8(a);
2699        let (b0, b1) = self.split_f32x8(b);
2700        let (c0, c1) = self.split_f32x8(c);
2701        self.combine_f32x4(
2702            self.mul_sub_f32x4(a0, b0, c0),
2703            self.mul_sub_f32x4(a1, b1, c1),
2704        )
2705    }
2706    #[doc = "Compute `(a * b) - c` for each element, with a single rounding at the end.\n\nThe result is the infinite-precision product-minus-subtrahend rounded once to the element type. This may be substantially slower than `mul_sub` on platforms without fused multiply-add instructions, including WebAssembly.\n        # Precision guarantees\n\nThis function is **not** susceptible to [the bug](https://github.com/rust-lang/compiler-builtins/issues/1262) in Rust standard library and in musl libc that causes incorrect rounding for near-zero values on CPUs without hardware support for this operation.\n\nOn the tier-2 i586-* targets, this function is correct if and only if SSE2 is available on the CPU.\n\nThe exact `NaN` payloads as well as signaling `NaN`s are not preserved."]
2707    #[inline(always)]
2708    fn mul_sub_precise_f32x8(self, a: f32x8<Self>, b: f32x8<Self>, c: f32x8<Self>) -> f32x8<Self> {
2709        let (a0, a1) = self.split_f32x8(a);
2710        let (b0, b1) = self.split_f32x8(b);
2711        let (c0, c1) = self.split_f32x8(c);
2712        self.combine_f32x4(
2713            self.mul_sub_precise_f32x4(a0, b0, c0),
2714            self.mul_sub_precise_f32x4(a1, b1, c1),
2715        )
2716    }
2717    #[doc = "Return the largest integer less than or equal to each element, that is, round towards negative infinity."]
2718    #[inline(always)]
2719    fn floor_f32x8(self, a: f32x8<Self>) -> f32x8<Self> {
2720        let (a0, a1) = self.split_f32x8(a);
2721        self.combine_f32x4(self.floor_f32x4(a0), self.floor_f32x4(a1))
2722    }
2723    #[doc = "Return the smallest integer greater than or equal to each element, that is, round towards positive infinity."]
2724    #[inline(always)]
2725    fn ceil_f32x8(self, a: f32x8<Self>) -> f32x8<Self> {
2726        let (a0, a1) = self.split_f32x8(a);
2727        self.combine_f32x4(self.ceil_f32x4(a0), self.ceil_f32x4(a1))
2728    }
2729    #[doc = "Round each element to the nearest integer, with ties rounding to the nearest even integer."]
2730    #[inline(always)]
2731    fn round_ties_even_f32x8(self, a: f32x8<Self>) -> f32x8<Self> {
2732        let (a0, a1) = self.split_f32x8(a);
2733        self.combine_f32x4(
2734            self.round_ties_even_f32x4(a0),
2735            self.round_ties_even_f32x4(a1),
2736        )
2737    }
2738    #[doc = "Round each element to the nearest integer, with ties rounding away from zero.\n\n## Performance considerations\n\nOnly `AArch64` has native instructions for this operation. `round` has to be emulated on all other platforms which is around 2-4x slower than `round_ties_even`. Prefer using [`round_ties_even`](SimdFloat::round_ties_even) if possible."]
2739    #[inline(always)]
2740    fn round_f32x8(self, a: f32x8<Self>) -> f32x8<Self> {
2741        let (a0, a1) = self.split_f32x8(a);
2742        self.combine_f32x4(self.round_f32x4(a0), self.round_f32x4(a1))
2743    }
2744    #[doc = "Return the fractional part of each element.\n\nThis is equivalent to `a - a.trunc()`."]
2745    #[inline(always)]
2746    fn fract_f32x8(self, a: f32x8<Self>) -> f32x8<Self> {
2747        let (a0, a1) = self.split_f32x8(a);
2748        self.combine_f32x4(self.fract_f32x4(a0), self.fract_f32x4(a1))
2749    }
2750    #[doc = "Return the integer part of each element, rounding towards zero."]
2751    #[inline(always)]
2752    fn trunc_f32x8(self, a: f32x8<Self>) -> f32x8<Self> {
2753        let (a0, a1) = self.split_f32x8(a);
2754        self.combine_f32x4(self.trunc_f32x4(a0), self.trunc_f32x4(a1))
2755    }
2756    #[doc = "Converts radians to degrees.\n\nThe precision of this function is non-deterministic. This means it varies by platform, Rust version, and can even differ within the same execution from one invocation to the next."]
2757    #[inline(always)]
2758    fn to_degrees_f32x8(self, a: f32x8<Self>) -> f32x8<Self> {
2759        let (a0, a1) = self.split_f32x8(a);
2760        self.combine_f32x4(self.to_degrees_f32x4(a0), self.to_degrees_f32x4(a1))
2761    }
2762    #[doc = "Converts degrees to radians.\n\nThe precision of this function is non-deterministic. This means it varies by platform, Rust version, and can even differ within the same execution from one invocation to the next."]
2763    #[inline(always)]
2764    fn to_radians_f32x8(self, a: f32x8<Self>) -> f32x8<Self> {
2765        let (a0, a1) = self.split_f32x8(a);
2766        self.combine_f32x4(self.to_radians_f32x4(a0), self.to_radians_f32x4(a1))
2767    }
2768    #[doc = "Return a mask indicating which elements are NaN."]
2769    fn is_nan_f32x8(self, a: f32x8<Self>) -> mask32x8<Self>;
2770    #[doc = "Return a mask indicating which elements are positive or negative infinite."]
2771    fn is_infinite_f32x8(self, a: f32x8<Self>) -> mask32x8<Self>;
2772    #[doc = "Return a mask indicating which elements are neither infinite nor NaN."]
2773    fn is_finite_f32x8(self, a: f32x8<Self>) -> mask32x8<Self>;
2774    #[doc = "Return a mask indicating which elements are subnormal.\n\nThis classifies the stored bit pattern, even when floating-point operations treat subnormals as zero."]
2775    fn is_subnormal_f32x8(self, a: f32x8<Self>) -> mask32x8<Self>;
2776    #[doc = "Return a mask indicating which elements are neither zero, infinite, subnormal, or NaN."]
2777    fn is_normal_f32x8(self, a: f32x8<Self>) -> mask32x8<Self>;
2778    #[doc = "Return a mask indicating which elements have a positive sign, including `+0.0`, NaNs with positive sign bit and positive infinity.\n\nNaN inputs may produce an unexpected or non-portable result, see [`f32::is_sign_positive`] for details."]
2779    fn is_sign_positive_f32x8(self, a: f32x8<Self>) -> mask32x8<Self>;
2780    #[doc = "Return a mask indicating which elements have a negative sign, including `-0.0`, NaNs with negative sign bit and negative infinity.\n\nNaN inputs may produce an unexpected or non-portable result, see [`f32::is_sign_negative`] for details."]
2781    fn is_sign_negative_f32x8(self, a: f32x8<Self>) -> mask32x8<Self>;
2782    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
2783    #[inline(always)]
2784    fn select_f32x8(self, a: mask32x8<Self>, b: f32x8<Self>, c: f32x8<Self>) -> f32x8<Self> {
2785        let (a0, a1) = self.split_mask32x8(a);
2786        let (b0, b1) = self.split_f32x8(b);
2787        let (c0, c1) = self.split_f32x8(c);
2788        self.combine_f32x4(self.select_f32x4(a0, b0, c0), self.select_f32x4(a1, b1, c1))
2789    }
2790    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
2791    fn combine_f32x8(self, a: f32x8<Self>, b: f32x8<Self>) -> f32x16<Self>;
2792    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
2793    fn split_f32x8(self, a: f32x8<Self>) -> (f32x4<Self>, f32x4<Self>);
2794    #[doc = "Widen every `f32` lane exactly into two same-width `f64` vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
2795    #[inline(always)]
2796    fn widen_f32x8(self, a: f32x8<Self>) -> (f64x4<Self>, f64x4<Self>) {
2797        let (a0, a1) = self.split_f32x8(a);
2798        let (a00, a01) = self.widen_f32x4(a0);
2799        let (a10, a11) = self.widen_f32x4(a1);
2800        (self.combine_f64x2(a00, a01), self.combine_f64x2(a10, a11))
2801    }
2802    #[doc = "Convert each floating-point element to an unsigned 32-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results.\n\nOn x86 platforms below AVX-512, this operation will still be slower than converting to `i32`, because there is no native instruction for converting to `u32`.\nIf you know your values fit within range of an `i32`, you should convert to an `i32` and cast to your desired datatype afterwards."]
2803    #[inline(always)]
2804    fn cvt_u32_f32x8(self, a: f32x8<Self>) -> u32x8<Self> {
2805        let (a0, a1) = self.split_f32x8(a);
2806        self.combine_u32x4(self.cvt_u32_f32x4(a0), self.cvt_u32_f32x4(a1))
2807    }
2808    #[doc = "Convert each floating-point element to an unsigned 32-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
2809    #[inline(always)]
2810    fn cvt_u32_precise_f32x8(self, a: f32x8<Self>) -> u32x8<Self> {
2811        let (a0, a1) = self.split_f32x8(a);
2812        self.combine_u32x4(
2813            self.cvt_u32_precise_f32x4(a0),
2814            self.cvt_u32_precise_f32x4(a1),
2815        )
2816    }
2817    #[doc = "Convert each floating-point element to a signed 32-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
2818    #[inline(always)]
2819    fn cvt_i32_f32x8(self, a: f32x8<Self>) -> i32x8<Self> {
2820        let (a0, a1) = self.split_f32x8(a);
2821        self.combine_i32x4(self.cvt_i32_f32x4(a0), self.cvt_i32_f32x4(a1))
2822    }
2823    #[doc = "Convert each floating-point element to a signed 32-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
2824    #[inline(always)]
2825    fn cvt_i32_precise_f32x8(self, a: f32x8<Self>) -> i32x8<Self> {
2826        let (a0, a1) = self.split_f32x8(a);
2827        self.combine_i32x4(
2828            self.cvt_i32_precise_f32x4(a0),
2829            self.cvt_i32_precise_f32x4(a1),
2830        )
2831    }
2832    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
2833    #[inline(always)]
2834    fn abs_i8x32(self, a: i8x32<Self>) -> i8x32<Self> {
2835        let (a0, a1) = self.split_i8x32(a);
2836        self.combine_i8x16(self.abs_i8x16(a0), self.abs_i8x16(a1))
2837    }
2838    #[doc = "Create a SIMD vector with all elements set to the given value."]
2839    #[inline(always)]
2840    fn splat_i8x32(self, val: i8) -> i8x32<Self> {
2841        let half = self.splat_i8x16(val);
2842        self.combine_i8x16(half, half)
2843    }
2844    #[doc = "Reverse the order of the vector's elements."]
2845    #[inline(always)]
2846    fn reverse_i8x32(self, a: i8x32<Self>) -> i8x32<Self> {
2847        let (a0, a1) = self.split_i8x32(a);
2848        self.combine_i8x16(self.reverse_i8x16(a1), self.reverse_i8x16(a0))
2849    }
2850    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
2851    fn slide_i8x32<const SHIFT: usize>(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self>;
2852    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
2853    #[inline(always)]
2854    fn slide_within_blocks_i8x32<const SHIFT: usize>(
2855        self,
2856        a: i8x32<Self>,
2857        b: i8x32<Self>,
2858    ) -> i8x32<Self> {
2859        let (a0, a1) = self.split_i8x32(a);
2860        let (b0, b1) = self.split_i8x32(b);
2861        self.combine_i8x16(
2862            self.slide_within_blocks_i8x16::<SHIFT>(a0, b0),
2863            self.slide_within_blocks_i8x16::<SHIFT>(a1, b1),
2864        )
2865    }
2866    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
2867    #[inline(always)]
2868    fn swizzle_dyn_within_blocks_i8x32(self, a: i8x32<Self>, indices: u8x32<Self>) -> i8x32<Self> {
2869        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x32(Bytes::to_bytes(a), indices))
2870    }
2871    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
2872    #[inline(always)]
2873    fn swizzle_dyn_i8x32(self, a: i8x32<Self>, indices: u8x32<Self>) -> i8x32<Self> {
2874        Bytes::from_bytes(self.swizzle_dyn_u8x32(Bytes::to_bytes(a), indices))
2875    }
2876    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
2877    #[inline(always)]
2878    fn swizzle_dyn_precise_i8x32(self, a: i8x32<Self>, indices: u8x32<Self>) -> i8x32<Self> {
2879        Bytes::from_bytes(self.swizzle_dyn_precise_u8x32(Bytes::to_bytes(a), indices))
2880    }
2881    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
2882    #[inline(always)]
2883    fn concat_swizzle_dyn_i8x32(
2884        self,
2885        a: i8x32<Self>,
2886        b: i8x32<Self>,
2887        indices: u8x32<Self>,
2888    ) -> i8x32<Self> {
2889        Bytes::from_bytes(self.concat_swizzle_dyn_u8x32(
2890            Bytes::to_bytes(a),
2891            Bytes::to_bytes(b),
2892            indices,
2893        ))
2894    }
2895    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
2896    #[inline(always)]
2897    fn concat_swizzle_dyn_precise_i8x32(
2898        self,
2899        a: i8x32<Self>,
2900        b: i8x32<Self>,
2901        indices: u8x32<Self>,
2902    ) -> i8x32<Self> {
2903        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x32(
2904            Bytes::to_bytes(a),
2905            Bytes::to_bytes(b),
2906            indices,
2907        ))
2908    }
2909    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
2910    fn compress_i8x32(self, values: i8x32<Self>, mask: mask8x32<Self>) -> i8x32<Self>;
2911    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
2912    fn compress_merge_i8x32(
2913        self,
2914        values: i8x32<Self>,
2915        mask: mask8x32<Self>,
2916        merge: i8x32<Self>,
2917    ) -> i8x32<Self>;
2918    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
2919    fn expand_i8x32(self, values: i8x32<Self>, mask: mask8x32<Self>) -> i8x32<Self>;
2920    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
2921    fn expand_merge_i8x32(
2922        self,
2923        values: i8x32<Self>,
2924        mask: mask8x32<Self>,
2925        merge: i8x32<Self>,
2926    ) -> i8x32<Self>;
2927    #[doc = "Return the number of ones in the binary representation of each element."]
2928    #[inline(always)]
2929    fn count_ones_i8x32(self, a: i8x32<Self>) -> i8x32<Self> {
2930        let (a0, a1) = self.split_i8x32(a);
2931        self.combine_i8x16(self.count_ones_i8x16(a0), self.count_ones_i8x16(a1))
2932    }
2933    #[doc = "Return the number of zeros in the binary representation of each element."]
2934    #[inline(always)]
2935    fn count_zeros_i8x32(self, a: i8x32<Self>) -> i8x32<Self> {
2936        let (a0, a1) = self.split_i8x32(a);
2937        self.combine_i8x16(self.count_zeros_i8x16(a0), self.count_zeros_i8x16(a1))
2938    }
2939    #[doc = "Add two vectors element-wise, wrapping on overflow."]
2940    #[inline(always)]
2941    fn add_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
2942        let (a0, a1) = self.split_i8x32(a);
2943        let (b0, b1) = self.split_i8x32(b);
2944        self.combine_i8x16(self.add_i8x16(a0, b0), self.add_i8x16(a1, b1))
2945    }
2946    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
2947    #[inline(always)]
2948    fn saturating_add_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
2949        let (a0, a1) = self.split_i8x32(a);
2950        let (b0, b1) = self.split_i8x32(b);
2951        self.combine_i8x16(
2952            self.saturating_add_i8x16(a0, b0),
2953            self.saturating_add_i8x16(a1, b1),
2954        )
2955    }
2956    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
2957    #[inline(always)]
2958    fn sub_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
2959        let (a0, a1) = self.split_i8x32(a);
2960        let (b0, b1) = self.split_i8x32(b);
2961        self.combine_i8x16(self.sub_i8x16(a0, b0), self.sub_i8x16(a1, b1))
2962    }
2963    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
2964    #[inline(always)]
2965    fn saturating_sub_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
2966        let (a0, a1) = self.split_i8x32(a);
2967        let (b0, b1) = self.split_i8x32(b);
2968        self.combine_i8x16(
2969            self.saturating_sub_i8x16(a0, b0),
2970            self.saturating_sub_i8x16(a1, b1),
2971        )
2972    }
2973    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
2974    #[inline(always)]
2975    fn mul_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
2976        let (a0, a1) = self.split_i8x32(a);
2977        let (b0, b1) = self.split_i8x32(b);
2978        self.combine_i8x16(self.mul_i8x16(a0, b0), self.mul_i8x16(a1, b1))
2979    }
2980    #[doc = "Compute the bitwise AND of two vectors."]
2981    #[inline(always)]
2982    fn and_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
2983        let (a0, a1) = self.split_i8x32(a);
2984        let (b0, b1) = self.split_i8x32(b);
2985        self.combine_i8x16(self.and_i8x16(a0, b0), self.and_i8x16(a1, b1))
2986    }
2987    #[doc = "Compute the bitwise OR of two vectors."]
2988    #[inline(always)]
2989    fn or_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
2990        let (a0, a1) = self.split_i8x32(a);
2991        let (b0, b1) = self.split_i8x32(b);
2992        self.combine_i8x16(self.or_i8x16(a0, b0), self.or_i8x16(a1, b1))
2993    }
2994    #[doc = "Compute the bitwise XOR of two vectors."]
2995    #[inline(always)]
2996    fn xor_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
2997        let (a0, a1) = self.split_i8x32(a);
2998        let (b0, b1) = self.split_i8x32(b);
2999        self.combine_i8x16(self.xor_i8x16(a0, b0), self.xor_i8x16(a1, b1))
3000    }
3001    #[doc = "Compute the bitwise NOT of the vector."]
3002    #[inline(always)]
3003    fn not_i8x32(self, a: i8x32<Self>) -> i8x32<Self> {
3004        let (a0, a1) = self.split_i8x32(a);
3005        self.combine_i8x16(self.not_i8x16(a0), self.not_i8x16(a1))
3006    }
3007    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
3008    #[inline(always)]
3009    fn shl_i8x32(self, a: i8x32<Self>, shift: u32) -> i8x32<Self> {
3010        let (a0, a1) = self.split_i8x32(a);
3011        self.combine_i8x16(self.shl_i8x16(a0, shift), self.shl_i8x16(a1, shift))
3012    }
3013    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
3014    #[inline(always)]
3015    fn shlv_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
3016        let (a0, a1) = self.split_i8x32(a);
3017        let (b0, b1) = self.split_i8x32(b);
3018        self.combine_i8x16(self.shlv_i8x16(a0, b0), self.shlv_i8x16(a1, b1))
3019    }
3020    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
3021    #[inline(always)]
3022    fn shr_i8x32(self, a: i8x32<Self>, shift: u32) -> i8x32<Self> {
3023        let (a0, a1) = self.split_i8x32(a);
3024        self.combine_i8x16(self.shr_i8x16(a0, shift), self.shr_i8x16(a1, shift))
3025    }
3026    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
3027    #[inline(always)]
3028    fn shrv_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
3029        let (a0, a1) = self.split_i8x32(a);
3030        let (b0, b1) = self.split_i8x32(b);
3031        self.combine_i8x16(self.shrv_i8x16(a0, b0), self.shrv_i8x16(a1, b1))
3032    }
3033    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
3034    #[inline(always)]
3035    fn reduce_max_i8x32(self, a: i8x32<Self>) -> i8 {
3036        let (a0, a1) = self.split_i8x32(a);
3037        self.reduce_max_i8x16(self.max_i8x16(a0, a1))
3038    }
3039    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
3040    #[inline(always)]
3041    fn reduce_min_i8x32(self, a: i8x32<Self>) -> i8 {
3042        let (a0, a1) = self.split_i8x32(a);
3043        self.reduce_min_i8x16(self.min_i8x16(a0, a1))
3044    }
3045    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
3046    #[inline(always)]
3047    fn reduce_sum_i8x32(self, a: i8x32<Self>) -> i8 {
3048        let (a0, a1) = self.split_i8x32(a);
3049        self.reduce_sum_i8x16(self.add_i8x16(a0, a1))
3050    }
3051    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
3052    #[inline(always)]
3053    fn reduce_product_i8x32(self, a: i8x32<Self>) -> i8 {
3054        let (a0, a1) = self.split_i8x32(a);
3055        self.reduce_product_i8x16(self.mul_i8x16(a0, a1))
3056    }
3057    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
3058    #[inline(always)]
3059    fn max_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
3060        let (a0, a1) = self.split_i8x32(a);
3061        let (b0, b1) = self.split_i8x32(b);
3062        self.combine_i8x16(self.max_i8x16(a0, b0), self.max_i8x16(a1, b1))
3063    }
3064    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
3065    #[inline(always)]
3066    fn min_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
3067        let (a0, a1) = self.split_i8x32(a);
3068        let (b0, b1) = self.split_i8x32(b);
3069        self.combine_i8x16(self.min_i8x16(a0, b0), self.min_i8x16(a1, b1))
3070    }
3071    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
3072    #[inline(always)]
3073    fn clamp_i8x32(self, a: i8x32<Self>, b: i8x32<Self>, c: i8x32<Self>) -> i8x32<Self> {
3074        let (a0, a1) = self.split_i8x32(a);
3075        let (b0, b1) = self.split_i8x32(b);
3076        let (c0, c1) = self.split_i8x32(c);
3077        self.combine_i8x16(self.clamp_i8x16(a0, b0, c0), self.clamp_i8x16(a1, b1, c1))
3078    }
3079    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
3080    #[inline(always)]
3081    fn simd_eq_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> mask8x32<Self> {
3082        let (a0, a1) = self.split_i8x32(a);
3083        let (b0, b1) = self.split_i8x32(b);
3084        self.combine_mask8x16(self.simd_eq_i8x16(a0, b0), self.simd_eq_i8x16(a1, b1))
3085    }
3086    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
3087    #[inline(always)]
3088    fn simd_ne_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> mask8x32<Self> {
3089        self.not_mask8x32(self.simd_eq_i8x32(a, b))
3090    }
3091    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
3092    #[inline(always)]
3093    fn simd_lt_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> mask8x32<Self> {
3094        let (a0, a1) = self.split_i8x32(a);
3095        let (b0, b1) = self.split_i8x32(b);
3096        self.combine_mask8x16(self.simd_lt_i8x16(a0, b0), self.simd_lt_i8x16(a1, b1))
3097    }
3098    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
3099    #[inline(always)]
3100    fn simd_le_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> mask8x32<Self> {
3101        let (a0, a1) = self.split_i8x32(a);
3102        let (b0, b1) = self.split_i8x32(b);
3103        self.combine_mask8x16(self.simd_le_i8x16(a0, b0), self.simd_le_i8x16(a1, b1))
3104    }
3105    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
3106    #[inline(always)]
3107    fn simd_ge_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> mask8x32<Self> {
3108        self.simd_le_i8x32(b, a)
3109    }
3110    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
3111    #[inline(always)]
3112    fn simd_gt_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> mask8x32<Self> {
3113        self.simd_lt_i8x32(b, a)
3114    }
3115    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
3116    #[inline(always)]
3117    fn zip_low_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
3118        let (a0, _) = self.split_i8x32(a);
3119        let (b0, _) = self.split_i8x32(b);
3120        self.combine_i8x16(self.zip_low_i8x16(a0, b0), self.zip_high_i8x16(a0, b0))
3121    }
3122    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
3123    #[inline(always)]
3124    fn zip_high_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
3125        let (_, a1) = self.split_i8x32(a);
3126        let (_, b1) = self.split_i8x32(b);
3127        self.combine_i8x16(self.zip_low_i8x16(a1, b1), self.zip_high_i8x16(a1, b1))
3128    }
3129    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
3130    #[inline(always)]
3131    fn unzip_low_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
3132        let (a0, a1) = self.split_i8x32(a);
3133        let (b0, b1) = self.split_i8x32(b);
3134        self.combine_i8x16(self.unzip_low_i8x16(a0, a1), self.unzip_low_i8x16(b0, b1))
3135    }
3136    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
3137    #[inline(always)]
3138    fn unzip_high_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x32<Self> {
3139        let (a0, a1) = self.split_i8x32(a);
3140        let (b0, b1) = self.split_i8x32(b);
3141        self.combine_i8x16(self.unzip_high_i8x16(a0, a1), self.unzip_high_i8x16(b0, b1))
3142    }
3143    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
3144    #[inline(always)]
3145    fn interleave_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> (i8x32<Self>, i8x32<Self>) {
3146        let (a0, a1) = self.split_i8x32(a);
3147        let (b0, b1) = self.split_i8x32(b);
3148        let lo_lo = self.zip_low_i8x16(a0, b0);
3149        let lo_hi = self.zip_high_i8x16(a0, b0);
3150        let hi_lo = self.zip_low_i8x16(a1, b1);
3151        let hi_hi = self.zip_high_i8x16(a1, b1);
3152        (
3153            self.combine_i8x16(lo_lo, lo_hi),
3154            self.combine_i8x16(hi_lo, hi_hi),
3155        )
3156    }
3157    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
3158    #[inline(always)]
3159    fn deinterleave_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> (i8x32<Self>, i8x32<Self>) {
3160        let (a0, a1) = self.split_i8x32(a);
3161        let (b0, b1) = self.split_i8x32(b);
3162        let lo_even = self.unzip_low_i8x16(a0, a1);
3163        let lo_odd = self.unzip_high_i8x16(a0, a1);
3164        let hi_even = self.unzip_low_i8x16(b0, b1);
3165        let hi_odd = self.unzip_high_i8x16(b0, b1);
3166        (
3167            self.combine_i8x16(lo_even, hi_even),
3168            self.combine_i8x16(lo_odd, hi_odd),
3169        )
3170    }
3171    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
3172    #[inline(always)]
3173    fn select_i8x32(self, a: mask8x32<Self>, b: i8x32<Self>, c: i8x32<Self>) -> i8x32<Self> {
3174        let (a0, a1) = self.split_mask8x32(a);
3175        let (b0, b1) = self.split_i8x32(b);
3176        let (c0, c1) = self.split_i8x32(c);
3177        self.combine_i8x16(self.select_i8x16(a0, b0, c0), self.select_i8x16(a1, b1, c1))
3178    }
3179    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
3180    fn combine_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i8x64<Self>;
3181    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
3182    fn split_i8x32(self, a: i8x32<Self>) -> (i8x16<Self>, i8x16<Self>);
3183    #[doc = "Negate each element of the vector, wrapping on overflow."]
3184    #[inline(always)]
3185    fn neg_i8x32(self, a: i8x32<Self>) -> i8x32<Self> {
3186        let (a0, a1) = self.split_i8x32(a);
3187        self.combine_i8x16(self.neg_i8x16(a0), self.neg_i8x16(a1))
3188    }
3189    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
3190    #[inline(always)]
3191    fn widen_i8x32(self, a: i8x32<Self>) -> (i16x16<Self>, i16x16<Self>) {
3192        let (a0, a1) = self.split_i8x32(a);
3193        let (a00, a01) = self.widen_i8x16(a0);
3194        let (a10, a11) = self.widen_i8x16(a1);
3195        (self.combine_i16x8(a00, a01), self.combine_i16x8(a10, a11))
3196    }
3197    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
3198    #[inline(always)]
3199    fn widening_mul_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> (i16x16<Self>, i16x16<Self>) {
3200        let (a0, a1) = self.split_i8x32(a);
3201        let (b0, b1) = self.split_i8x32(b);
3202        let (low0, low1) = self.widening_mul_i8x16(a0, b0);
3203        let (high0, high1) = self.widening_mul_i8x16(a1, b1);
3204        (
3205            self.combine_i16x8(low0, low1),
3206            self.combine_i16x8(high0, high1),
3207        )
3208    }
3209    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
3210    #[inline(always)]
3211    fn widening_add_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> (i16x16<Self>, i16x16<Self>) {
3212        let (a0, a1) = self.split_i8x32(a);
3213        let (b0, b1) = self.split_i8x32(b);
3214        let (low0, low1) = self.widening_add_i8x16(a0, b0);
3215        let (high0, high1) = self.widening_add_i8x16(a1, b1);
3216        (
3217            self.combine_i16x8(low0, low1),
3218            self.combine_i16x8(high0, high1),
3219        )
3220    }
3221    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
3222    #[inline(always)]
3223    fn pairwise_widening_add_i8x32(self, a: i8x32<Self>) -> i16x16<Self> {
3224        let (a0, a1) = self.split_i8x32(a);
3225        self.combine_i16x8(
3226            self.pairwise_widening_add_i8x16(a0),
3227            self.pairwise_widening_add_i8x16(a1),
3228        )
3229    }
3230    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
3231    #[inline(always)]
3232    fn pairwise_dot_product_i8x32(self, a: i8x32<Self>, b: i8x32<Self>) -> i16x16<Self> {
3233        let (a0, a1) = self.split_i8x32(a);
3234        let (b0, b1) = self.split_i8x32(b);
3235        self.combine_i16x8(
3236            self.pairwise_dot_product_i8x16(a0, b0),
3237            self.pairwise_dot_product_i8x16(a1, b1),
3238        )
3239    }
3240    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
3241    #[inline(always)]
3242    fn abs_u8x32(self, a: u8x32<Self>) -> u8x32<Self> {
3243        a
3244    }
3245    #[doc = "Create a SIMD vector with all elements set to the given value."]
3246    #[inline(always)]
3247    fn splat_u8x32(self, val: u8) -> u8x32<Self> {
3248        let half = self.splat_u8x16(val);
3249        self.combine_u8x16(half, half)
3250    }
3251    #[doc = "Reverse the order of the vector's elements."]
3252    #[inline(always)]
3253    fn reverse_u8x32(self, a: u8x32<Self>) -> u8x32<Self> {
3254        let (a0, a1) = self.split_u8x32(a);
3255        self.combine_u8x16(self.reverse_u8x16(a1), self.reverse_u8x16(a0))
3256    }
3257    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
3258    fn slide_u8x32<const SHIFT: usize>(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self>;
3259    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
3260    #[inline(always)]
3261    fn slide_within_blocks_u8x32<const SHIFT: usize>(
3262        self,
3263        a: u8x32<Self>,
3264        b: u8x32<Self>,
3265    ) -> u8x32<Self> {
3266        let (a0, a1) = self.split_u8x32(a);
3267        let (b0, b1) = self.split_u8x32(b);
3268        self.combine_u8x16(
3269            self.slide_within_blocks_u8x16::<SHIFT>(a0, b0),
3270            self.slide_within_blocks_u8x16::<SHIFT>(a1, b1),
3271        )
3272    }
3273    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
3274    #[inline(always)]
3275    fn swizzle_dyn_within_blocks_u8x32(self, a: u8x32<Self>, indices: u8x32<Self>) -> u8x32<Self> {
3276        let (a0, a1) = self.split_u8x32(a);
3277        let (indices0, indices1) = self.split_u8x32(indices);
3278        self.combine_u8x16(
3279            self.swizzle_dyn_within_blocks_u8x16(a0, indices0),
3280            self.swizzle_dyn_within_blocks_u8x16(a1, indices1),
3281        )
3282    }
3283    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
3284    fn swizzle_dyn_u8x32(self, a: u8x32<Self>, indices: u8x32<Self>) -> u8x32<Self>;
3285    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
3286    fn swizzle_dyn_precise_u8x32(self, a: u8x32<Self>, indices: u8x32<Self>) -> u8x32<Self>;
3287    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
3288    fn concat_swizzle_dyn_u8x32(
3289        self,
3290        a: u8x32<Self>,
3291        b: u8x32<Self>,
3292        indices: u8x32<Self>,
3293    ) -> u8x32<Self>;
3294    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
3295    fn concat_swizzle_dyn_precise_u8x32(
3296        self,
3297        a: u8x32<Self>,
3298        b: u8x32<Self>,
3299        indices: u8x32<Self>,
3300    ) -> u8x32<Self>;
3301    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
3302    fn compress_u8x32(self, values: u8x32<Self>, mask: mask8x32<Self>) -> u8x32<Self>;
3303    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
3304    fn compress_merge_u8x32(
3305        self,
3306        values: u8x32<Self>,
3307        mask: mask8x32<Self>,
3308        merge: u8x32<Self>,
3309    ) -> u8x32<Self>;
3310    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
3311    fn expand_u8x32(self, values: u8x32<Self>, mask: mask8x32<Self>) -> u8x32<Self>;
3312    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
3313    fn expand_merge_u8x32(
3314        self,
3315        values: u8x32<Self>,
3316        mask: mask8x32<Self>,
3317        merge: u8x32<Self>,
3318    ) -> u8x32<Self>;
3319    #[doc = "Return the number of ones in the binary representation of each element."]
3320    #[inline(always)]
3321    fn count_ones_u8x32(self, a: u8x32<Self>) -> u8x32<Self> {
3322        let (a0, a1) = self.split_u8x32(a);
3323        self.combine_u8x16(self.count_ones_u8x16(a0), self.count_ones_u8x16(a1))
3324    }
3325    #[doc = "Return the number of zeros in the binary representation of each element."]
3326    #[inline(always)]
3327    fn count_zeros_u8x32(self, a: u8x32<Self>) -> u8x32<Self> {
3328        let (a0, a1) = self.split_u8x32(a);
3329        self.combine_u8x16(self.count_zeros_u8x16(a0), self.count_zeros_u8x16(a1))
3330    }
3331    #[doc = "Add two vectors element-wise, wrapping on overflow."]
3332    #[inline(always)]
3333    fn add_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
3334        let (a0, a1) = self.split_u8x32(a);
3335        let (b0, b1) = self.split_u8x32(b);
3336        self.combine_u8x16(self.add_u8x16(a0, b0), self.add_u8x16(a1, b1))
3337    }
3338    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
3339    #[inline(always)]
3340    fn saturating_add_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
3341        let (a0, a1) = self.split_u8x32(a);
3342        let (b0, b1) = self.split_u8x32(b);
3343        self.combine_u8x16(
3344            self.saturating_add_u8x16(a0, b0),
3345            self.saturating_add_u8x16(a1, b1),
3346        )
3347    }
3348    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
3349    #[inline(always)]
3350    fn sub_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
3351        let (a0, a1) = self.split_u8x32(a);
3352        let (b0, b1) = self.split_u8x32(b);
3353        self.combine_u8x16(self.sub_u8x16(a0, b0), self.sub_u8x16(a1, b1))
3354    }
3355    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
3356    #[inline(always)]
3357    fn saturating_sub_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
3358        let (a0, a1) = self.split_u8x32(a);
3359        let (b0, b1) = self.split_u8x32(b);
3360        self.combine_u8x16(
3361            self.saturating_sub_u8x16(a0, b0),
3362            self.saturating_sub_u8x16(a1, b1),
3363        )
3364    }
3365    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
3366    #[inline(always)]
3367    fn mul_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
3368        let (a0, a1) = self.split_u8x32(a);
3369        let (b0, b1) = self.split_u8x32(b);
3370        self.combine_u8x16(self.mul_u8x16(a0, b0), self.mul_u8x16(a1, b1))
3371    }
3372    #[doc = "Compute the bitwise AND of two vectors."]
3373    #[inline(always)]
3374    fn and_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
3375        let (a0, a1) = self.split_u8x32(a);
3376        let (b0, b1) = self.split_u8x32(b);
3377        self.combine_u8x16(self.and_u8x16(a0, b0), self.and_u8x16(a1, b1))
3378    }
3379    #[doc = "Compute the bitwise OR of two vectors."]
3380    #[inline(always)]
3381    fn or_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
3382        let (a0, a1) = self.split_u8x32(a);
3383        let (b0, b1) = self.split_u8x32(b);
3384        self.combine_u8x16(self.or_u8x16(a0, b0), self.or_u8x16(a1, b1))
3385    }
3386    #[doc = "Compute the bitwise XOR of two vectors."]
3387    #[inline(always)]
3388    fn xor_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
3389        let (a0, a1) = self.split_u8x32(a);
3390        let (b0, b1) = self.split_u8x32(b);
3391        self.combine_u8x16(self.xor_u8x16(a0, b0), self.xor_u8x16(a1, b1))
3392    }
3393    #[doc = "Compute the bitwise NOT of the vector."]
3394    #[inline(always)]
3395    fn not_u8x32(self, a: u8x32<Self>) -> u8x32<Self> {
3396        let (a0, a1) = self.split_u8x32(a);
3397        self.combine_u8x16(self.not_u8x16(a0), self.not_u8x16(a1))
3398    }
3399    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
3400    #[inline(always)]
3401    fn shl_u8x32(self, a: u8x32<Self>, shift: u32) -> u8x32<Self> {
3402        let (a0, a1) = self.split_u8x32(a);
3403        self.combine_u8x16(self.shl_u8x16(a0, shift), self.shl_u8x16(a1, shift))
3404    }
3405    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
3406    #[inline(always)]
3407    fn shlv_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
3408        let (a0, a1) = self.split_u8x32(a);
3409        let (b0, b1) = self.split_u8x32(b);
3410        self.combine_u8x16(self.shlv_u8x16(a0, b0), self.shlv_u8x16(a1, b1))
3411    }
3412    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
3413    #[inline(always)]
3414    fn shr_u8x32(self, a: u8x32<Self>, shift: u32) -> u8x32<Self> {
3415        let (a0, a1) = self.split_u8x32(a);
3416        self.combine_u8x16(self.shr_u8x16(a0, shift), self.shr_u8x16(a1, shift))
3417    }
3418    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
3419    #[inline(always)]
3420    fn shrv_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
3421        let (a0, a1) = self.split_u8x32(a);
3422        let (b0, b1) = self.split_u8x32(b);
3423        self.combine_u8x16(self.shrv_u8x16(a0, b0), self.shrv_u8x16(a1, b1))
3424    }
3425    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
3426    #[inline(always)]
3427    fn reduce_max_u8x32(self, a: u8x32<Self>) -> u8 {
3428        let (a0, a1) = self.split_u8x32(a);
3429        self.reduce_max_u8x16(self.max_u8x16(a0, a1))
3430    }
3431    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
3432    #[inline(always)]
3433    fn reduce_min_u8x32(self, a: u8x32<Self>) -> u8 {
3434        let (a0, a1) = self.split_u8x32(a);
3435        self.reduce_min_u8x16(self.min_u8x16(a0, a1))
3436    }
3437    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
3438    #[inline(always)]
3439    fn reduce_sum_u8x32(self, a: u8x32<Self>) -> u8 {
3440        let (a0, a1) = self.split_u8x32(a);
3441        self.reduce_sum_u8x16(self.add_u8x16(a0, a1))
3442    }
3443    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
3444    #[inline(always)]
3445    fn reduce_product_u8x32(self, a: u8x32<Self>) -> u8 {
3446        let (a0, a1) = self.split_u8x32(a);
3447        self.reduce_product_u8x16(self.mul_u8x16(a0, a1))
3448    }
3449    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
3450    #[inline(always)]
3451    fn max_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
3452        let (a0, a1) = self.split_u8x32(a);
3453        let (b0, b1) = self.split_u8x32(b);
3454        self.combine_u8x16(self.max_u8x16(a0, b0), self.max_u8x16(a1, b1))
3455    }
3456    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
3457    #[inline(always)]
3458    fn min_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
3459        let (a0, a1) = self.split_u8x32(a);
3460        let (b0, b1) = self.split_u8x32(b);
3461        self.combine_u8x16(self.min_u8x16(a0, b0), self.min_u8x16(a1, b1))
3462    }
3463    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
3464    #[inline(always)]
3465    fn clamp_u8x32(self, a: u8x32<Self>, b: u8x32<Self>, c: u8x32<Self>) -> u8x32<Self> {
3466        let (a0, a1) = self.split_u8x32(a);
3467        let (b0, b1) = self.split_u8x32(b);
3468        let (c0, c1) = self.split_u8x32(c);
3469        self.combine_u8x16(self.clamp_u8x16(a0, b0, c0), self.clamp_u8x16(a1, b1, c1))
3470    }
3471    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
3472    #[inline(always)]
3473    fn simd_eq_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> mask8x32<Self> {
3474        let (a0, a1) = self.split_u8x32(a);
3475        let (b0, b1) = self.split_u8x32(b);
3476        self.combine_mask8x16(self.simd_eq_u8x16(a0, b0), self.simd_eq_u8x16(a1, b1))
3477    }
3478    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
3479    #[inline(always)]
3480    fn simd_ne_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> mask8x32<Self> {
3481        self.not_mask8x32(self.simd_eq_u8x32(a, b))
3482    }
3483    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
3484    #[inline(always)]
3485    fn simd_lt_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> mask8x32<Self> {
3486        let (a0, a1) = self.split_u8x32(a);
3487        let (b0, b1) = self.split_u8x32(b);
3488        self.combine_mask8x16(self.simd_lt_u8x16(a0, b0), self.simd_lt_u8x16(a1, b1))
3489    }
3490    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
3491    #[inline(always)]
3492    fn simd_le_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> mask8x32<Self> {
3493        let (a0, a1) = self.split_u8x32(a);
3494        let (b0, b1) = self.split_u8x32(b);
3495        self.combine_mask8x16(self.simd_le_u8x16(a0, b0), self.simd_le_u8x16(a1, b1))
3496    }
3497    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
3498    #[inline(always)]
3499    fn simd_ge_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> mask8x32<Self> {
3500        self.simd_le_u8x32(b, a)
3501    }
3502    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
3503    #[inline(always)]
3504    fn simd_gt_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> mask8x32<Self> {
3505        self.simd_lt_u8x32(b, a)
3506    }
3507    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
3508    #[inline(always)]
3509    fn zip_low_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
3510        let (a0, _) = self.split_u8x32(a);
3511        let (b0, _) = self.split_u8x32(b);
3512        self.combine_u8x16(self.zip_low_u8x16(a0, b0), self.zip_high_u8x16(a0, b0))
3513    }
3514    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
3515    #[inline(always)]
3516    fn zip_high_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
3517        let (_, a1) = self.split_u8x32(a);
3518        let (_, b1) = self.split_u8x32(b);
3519        self.combine_u8x16(self.zip_low_u8x16(a1, b1), self.zip_high_u8x16(a1, b1))
3520    }
3521    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
3522    #[inline(always)]
3523    fn unzip_low_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
3524        let (a0, a1) = self.split_u8x32(a);
3525        let (b0, b1) = self.split_u8x32(b);
3526        self.combine_u8x16(self.unzip_low_u8x16(a0, a1), self.unzip_low_u8x16(b0, b1))
3527    }
3528    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
3529    #[inline(always)]
3530    fn unzip_high_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x32<Self> {
3531        let (a0, a1) = self.split_u8x32(a);
3532        let (b0, b1) = self.split_u8x32(b);
3533        self.combine_u8x16(self.unzip_high_u8x16(a0, a1), self.unzip_high_u8x16(b0, b1))
3534    }
3535    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
3536    #[inline(always)]
3537    fn interleave_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> (u8x32<Self>, u8x32<Self>) {
3538        let (a0, a1) = self.split_u8x32(a);
3539        let (b0, b1) = self.split_u8x32(b);
3540        let lo_lo = self.zip_low_u8x16(a0, b0);
3541        let lo_hi = self.zip_high_u8x16(a0, b0);
3542        let hi_lo = self.zip_low_u8x16(a1, b1);
3543        let hi_hi = self.zip_high_u8x16(a1, b1);
3544        (
3545            self.combine_u8x16(lo_lo, lo_hi),
3546            self.combine_u8x16(hi_lo, hi_hi),
3547        )
3548    }
3549    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
3550    #[inline(always)]
3551    fn deinterleave_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> (u8x32<Self>, u8x32<Self>) {
3552        let (a0, a1) = self.split_u8x32(a);
3553        let (b0, b1) = self.split_u8x32(b);
3554        let lo_even = self.unzip_low_u8x16(a0, a1);
3555        let lo_odd = self.unzip_high_u8x16(a0, a1);
3556        let hi_even = self.unzip_low_u8x16(b0, b1);
3557        let hi_odd = self.unzip_high_u8x16(b0, b1);
3558        (
3559            self.combine_u8x16(lo_even, hi_even),
3560            self.combine_u8x16(lo_odd, hi_odd),
3561        )
3562    }
3563    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
3564    #[inline(always)]
3565    fn select_u8x32(self, a: mask8x32<Self>, b: u8x32<Self>, c: u8x32<Self>) -> u8x32<Self> {
3566        let (a0, a1) = self.split_mask8x32(a);
3567        let (b0, b1) = self.split_u8x32(b);
3568        let (c0, c1) = self.split_u8x32(c);
3569        self.combine_u8x16(self.select_u8x16(a0, b0, c0), self.select_u8x16(a1, b1, c1))
3570    }
3571    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
3572    fn combine_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u8x64<Self>;
3573    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
3574    fn split_u8x32(self, a: u8x32<Self>) -> (u8x16<Self>, u8x16<Self>);
3575    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
3576    #[inline(always)]
3577    fn widen_u8x32(self, a: u8x32<Self>) -> (u16x16<Self>, u16x16<Self>) {
3578        let (a0, a1) = self.split_u8x32(a);
3579        let (a00, a01) = self.widen_u8x16(a0);
3580        let (a10, a11) = self.widen_u8x16(a1);
3581        (self.combine_u16x8(a00, a01), self.combine_u16x8(a10, a11))
3582    }
3583    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
3584    #[inline(always)]
3585    fn widening_mul_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> (u16x16<Self>, u16x16<Self>) {
3586        let (a0, a1) = self.split_u8x32(a);
3587        let (b0, b1) = self.split_u8x32(b);
3588        let (low0, low1) = self.widening_mul_u8x16(a0, b0);
3589        let (high0, high1) = self.widening_mul_u8x16(a1, b1);
3590        (
3591            self.combine_u16x8(low0, low1),
3592            self.combine_u16x8(high0, high1),
3593        )
3594    }
3595    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
3596    #[inline(always)]
3597    fn widening_add_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> (u16x16<Self>, u16x16<Self>) {
3598        let (a0, a1) = self.split_u8x32(a);
3599        let (b0, b1) = self.split_u8x32(b);
3600        let (low0, low1) = self.widening_add_u8x16(a0, b0);
3601        let (high0, high1) = self.widening_add_u8x16(a1, b1);
3602        (
3603            self.combine_u16x8(low0, low1),
3604            self.combine_u16x8(high0, high1),
3605        )
3606    }
3607    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
3608    #[inline(always)]
3609    fn pairwise_widening_add_u8x32(self, a: u8x32<Self>) -> u16x16<Self> {
3610        let (a0, a1) = self.split_u8x32(a);
3611        self.combine_u16x8(
3612            self.pairwise_widening_add_u8x16(a0),
3613            self.pairwise_widening_add_u8x16(a1),
3614        )
3615    }
3616    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
3617    #[inline(always)]
3618    fn pairwise_dot_product_u8x32(self, a: u8x32<Self>, b: u8x32<Self>) -> u16x16<Self> {
3619        let (a0, a1) = self.split_u8x32(a);
3620        let (b0, b1) = self.split_u8x32(b);
3621        self.combine_u16x8(
3622            self.pairwise_dot_product_u8x16(a0, b0),
3623            self.pairwise_dot_product_u8x16(a1, b1),
3624        )
3625    }
3626    #[doc = "Create a SIMD mask with all lanes set from the given boolean value."]
3627    #[inline(always)]
3628    fn splat_mask8x32(self, val: bool) -> mask8x32<Self> {
3629        let half = self.splat_mask8x16(val);
3630        self.combine_mask8x16(half, half)
3631    }
3632    #[doc = "Create a SIMD mask from a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are ignored."]
3633    #[inline(always)]
3634    fn from_bitmask_mask8x32(self, bits: u64) -> mask8x32<Self> {
3635        let lo = self.from_bitmask_mask8x16(bits);
3636        let hi = self.from_bitmask_mask8x16(bits >> 16usize);
3637        self.combine_mask8x16(lo, hi)
3638    }
3639    #[doc = "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared."]
3640    #[inline(always)]
3641    fn to_bitmask_mask8x32(self, a: mask8x32<Self>) -> u64 {
3642        let (lo, hi) = self.split_mask8x32(a);
3643        let lo = self.to_bitmask_mask8x16(lo);
3644        let hi = self.to_bitmask_mask8x16(hi);
3645        lo | (hi << 16usize)
3646    }
3647    #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."]
3648    fn from_vector_mask8x32(self, vector: i8x32<Self>) -> mask8x32<Self>;
3649    #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."]
3650    fn to_vector_mask8x32(self, a: mask8x32<Self>) -> i8x32<Self>;
3651    #[doc = "Set one logical lane of a SIMD mask."]
3652    fn set_mask8x32(self, a: &mut mask8x32<Self>, index: usize, value: bool) -> ();
3653    #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
3654    fn rotate_elements_left_mask8x32<const OFFSET: usize>(
3655        self,
3656        a: mask8x32<Self>,
3657    ) -> mask8x32<Self>;
3658    #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
3659    fn rotate_elements_right_mask8x32<const OFFSET: usize>(
3660        self,
3661        a: mask8x32<Self>,
3662    ) -> mask8x32<Self>;
3663    #[doc = "Compute the logical AND of two masks."]
3664    #[inline(always)]
3665    fn and_mask8x32(self, a: mask8x32<Self>, b: mask8x32<Self>) -> mask8x32<Self> {
3666        let (a0, a1) = self.split_mask8x32(a);
3667        let (b0, b1) = self.split_mask8x32(b);
3668        self.combine_mask8x16(self.and_mask8x16(a0, b0), self.and_mask8x16(a1, b1))
3669    }
3670    #[doc = "Compute the logical OR of two masks."]
3671    #[inline(always)]
3672    fn or_mask8x32(self, a: mask8x32<Self>, b: mask8x32<Self>) -> mask8x32<Self> {
3673        let (a0, a1) = self.split_mask8x32(a);
3674        let (b0, b1) = self.split_mask8x32(b);
3675        self.combine_mask8x16(self.or_mask8x16(a0, b0), self.or_mask8x16(a1, b1))
3676    }
3677    #[doc = "Compute the logical XOR of two masks."]
3678    #[inline(always)]
3679    fn xor_mask8x32(self, a: mask8x32<Self>, b: mask8x32<Self>) -> mask8x32<Self> {
3680        let (a0, a1) = self.split_mask8x32(a);
3681        let (b0, b1) = self.split_mask8x32(b);
3682        self.combine_mask8x16(self.xor_mask8x16(a0, b0), self.xor_mask8x16(a1, b1))
3683    }
3684    #[doc = "Compute the logical NOT of the mask."]
3685    #[inline(always)]
3686    fn not_mask8x32(self, a: mask8x32<Self>) -> mask8x32<Self> {
3687        let (a0, a1) = self.split_mask8x32(a);
3688        self.combine_mask8x16(self.not_mask8x16(a0), self.not_mask8x16(a1))
3689    }
3690    #[doc = "Reverse the order of the mask's logical lanes."]
3691    #[inline(always)]
3692    fn reverse_mask8x32(self, a: mask8x32<Self>) -> mask8x32<Self> {
3693        let (a0, a1) = self.split_mask8x32(a);
3694        self.combine_mask8x16(self.reverse_mask8x16(a1), self.reverse_mask8x16(a0))
3695    }
3696    #[doc = "Select elements from `b` and `c` based on the mask operand `a`.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
3697    #[inline(always)]
3698    fn select_mask8x32(
3699        self,
3700        a: mask8x32<Self>,
3701        b: mask8x32<Self>,
3702        c: mask8x32<Self>,
3703    ) -> mask8x32<Self> {
3704        let (a0, a1) = self.split_mask8x32(a);
3705        let (b0, b1) = self.split_mask8x32(b);
3706        let (c0, c1) = self.split_mask8x32(c);
3707        self.combine_mask8x16(
3708            self.select_mask8x16(a0, b0, c0),
3709            self.select_mask8x16(a1, b1, c1),
3710        )
3711    }
3712    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
3713    #[inline(always)]
3714    fn simd_eq_mask8x32(self, a: mask8x32<Self>, b: mask8x32<Self>) -> mask8x32<Self> {
3715        let (a0, a1) = self.split_mask8x32(a);
3716        let (b0, b1) = self.split_mask8x32(b);
3717        self.combine_mask8x16(self.simd_eq_mask8x16(a0, b0), self.simd_eq_mask8x16(a1, b1))
3718    }
3719    #[doc = "Compare two masks element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
3720    #[inline(always)]
3721    fn simd_ne_mask8x32(self, a: mask8x32<Self>, b: mask8x32<Self>) -> mask8x32<Self> {
3722        self.not_mask8x32(self.simd_eq_mask8x32(a, b))
3723    }
3724    #[doc = "Returns true if any logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
3725    #[inline(always)]
3726    fn any_true_mask8x32(self, a: mask8x32<Self>) -> bool {
3727        let (a0, a1) = self.split_mask8x32(a);
3728        self.any_true_mask8x16(self.or_mask8x16(a0, a1))
3729    }
3730    #[doc = "Returns true if all logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
3731    #[inline(always)]
3732    fn all_true_mask8x32(self, a: mask8x32<Self>) -> bool {
3733        let (a0, a1) = self.split_mask8x32(a);
3734        self.all_true_mask8x16(self.and_mask8x16(a0, a1))
3735    }
3736    #[doc = "Returns true if any logical lanes in this mask are false.\n\nThis is logically equivalent to `!all_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
3737    #[inline(always)]
3738    fn any_false_mask8x32(self, a: mask8x32<Self>) -> bool {
3739        let (a0, a1) = self.split_mask8x32(a);
3740        self.any_false_mask8x16(self.and_mask8x16(a0, a1))
3741    }
3742    #[doc = "Returns true if all logical lanes in this mask are false.\n\nThis is logically equivalent to `!any_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
3743    #[inline(always)]
3744    fn all_false_mask8x32(self, a: mask8x32<Self>) -> bool {
3745        let (a0, a1) = self.split_mask8x32(a);
3746        self.all_false_mask8x16(self.or_mask8x16(a0, a1))
3747    }
3748    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
3749    fn combine_mask8x32(self, a: mask8x32<Self>, b: mask8x32<Self>) -> mask8x64<Self>;
3750    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
3751    fn split_mask8x32(self, a: mask8x32<Self>) -> (mask8x16<Self>, mask8x16<Self>);
3752    #[doc = "Widen each boolean lane into two masks of the same logical width, preserving its value.\n\nThe first result contains the lower lanes and the second contains the upper lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
3753    #[inline(always)]
3754    fn widen_mask8x32(self, a: mask8x32<Self>) -> (mask16x16<Self>, mask16x16<Self>) {
3755        let (a0, a1) = self.split_mask8x32(a);
3756        let (a00, a01) = self.widen_mask8x16(a0);
3757        let (a10, a11) = self.widen_mask8x16(a1);
3758        (
3759            self.combine_mask16x8(a00, a01),
3760            self.combine_mask16x8(a10, a11),
3761        )
3762    }
3763    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
3764    #[inline(always)]
3765    fn abs_i16x16(self, a: i16x16<Self>) -> i16x16<Self> {
3766        let (a0, a1) = self.split_i16x16(a);
3767        self.combine_i16x8(self.abs_i16x8(a0), self.abs_i16x8(a1))
3768    }
3769    #[doc = "Create a SIMD vector with all elements set to the given value."]
3770    #[inline(always)]
3771    fn splat_i16x16(self, val: i16) -> i16x16<Self> {
3772        let half = self.splat_i16x8(val);
3773        self.combine_i16x8(half, half)
3774    }
3775    #[doc = "Reverse the order of the vector's elements."]
3776    #[inline(always)]
3777    fn reverse_i16x16(self, a: i16x16<Self>) -> i16x16<Self> {
3778        let (a0, a1) = self.split_i16x16(a);
3779        self.combine_i16x8(self.reverse_i16x8(a1), self.reverse_i16x8(a0))
3780    }
3781    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
3782    fn slide_i16x16<const SHIFT: usize>(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self>;
3783    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
3784    #[inline(always)]
3785    fn slide_within_blocks_i16x16<const SHIFT: usize>(
3786        self,
3787        a: i16x16<Self>,
3788        b: i16x16<Self>,
3789    ) -> i16x16<Self> {
3790        let (a0, a1) = self.split_i16x16(a);
3791        let (b0, b1) = self.split_i16x16(b);
3792        self.combine_i16x8(
3793            self.slide_within_blocks_i16x8::<SHIFT>(a0, b0),
3794            self.slide_within_blocks_i16x8::<SHIFT>(a1, b1),
3795        )
3796    }
3797    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
3798    #[inline(always)]
3799    fn swizzle_dyn_within_blocks_i16x16(
3800        self,
3801        a: i16x16<Self>,
3802        indices: u8x32<Self>,
3803    ) -> i16x16<Self> {
3804        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x32(Bytes::to_bytes(a), indices))
3805    }
3806    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
3807    #[inline(always)]
3808    fn swizzle_dyn_i16x16(self, a: i16x16<Self>, indices: u8x32<Self>) -> i16x16<Self> {
3809        Bytes::from_bytes(self.swizzle_dyn_u8x32(Bytes::to_bytes(a), indices))
3810    }
3811    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
3812    #[inline(always)]
3813    fn swizzle_dyn_precise_i16x16(self, a: i16x16<Self>, indices: u8x32<Self>) -> i16x16<Self> {
3814        Bytes::from_bytes(self.swizzle_dyn_precise_u8x32(Bytes::to_bytes(a), indices))
3815    }
3816    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
3817    #[inline(always)]
3818    fn concat_swizzle_dyn_i16x16(
3819        self,
3820        a: i16x16<Self>,
3821        b: i16x16<Self>,
3822        indices: u8x32<Self>,
3823    ) -> i16x16<Self> {
3824        Bytes::from_bytes(self.concat_swizzle_dyn_u8x32(
3825            Bytes::to_bytes(a),
3826            Bytes::to_bytes(b),
3827            indices,
3828        ))
3829    }
3830    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
3831    #[inline(always)]
3832    fn concat_swizzle_dyn_precise_i16x16(
3833        self,
3834        a: i16x16<Self>,
3835        b: i16x16<Self>,
3836        indices: u8x32<Self>,
3837    ) -> i16x16<Self> {
3838        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x32(
3839            Bytes::to_bytes(a),
3840            Bytes::to_bytes(b),
3841            indices,
3842        ))
3843    }
3844    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
3845    fn compress_i16x16(self, values: i16x16<Self>, mask: mask16x16<Self>) -> i16x16<Self>;
3846    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
3847    fn compress_merge_i16x16(
3848        self,
3849        values: i16x16<Self>,
3850        mask: mask16x16<Self>,
3851        merge: i16x16<Self>,
3852    ) -> i16x16<Self>;
3853    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
3854    fn expand_i16x16(self, values: i16x16<Self>, mask: mask16x16<Self>) -> i16x16<Self>;
3855    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
3856    fn expand_merge_i16x16(
3857        self,
3858        values: i16x16<Self>,
3859        mask: mask16x16<Self>,
3860        merge: i16x16<Self>,
3861    ) -> i16x16<Self>;
3862    #[doc = "Return the number of ones in the binary representation of each element."]
3863    #[inline(always)]
3864    fn count_ones_i16x16(self, a: i16x16<Self>) -> i16x16<Self> {
3865        let (a0, a1) = self.split_i16x16(a);
3866        self.combine_i16x8(self.count_ones_i16x8(a0), self.count_ones_i16x8(a1))
3867    }
3868    #[doc = "Return the number of zeros in the binary representation of each element."]
3869    #[inline(always)]
3870    fn count_zeros_i16x16(self, a: i16x16<Self>) -> i16x16<Self> {
3871        let (a0, a1) = self.split_i16x16(a);
3872        self.combine_i16x8(self.count_zeros_i16x8(a0), self.count_zeros_i16x8(a1))
3873    }
3874    #[doc = "Add two vectors element-wise, wrapping on overflow."]
3875    #[inline(always)]
3876    fn add_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
3877        let (a0, a1) = self.split_i16x16(a);
3878        let (b0, b1) = self.split_i16x16(b);
3879        self.combine_i16x8(self.add_i16x8(a0, b0), self.add_i16x8(a1, b1))
3880    }
3881    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
3882    #[inline(always)]
3883    fn saturating_add_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
3884        let (a0, a1) = self.split_i16x16(a);
3885        let (b0, b1) = self.split_i16x16(b);
3886        self.combine_i16x8(
3887            self.saturating_add_i16x8(a0, b0),
3888            self.saturating_add_i16x8(a1, b1),
3889        )
3890    }
3891    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
3892    #[inline(always)]
3893    fn sub_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
3894        let (a0, a1) = self.split_i16x16(a);
3895        let (b0, b1) = self.split_i16x16(b);
3896        self.combine_i16x8(self.sub_i16x8(a0, b0), self.sub_i16x8(a1, b1))
3897    }
3898    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
3899    #[inline(always)]
3900    fn saturating_sub_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
3901        let (a0, a1) = self.split_i16x16(a);
3902        let (b0, b1) = self.split_i16x16(b);
3903        self.combine_i16x8(
3904            self.saturating_sub_i16x8(a0, b0),
3905            self.saturating_sub_i16x8(a1, b1),
3906        )
3907    }
3908    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
3909    #[inline(always)]
3910    fn mul_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
3911        let (a0, a1) = self.split_i16x16(a);
3912        let (b0, b1) = self.split_i16x16(b);
3913        self.combine_i16x8(self.mul_i16x8(a0, b0), self.mul_i16x8(a1, b1))
3914    }
3915    #[doc = "Compute the bitwise AND of two vectors."]
3916    #[inline(always)]
3917    fn and_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
3918        let (a0, a1) = self.split_i16x16(a);
3919        let (b0, b1) = self.split_i16x16(b);
3920        self.combine_i16x8(self.and_i16x8(a0, b0), self.and_i16x8(a1, b1))
3921    }
3922    #[doc = "Compute the bitwise OR of two vectors."]
3923    #[inline(always)]
3924    fn or_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
3925        let (a0, a1) = self.split_i16x16(a);
3926        let (b0, b1) = self.split_i16x16(b);
3927        self.combine_i16x8(self.or_i16x8(a0, b0), self.or_i16x8(a1, b1))
3928    }
3929    #[doc = "Compute the bitwise XOR of two vectors."]
3930    #[inline(always)]
3931    fn xor_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
3932        let (a0, a1) = self.split_i16x16(a);
3933        let (b0, b1) = self.split_i16x16(b);
3934        self.combine_i16x8(self.xor_i16x8(a0, b0), self.xor_i16x8(a1, b1))
3935    }
3936    #[doc = "Compute the bitwise NOT of the vector."]
3937    #[inline(always)]
3938    fn not_i16x16(self, a: i16x16<Self>) -> i16x16<Self> {
3939        let (a0, a1) = self.split_i16x16(a);
3940        self.combine_i16x8(self.not_i16x8(a0), self.not_i16x8(a1))
3941    }
3942    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
3943    #[inline(always)]
3944    fn shl_i16x16(self, a: i16x16<Self>, shift: u32) -> i16x16<Self> {
3945        let (a0, a1) = self.split_i16x16(a);
3946        self.combine_i16x8(self.shl_i16x8(a0, shift), self.shl_i16x8(a1, shift))
3947    }
3948    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
3949    #[inline(always)]
3950    fn shlv_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
3951        let (a0, a1) = self.split_i16x16(a);
3952        let (b0, b1) = self.split_i16x16(b);
3953        self.combine_i16x8(self.shlv_i16x8(a0, b0), self.shlv_i16x8(a1, b1))
3954    }
3955    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
3956    #[inline(always)]
3957    fn shr_i16x16(self, a: i16x16<Self>, shift: u32) -> i16x16<Self> {
3958        let (a0, a1) = self.split_i16x16(a);
3959        self.combine_i16x8(self.shr_i16x8(a0, shift), self.shr_i16x8(a1, shift))
3960    }
3961    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
3962    #[inline(always)]
3963    fn shrv_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
3964        let (a0, a1) = self.split_i16x16(a);
3965        let (b0, b1) = self.split_i16x16(b);
3966        self.combine_i16x8(self.shrv_i16x8(a0, b0), self.shrv_i16x8(a1, b1))
3967    }
3968    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
3969    #[inline(always)]
3970    fn reduce_max_i16x16(self, a: i16x16<Self>) -> i16 {
3971        let (a0, a1) = self.split_i16x16(a);
3972        self.reduce_max_i16x8(self.max_i16x8(a0, a1))
3973    }
3974    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
3975    #[inline(always)]
3976    fn reduce_min_i16x16(self, a: i16x16<Self>) -> i16 {
3977        let (a0, a1) = self.split_i16x16(a);
3978        self.reduce_min_i16x8(self.min_i16x8(a0, a1))
3979    }
3980    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
3981    #[inline(always)]
3982    fn reduce_sum_i16x16(self, a: i16x16<Self>) -> i16 {
3983        let (a0, a1) = self.split_i16x16(a);
3984        self.reduce_sum_i16x8(self.add_i16x8(a0, a1))
3985    }
3986    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
3987    #[inline(always)]
3988    fn reduce_product_i16x16(self, a: i16x16<Self>) -> i16 {
3989        let (a0, a1) = self.split_i16x16(a);
3990        self.reduce_product_i16x8(self.mul_i16x8(a0, a1))
3991    }
3992    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
3993    #[inline(always)]
3994    fn max_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
3995        let (a0, a1) = self.split_i16x16(a);
3996        let (b0, b1) = self.split_i16x16(b);
3997        self.combine_i16x8(self.max_i16x8(a0, b0), self.max_i16x8(a1, b1))
3998    }
3999    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
4000    #[inline(always)]
4001    fn min_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
4002        let (a0, a1) = self.split_i16x16(a);
4003        let (b0, b1) = self.split_i16x16(b);
4004        self.combine_i16x8(self.min_i16x8(a0, b0), self.min_i16x8(a1, b1))
4005    }
4006    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
4007    #[inline(always)]
4008    fn clamp_i16x16(self, a: i16x16<Self>, b: i16x16<Self>, c: i16x16<Self>) -> i16x16<Self> {
4009        let (a0, a1) = self.split_i16x16(a);
4010        let (b0, b1) = self.split_i16x16(b);
4011        let (c0, c1) = self.split_i16x16(c);
4012        self.combine_i16x8(self.clamp_i16x8(a0, b0, c0), self.clamp_i16x8(a1, b1, c1))
4013    }
4014    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
4015    #[inline(always)]
4016    fn simd_eq_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> mask16x16<Self> {
4017        let (a0, a1) = self.split_i16x16(a);
4018        let (b0, b1) = self.split_i16x16(b);
4019        self.combine_mask16x8(self.simd_eq_i16x8(a0, b0), self.simd_eq_i16x8(a1, b1))
4020    }
4021    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
4022    #[inline(always)]
4023    fn simd_ne_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> mask16x16<Self> {
4024        self.not_mask16x16(self.simd_eq_i16x16(a, b))
4025    }
4026    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
4027    #[inline(always)]
4028    fn simd_lt_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> mask16x16<Self> {
4029        let (a0, a1) = self.split_i16x16(a);
4030        let (b0, b1) = self.split_i16x16(b);
4031        self.combine_mask16x8(self.simd_lt_i16x8(a0, b0), self.simd_lt_i16x8(a1, b1))
4032    }
4033    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
4034    #[inline(always)]
4035    fn simd_le_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> mask16x16<Self> {
4036        let (a0, a1) = self.split_i16x16(a);
4037        let (b0, b1) = self.split_i16x16(b);
4038        self.combine_mask16x8(self.simd_le_i16x8(a0, b0), self.simd_le_i16x8(a1, b1))
4039    }
4040    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
4041    #[inline(always)]
4042    fn simd_ge_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> mask16x16<Self> {
4043        self.simd_le_i16x16(b, a)
4044    }
4045    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
4046    #[inline(always)]
4047    fn simd_gt_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> mask16x16<Self> {
4048        self.simd_lt_i16x16(b, a)
4049    }
4050    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
4051    #[inline(always)]
4052    fn zip_low_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
4053        let (a0, _) = self.split_i16x16(a);
4054        let (b0, _) = self.split_i16x16(b);
4055        self.combine_i16x8(self.zip_low_i16x8(a0, b0), self.zip_high_i16x8(a0, b0))
4056    }
4057    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
4058    #[inline(always)]
4059    fn zip_high_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
4060        let (_, a1) = self.split_i16x16(a);
4061        let (_, b1) = self.split_i16x16(b);
4062        self.combine_i16x8(self.zip_low_i16x8(a1, b1), self.zip_high_i16x8(a1, b1))
4063    }
4064    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
4065    #[inline(always)]
4066    fn unzip_low_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
4067        let (a0, a1) = self.split_i16x16(a);
4068        let (b0, b1) = self.split_i16x16(b);
4069        self.combine_i16x8(self.unzip_low_i16x8(a0, a1), self.unzip_low_i16x8(b0, b1))
4070    }
4071    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
4072    #[inline(always)]
4073    fn unzip_high_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x16<Self> {
4074        let (a0, a1) = self.split_i16x16(a);
4075        let (b0, b1) = self.split_i16x16(b);
4076        self.combine_i16x8(self.unzip_high_i16x8(a0, a1), self.unzip_high_i16x8(b0, b1))
4077    }
4078    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
4079    #[inline(always)]
4080    fn interleave_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> (i16x16<Self>, i16x16<Self>) {
4081        let (a0, a1) = self.split_i16x16(a);
4082        let (b0, b1) = self.split_i16x16(b);
4083        let lo_lo = self.zip_low_i16x8(a0, b0);
4084        let lo_hi = self.zip_high_i16x8(a0, b0);
4085        let hi_lo = self.zip_low_i16x8(a1, b1);
4086        let hi_hi = self.zip_high_i16x8(a1, b1);
4087        (
4088            self.combine_i16x8(lo_lo, lo_hi),
4089            self.combine_i16x8(hi_lo, hi_hi),
4090        )
4091    }
4092    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
4093    #[inline(always)]
4094    fn deinterleave_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> (i16x16<Self>, i16x16<Self>) {
4095        let (a0, a1) = self.split_i16x16(a);
4096        let (b0, b1) = self.split_i16x16(b);
4097        let lo_even = self.unzip_low_i16x8(a0, a1);
4098        let lo_odd = self.unzip_high_i16x8(a0, a1);
4099        let hi_even = self.unzip_low_i16x8(b0, b1);
4100        let hi_odd = self.unzip_high_i16x8(b0, b1);
4101        (
4102            self.combine_i16x8(lo_even, hi_even),
4103            self.combine_i16x8(lo_odd, hi_odd),
4104        )
4105    }
4106    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
4107    #[inline(always)]
4108    fn select_i16x16(self, a: mask16x16<Self>, b: i16x16<Self>, c: i16x16<Self>) -> i16x16<Self> {
4109        let (a0, a1) = self.split_mask16x16(a);
4110        let (b0, b1) = self.split_i16x16(b);
4111        let (c0, c1) = self.split_i16x16(c);
4112        self.combine_i16x8(self.select_i16x8(a0, b0, c0), self.select_i16x8(a1, b1, c1))
4113    }
4114    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
4115    fn combine_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i16x32<Self>;
4116    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
4117    fn split_i16x16(self, a: i16x16<Self>) -> (i16x8<Self>, i16x8<Self>);
4118    #[doc = "Negate each element of the vector, wrapping on overflow."]
4119    #[inline(always)]
4120    fn neg_i16x16(self, a: i16x16<Self>) -> i16x16<Self> {
4121        let (a0, a1) = self.split_i16x16(a);
4122        self.combine_i16x8(self.neg_i16x8(a0), self.neg_i16x8(a1))
4123    }
4124    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
4125    #[inline(always)]
4126    fn widen_i16x16(self, a: i16x16<Self>) -> (i32x8<Self>, i32x8<Self>) {
4127        let (a0, a1) = self.split_i16x16(a);
4128        let (a00, a01) = self.widen_i16x8(a0);
4129        let (a10, a11) = self.widen_i16x8(a1);
4130        (self.combine_i32x4(a00, a01), self.combine_i32x4(a10, a11))
4131    }
4132    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
4133    #[inline(always)]
4134    fn widening_mul_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> (i32x8<Self>, i32x8<Self>) {
4135        let (a0, a1) = self.split_i16x16(a);
4136        let (b0, b1) = self.split_i16x16(b);
4137        let (low0, low1) = self.widening_mul_i16x8(a0, b0);
4138        let (high0, high1) = self.widening_mul_i16x8(a1, b1);
4139        (
4140            self.combine_i32x4(low0, low1),
4141            self.combine_i32x4(high0, high1),
4142        )
4143    }
4144    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
4145    #[inline(always)]
4146    fn widening_add_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> (i32x8<Self>, i32x8<Self>) {
4147        let (a0, a1) = self.split_i16x16(a);
4148        let (b0, b1) = self.split_i16x16(b);
4149        let (low0, low1) = self.widening_add_i16x8(a0, b0);
4150        let (high0, high1) = self.widening_add_i16x8(a1, b1);
4151        (
4152            self.combine_i32x4(low0, low1),
4153            self.combine_i32x4(high0, high1),
4154        )
4155    }
4156    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
4157    #[inline(always)]
4158    fn pairwise_widening_add_i16x16(self, a: i16x16<Self>) -> i32x8<Self> {
4159        let (a0, a1) = self.split_i16x16(a);
4160        self.combine_i32x4(
4161            self.pairwise_widening_add_i16x8(a0),
4162            self.pairwise_widening_add_i16x8(a1),
4163        )
4164    }
4165    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
4166    #[inline(always)]
4167    fn pairwise_dot_product_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i32x8<Self> {
4168        let (a0, a1) = self.split_i16x16(a);
4169        let (b0, b1) = self.split_i16x16(b);
4170        self.combine_i32x4(
4171            self.pairwise_dot_product_i16x8(a0, b0),
4172            self.pairwise_dot_product_i16x8(a1, b1),
4173        )
4174    }
4175    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
4176    #[inline(always)]
4177    fn narrow_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i8x32<Self> {
4178        let (a0, a1) = self.split_i16x16(a);
4179        let (b0, b1) = self.split_i16x16(b);
4180        self.combine_i8x16(self.narrow_i16x8(a0, a1), self.narrow_i16x8(b0, b1))
4181    }
4182    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
4183    #[inline(always)]
4184    fn saturating_narrow_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i8x32<Self> {
4185        let (a0, a1) = self.split_i16x16(a);
4186        let (b0, b1) = self.split_i16x16(b);
4187        self.combine_i8x16(
4188            self.saturating_narrow_i16x8(a0, a1),
4189            self.saturating_narrow_i16x8(b0, b1),
4190        )
4191    }
4192    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
4193    #[inline(always)]
4194    fn relaxed_narrow_i16x16(self, a: i16x16<Self>, b: i16x16<Self>) -> i8x32<Self> {
4195        let (a0, a1) = self.split_i16x16(a);
4196        let (b0, b1) = self.split_i16x16(b);
4197        self.combine_i8x16(
4198            self.relaxed_narrow_i16x8(a0, a1),
4199            self.relaxed_narrow_i16x8(b0, b1),
4200        )
4201    }
4202    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
4203    #[inline(always)]
4204    fn abs_u16x16(self, a: u16x16<Self>) -> u16x16<Self> {
4205        a
4206    }
4207    #[doc = "Create a SIMD vector with all elements set to the given value."]
4208    #[inline(always)]
4209    fn splat_u16x16(self, val: u16) -> u16x16<Self> {
4210        let half = self.splat_u16x8(val);
4211        self.combine_u16x8(half, half)
4212    }
4213    #[doc = "Reverse the order of the vector's elements."]
4214    #[inline(always)]
4215    fn reverse_u16x16(self, a: u16x16<Self>) -> u16x16<Self> {
4216        let (a0, a1) = self.split_u16x16(a);
4217        self.combine_u16x8(self.reverse_u16x8(a1), self.reverse_u16x8(a0))
4218    }
4219    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
4220    fn slide_u16x16<const SHIFT: usize>(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self>;
4221    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
4222    #[inline(always)]
4223    fn slide_within_blocks_u16x16<const SHIFT: usize>(
4224        self,
4225        a: u16x16<Self>,
4226        b: u16x16<Self>,
4227    ) -> u16x16<Self> {
4228        let (a0, a1) = self.split_u16x16(a);
4229        let (b0, b1) = self.split_u16x16(b);
4230        self.combine_u16x8(
4231            self.slide_within_blocks_u16x8::<SHIFT>(a0, b0),
4232            self.slide_within_blocks_u16x8::<SHIFT>(a1, b1),
4233        )
4234    }
4235    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
4236    #[inline(always)]
4237    fn swizzle_dyn_within_blocks_u16x16(
4238        self,
4239        a: u16x16<Self>,
4240        indices: u8x32<Self>,
4241    ) -> u16x16<Self> {
4242        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x32(Bytes::to_bytes(a), indices))
4243    }
4244    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
4245    #[inline(always)]
4246    fn swizzle_dyn_u16x16(self, a: u16x16<Self>, indices: u8x32<Self>) -> u16x16<Self> {
4247        Bytes::from_bytes(self.swizzle_dyn_u8x32(Bytes::to_bytes(a), indices))
4248    }
4249    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
4250    #[inline(always)]
4251    fn swizzle_dyn_precise_u16x16(self, a: u16x16<Self>, indices: u8x32<Self>) -> u16x16<Self> {
4252        Bytes::from_bytes(self.swizzle_dyn_precise_u8x32(Bytes::to_bytes(a), indices))
4253    }
4254    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
4255    #[inline(always)]
4256    fn concat_swizzle_dyn_u16x16(
4257        self,
4258        a: u16x16<Self>,
4259        b: u16x16<Self>,
4260        indices: u8x32<Self>,
4261    ) -> u16x16<Self> {
4262        Bytes::from_bytes(self.concat_swizzle_dyn_u8x32(
4263            Bytes::to_bytes(a),
4264            Bytes::to_bytes(b),
4265            indices,
4266        ))
4267    }
4268    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
4269    #[inline(always)]
4270    fn concat_swizzle_dyn_precise_u16x16(
4271        self,
4272        a: u16x16<Self>,
4273        b: u16x16<Self>,
4274        indices: u8x32<Self>,
4275    ) -> u16x16<Self> {
4276        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x32(
4277            Bytes::to_bytes(a),
4278            Bytes::to_bytes(b),
4279            indices,
4280        ))
4281    }
4282    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
4283    fn compress_u16x16(self, values: u16x16<Self>, mask: mask16x16<Self>) -> u16x16<Self>;
4284    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
4285    fn compress_merge_u16x16(
4286        self,
4287        values: u16x16<Self>,
4288        mask: mask16x16<Self>,
4289        merge: u16x16<Self>,
4290    ) -> u16x16<Self>;
4291    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
4292    fn expand_u16x16(self, values: u16x16<Self>, mask: mask16x16<Self>) -> u16x16<Self>;
4293    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
4294    fn expand_merge_u16x16(
4295        self,
4296        values: u16x16<Self>,
4297        mask: mask16x16<Self>,
4298        merge: u16x16<Self>,
4299    ) -> u16x16<Self>;
4300    #[doc = "Return the number of ones in the binary representation of each element."]
4301    #[inline(always)]
4302    fn count_ones_u16x16(self, a: u16x16<Self>) -> u16x16<Self> {
4303        let (a0, a1) = self.split_u16x16(a);
4304        self.combine_u16x8(self.count_ones_u16x8(a0), self.count_ones_u16x8(a1))
4305    }
4306    #[doc = "Return the number of zeros in the binary representation of each element."]
4307    #[inline(always)]
4308    fn count_zeros_u16x16(self, a: u16x16<Self>) -> u16x16<Self> {
4309        let (a0, a1) = self.split_u16x16(a);
4310        self.combine_u16x8(self.count_zeros_u16x8(a0), self.count_zeros_u16x8(a1))
4311    }
4312    #[doc = "Add two vectors element-wise, wrapping on overflow."]
4313    #[inline(always)]
4314    fn add_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
4315        let (a0, a1) = self.split_u16x16(a);
4316        let (b0, b1) = self.split_u16x16(b);
4317        self.combine_u16x8(self.add_u16x8(a0, b0), self.add_u16x8(a1, b1))
4318    }
4319    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
4320    #[inline(always)]
4321    fn saturating_add_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
4322        let (a0, a1) = self.split_u16x16(a);
4323        let (b0, b1) = self.split_u16x16(b);
4324        self.combine_u16x8(
4325            self.saturating_add_u16x8(a0, b0),
4326            self.saturating_add_u16x8(a1, b1),
4327        )
4328    }
4329    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
4330    #[inline(always)]
4331    fn sub_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
4332        let (a0, a1) = self.split_u16x16(a);
4333        let (b0, b1) = self.split_u16x16(b);
4334        self.combine_u16x8(self.sub_u16x8(a0, b0), self.sub_u16x8(a1, b1))
4335    }
4336    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
4337    #[inline(always)]
4338    fn saturating_sub_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
4339        let (a0, a1) = self.split_u16x16(a);
4340        let (b0, b1) = self.split_u16x16(b);
4341        self.combine_u16x8(
4342            self.saturating_sub_u16x8(a0, b0),
4343            self.saturating_sub_u16x8(a1, b1),
4344        )
4345    }
4346    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
4347    #[inline(always)]
4348    fn mul_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
4349        let (a0, a1) = self.split_u16x16(a);
4350        let (b0, b1) = self.split_u16x16(b);
4351        self.combine_u16x8(self.mul_u16x8(a0, b0), self.mul_u16x8(a1, b1))
4352    }
4353    #[doc = "Compute the bitwise AND of two vectors."]
4354    #[inline(always)]
4355    fn and_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
4356        let (a0, a1) = self.split_u16x16(a);
4357        let (b0, b1) = self.split_u16x16(b);
4358        self.combine_u16x8(self.and_u16x8(a0, b0), self.and_u16x8(a1, b1))
4359    }
4360    #[doc = "Compute the bitwise OR of two vectors."]
4361    #[inline(always)]
4362    fn or_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
4363        let (a0, a1) = self.split_u16x16(a);
4364        let (b0, b1) = self.split_u16x16(b);
4365        self.combine_u16x8(self.or_u16x8(a0, b0), self.or_u16x8(a1, b1))
4366    }
4367    #[doc = "Compute the bitwise XOR of two vectors."]
4368    #[inline(always)]
4369    fn xor_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
4370        let (a0, a1) = self.split_u16x16(a);
4371        let (b0, b1) = self.split_u16x16(b);
4372        self.combine_u16x8(self.xor_u16x8(a0, b0), self.xor_u16x8(a1, b1))
4373    }
4374    #[doc = "Compute the bitwise NOT of the vector."]
4375    #[inline(always)]
4376    fn not_u16x16(self, a: u16x16<Self>) -> u16x16<Self> {
4377        let (a0, a1) = self.split_u16x16(a);
4378        self.combine_u16x8(self.not_u16x8(a0), self.not_u16x8(a1))
4379    }
4380    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
4381    #[inline(always)]
4382    fn shl_u16x16(self, a: u16x16<Self>, shift: u32) -> u16x16<Self> {
4383        let (a0, a1) = self.split_u16x16(a);
4384        self.combine_u16x8(self.shl_u16x8(a0, shift), self.shl_u16x8(a1, shift))
4385    }
4386    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
4387    #[inline(always)]
4388    fn shlv_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
4389        let (a0, a1) = self.split_u16x16(a);
4390        let (b0, b1) = self.split_u16x16(b);
4391        self.combine_u16x8(self.shlv_u16x8(a0, b0), self.shlv_u16x8(a1, b1))
4392    }
4393    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
4394    #[inline(always)]
4395    fn shr_u16x16(self, a: u16x16<Self>, shift: u32) -> u16x16<Self> {
4396        let (a0, a1) = self.split_u16x16(a);
4397        self.combine_u16x8(self.shr_u16x8(a0, shift), self.shr_u16x8(a1, shift))
4398    }
4399    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
4400    #[inline(always)]
4401    fn shrv_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
4402        let (a0, a1) = self.split_u16x16(a);
4403        let (b0, b1) = self.split_u16x16(b);
4404        self.combine_u16x8(self.shrv_u16x8(a0, b0), self.shrv_u16x8(a1, b1))
4405    }
4406    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
4407    #[inline(always)]
4408    fn reduce_max_u16x16(self, a: u16x16<Self>) -> u16 {
4409        let (a0, a1) = self.split_u16x16(a);
4410        self.reduce_max_u16x8(self.max_u16x8(a0, a1))
4411    }
4412    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
4413    #[inline(always)]
4414    fn reduce_min_u16x16(self, a: u16x16<Self>) -> u16 {
4415        let (a0, a1) = self.split_u16x16(a);
4416        self.reduce_min_u16x8(self.min_u16x8(a0, a1))
4417    }
4418    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
4419    #[inline(always)]
4420    fn reduce_sum_u16x16(self, a: u16x16<Self>) -> u16 {
4421        let (a0, a1) = self.split_u16x16(a);
4422        self.reduce_sum_u16x8(self.add_u16x8(a0, a1))
4423    }
4424    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
4425    #[inline(always)]
4426    fn reduce_product_u16x16(self, a: u16x16<Self>) -> u16 {
4427        let (a0, a1) = self.split_u16x16(a);
4428        self.reduce_product_u16x8(self.mul_u16x8(a0, a1))
4429    }
4430    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
4431    #[inline(always)]
4432    fn max_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
4433        let (a0, a1) = self.split_u16x16(a);
4434        let (b0, b1) = self.split_u16x16(b);
4435        self.combine_u16x8(self.max_u16x8(a0, b0), self.max_u16x8(a1, b1))
4436    }
4437    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
4438    #[inline(always)]
4439    fn min_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
4440        let (a0, a1) = self.split_u16x16(a);
4441        let (b0, b1) = self.split_u16x16(b);
4442        self.combine_u16x8(self.min_u16x8(a0, b0), self.min_u16x8(a1, b1))
4443    }
4444    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
4445    #[inline(always)]
4446    fn clamp_u16x16(self, a: u16x16<Self>, b: u16x16<Self>, c: u16x16<Self>) -> u16x16<Self> {
4447        let (a0, a1) = self.split_u16x16(a);
4448        let (b0, b1) = self.split_u16x16(b);
4449        let (c0, c1) = self.split_u16x16(c);
4450        self.combine_u16x8(self.clamp_u16x8(a0, b0, c0), self.clamp_u16x8(a1, b1, c1))
4451    }
4452    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
4453    #[inline(always)]
4454    fn simd_eq_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> mask16x16<Self> {
4455        let (a0, a1) = self.split_u16x16(a);
4456        let (b0, b1) = self.split_u16x16(b);
4457        self.combine_mask16x8(self.simd_eq_u16x8(a0, b0), self.simd_eq_u16x8(a1, b1))
4458    }
4459    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
4460    #[inline(always)]
4461    fn simd_ne_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> mask16x16<Self> {
4462        self.not_mask16x16(self.simd_eq_u16x16(a, b))
4463    }
4464    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
4465    #[inline(always)]
4466    fn simd_lt_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> mask16x16<Self> {
4467        let (a0, a1) = self.split_u16x16(a);
4468        let (b0, b1) = self.split_u16x16(b);
4469        self.combine_mask16x8(self.simd_lt_u16x8(a0, b0), self.simd_lt_u16x8(a1, b1))
4470    }
4471    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
4472    #[inline(always)]
4473    fn simd_le_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> mask16x16<Self> {
4474        let (a0, a1) = self.split_u16x16(a);
4475        let (b0, b1) = self.split_u16x16(b);
4476        self.combine_mask16x8(self.simd_le_u16x8(a0, b0), self.simd_le_u16x8(a1, b1))
4477    }
4478    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
4479    #[inline(always)]
4480    fn simd_ge_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> mask16x16<Self> {
4481        self.simd_le_u16x16(b, a)
4482    }
4483    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
4484    #[inline(always)]
4485    fn simd_gt_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> mask16x16<Self> {
4486        self.simd_lt_u16x16(b, a)
4487    }
4488    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
4489    #[inline(always)]
4490    fn zip_low_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
4491        let (a0, _) = self.split_u16x16(a);
4492        let (b0, _) = self.split_u16x16(b);
4493        self.combine_u16x8(self.zip_low_u16x8(a0, b0), self.zip_high_u16x8(a0, b0))
4494    }
4495    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
4496    #[inline(always)]
4497    fn zip_high_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
4498        let (_, a1) = self.split_u16x16(a);
4499        let (_, b1) = self.split_u16x16(b);
4500        self.combine_u16x8(self.zip_low_u16x8(a1, b1), self.zip_high_u16x8(a1, b1))
4501    }
4502    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
4503    #[inline(always)]
4504    fn unzip_low_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
4505        let (a0, a1) = self.split_u16x16(a);
4506        let (b0, b1) = self.split_u16x16(b);
4507        self.combine_u16x8(self.unzip_low_u16x8(a0, a1), self.unzip_low_u16x8(b0, b1))
4508    }
4509    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
4510    #[inline(always)]
4511    fn unzip_high_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x16<Self> {
4512        let (a0, a1) = self.split_u16x16(a);
4513        let (b0, b1) = self.split_u16x16(b);
4514        self.combine_u16x8(self.unzip_high_u16x8(a0, a1), self.unzip_high_u16x8(b0, b1))
4515    }
4516    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
4517    #[inline(always)]
4518    fn interleave_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> (u16x16<Self>, u16x16<Self>) {
4519        let (a0, a1) = self.split_u16x16(a);
4520        let (b0, b1) = self.split_u16x16(b);
4521        let lo_lo = self.zip_low_u16x8(a0, b0);
4522        let lo_hi = self.zip_high_u16x8(a0, b0);
4523        let hi_lo = self.zip_low_u16x8(a1, b1);
4524        let hi_hi = self.zip_high_u16x8(a1, b1);
4525        (
4526            self.combine_u16x8(lo_lo, lo_hi),
4527            self.combine_u16x8(hi_lo, hi_hi),
4528        )
4529    }
4530    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
4531    #[inline(always)]
4532    fn deinterleave_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> (u16x16<Self>, u16x16<Self>) {
4533        let (a0, a1) = self.split_u16x16(a);
4534        let (b0, b1) = self.split_u16x16(b);
4535        let lo_even = self.unzip_low_u16x8(a0, a1);
4536        let lo_odd = self.unzip_high_u16x8(a0, a1);
4537        let hi_even = self.unzip_low_u16x8(b0, b1);
4538        let hi_odd = self.unzip_high_u16x8(b0, b1);
4539        (
4540            self.combine_u16x8(lo_even, hi_even),
4541            self.combine_u16x8(lo_odd, hi_odd),
4542        )
4543    }
4544    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
4545    #[inline(always)]
4546    fn select_u16x16(self, a: mask16x16<Self>, b: u16x16<Self>, c: u16x16<Self>) -> u16x16<Self> {
4547        let (a0, a1) = self.split_mask16x16(a);
4548        let (b0, b1) = self.split_u16x16(b);
4549        let (c0, c1) = self.split_u16x16(c);
4550        self.combine_u16x8(self.select_u16x8(a0, b0, c0), self.select_u16x8(a1, b1, c1))
4551    }
4552    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
4553    fn combine_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u16x32<Self>;
4554    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
4555    fn split_u16x16(self, a: u16x16<Self>) -> (u16x8<Self>, u16x8<Self>);
4556    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
4557    #[inline(always)]
4558    fn widen_u16x16(self, a: u16x16<Self>) -> (u32x8<Self>, u32x8<Self>) {
4559        let (a0, a1) = self.split_u16x16(a);
4560        let (a00, a01) = self.widen_u16x8(a0);
4561        let (a10, a11) = self.widen_u16x8(a1);
4562        (self.combine_u32x4(a00, a01), self.combine_u32x4(a10, a11))
4563    }
4564    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
4565    #[inline(always)]
4566    fn widening_mul_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> (u32x8<Self>, u32x8<Self>) {
4567        let (a0, a1) = self.split_u16x16(a);
4568        let (b0, b1) = self.split_u16x16(b);
4569        let (low0, low1) = self.widening_mul_u16x8(a0, b0);
4570        let (high0, high1) = self.widening_mul_u16x8(a1, b1);
4571        (
4572            self.combine_u32x4(low0, low1),
4573            self.combine_u32x4(high0, high1),
4574        )
4575    }
4576    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
4577    #[inline(always)]
4578    fn widening_add_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> (u32x8<Self>, u32x8<Self>) {
4579        let (a0, a1) = self.split_u16x16(a);
4580        let (b0, b1) = self.split_u16x16(b);
4581        let (low0, low1) = self.widening_add_u16x8(a0, b0);
4582        let (high0, high1) = self.widening_add_u16x8(a1, b1);
4583        (
4584            self.combine_u32x4(low0, low1),
4585            self.combine_u32x4(high0, high1),
4586        )
4587    }
4588    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
4589    #[inline(always)]
4590    fn pairwise_widening_add_u16x16(self, a: u16x16<Self>) -> u32x8<Self> {
4591        let (a0, a1) = self.split_u16x16(a);
4592        self.combine_u32x4(
4593            self.pairwise_widening_add_u16x8(a0),
4594            self.pairwise_widening_add_u16x8(a1),
4595        )
4596    }
4597    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
4598    #[inline(always)]
4599    fn pairwise_dot_product_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u32x8<Self> {
4600        let (a0, a1) = self.split_u16x16(a);
4601        let (b0, b1) = self.split_u16x16(b);
4602        self.combine_u32x4(
4603            self.pairwise_dot_product_u16x8(a0, b0),
4604            self.pairwise_dot_product_u16x8(a1, b1),
4605        )
4606    }
4607    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
4608    #[inline(always)]
4609    fn narrow_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u8x32<Self> {
4610        let (a0, a1) = self.split_u16x16(a);
4611        let (b0, b1) = self.split_u16x16(b);
4612        self.combine_u8x16(self.narrow_u16x8(a0, a1), self.narrow_u16x8(b0, b1))
4613    }
4614    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
4615    #[inline(always)]
4616    fn saturating_narrow_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u8x32<Self> {
4617        let (a0, a1) = self.split_u16x16(a);
4618        let (b0, b1) = self.split_u16x16(b);
4619        self.combine_u8x16(
4620            self.saturating_narrow_u16x8(a0, a1),
4621            self.saturating_narrow_u16x8(b0, b1),
4622        )
4623    }
4624    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
4625    #[inline(always)]
4626    fn relaxed_narrow_u16x16(self, a: u16x16<Self>, b: u16x16<Self>) -> u8x32<Self> {
4627        let (a0, a1) = self.split_u16x16(a);
4628        let (b0, b1) = self.split_u16x16(b);
4629        self.combine_u8x16(
4630            self.relaxed_narrow_u16x8(a0, a1),
4631            self.relaxed_narrow_u16x8(b0, b1),
4632        )
4633    }
4634    #[doc = "Create a SIMD mask with all lanes set from the given boolean value."]
4635    #[inline(always)]
4636    fn splat_mask16x16(self, val: bool) -> mask16x16<Self> {
4637        let half = self.splat_mask16x8(val);
4638        self.combine_mask16x8(half, half)
4639    }
4640    #[doc = "Create a SIMD mask from a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are ignored."]
4641    #[inline(always)]
4642    fn from_bitmask_mask16x16(self, bits: u64) -> mask16x16<Self> {
4643        let lo = self.from_bitmask_mask16x8(bits);
4644        let hi = self.from_bitmask_mask16x8(bits >> 8usize);
4645        self.combine_mask16x8(lo, hi)
4646    }
4647    #[doc = "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared."]
4648    #[inline(always)]
4649    fn to_bitmask_mask16x16(self, a: mask16x16<Self>) -> u64 {
4650        let (lo, hi) = self.split_mask16x16(a);
4651        let lo = self.to_bitmask_mask16x8(lo);
4652        let hi = self.to_bitmask_mask16x8(hi);
4653        lo | (hi << 8usize)
4654    }
4655    #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."]
4656    fn from_vector_mask16x16(self, vector: i16x16<Self>) -> mask16x16<Self>;
4657    #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."]
4658    fn to_vector_mask16x16(self, a: mask16x16<Self>) -> i16x16<Self>;
4659    #[doc = "Set one logical lane of a SIMD mask."]
4660    fn set_mask16x16(self, a: &mut mask16x16<Self>, index: usize, value: bool) -> ();
4661    #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
4662    fn rotate_elements_left_mask16x16<const OFFSET: usize>(
4663        self,
4664        a: mask16x16<Self>,
4665    ) -> mask16x16<Self>;
4666    #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
4667    fn rotate_elements_right_mask16x16<const OFFSET: usize>(
4668        self,
4669        a: mask16x16<Self>,
4670    ) -> mask16x16<Self>;
4671    #[doc = "Compute the logical AND of two masks."]
4672    #[inline(always)]
4673    fn and_mask16x16(self, a: mask16x16<Self>, b: mask16x16<Self>) -> mask16x16<Self> {
4674        let (a0, a1) = self.split_mask16x16(a);
4675        let (b0, b1) = self.split_mask16x16(b);
4676        self.combine_mask16x8(self.and_mask16x8(a0, b0), self.and_mask16x8(a1, b1))
4677    }
4678    #[doc = "Compute the logical OR of two masks."]
4679    #[inline(always)]
4680    fn or_mask16x16(self, a: mask16x16<Self>, b: mask16x16<Self>) -> mask16x16<Self> {
4681        let (a0, a1) = self.split_mask16x16(a);
4682        let (b0, b1) = self.split_mask16x16(b);
4683        self.combine_mask16x8(self.or_mask16x8(a0, b0), self.or_mask16x8(a1, b1))
4684    }
4685    #[doc = "Compute the logical XOR of two masks."]
4686    #[inline(always)]
4687    fn xor_mask16x16(self, a: mask16x16<Self>, b: mask16x16<Self>) -> mask16x16<Self> {
4688        let (a0, a1) = self.split_mask16x16(a);
4689        let (b0, b1) = self.split_mask16x16(b);
4690        self.combine_mask16x8(self.xor_mask16x8(a0, b0), self.xor_mask16x8(a1, b1))
4691    }
4692    #[doc = "Compute the logical NOT of the mask."]
4693    #[inline(always)]
4694    fn not_mask16x16(self, a: mask16x16<Self>) -> mask16x16<Self> {
4695        let (a0, a1) = self.split_mask16x16(a);
4696        self.combine_mask16x8(self.not_mask16x8(a0), self.not_mask16x8(a1))
4697    }
4698    #[doc = "Reverse the order of the mask's logical lanes."]
4699    #[inline(always)]
4700    fn reverse_mask16x16(self, a: mask16x16<Self>) -> mask16x16<Self> {
4701        let (a0, a1) = self.split_mask16x16(a);
4702        self.combine_mask16x8(self.reverse_mask16x8(a1), self.reverse_mask16x8(a0))
4703    }
4704    #[doc = "Select elements from `b` and `c` based on the mask operand `a`.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
4705    #[inline(always)]
4706    fn select_mask16x16(
4707        self,
4708        a: mask16x16<Self>,
4709        b: mask16x16<Self>,
4710        c: mask16x16<Self>,
4711    ) -> mask16x16<Self> {
4712        let (a0, a1) = self.split_mask16x16(a);
4713        let (b0, b1) = self.split_mask16x16(b);
4714        let (c0, c1) = self.split_mask16x16(c);
4715        self.combine_mask16x8(
4716            self.select_mask16x8(a0, b0, c0),
4717            self.select_mask16x8(a1, b1, c1),
4718        )
4719    }
4720    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
4721    #[inline(always)]
4722    fn simd_eq_mask16x16(self, a: mask16x16<Self>, b: mask16x16<Self>) -> mask16x16<Self> {
4723        let (a0, a1) = self.split_mask16x16(a);
4724        let (b0, b1) = self.split_mask16x16(b);
4725        self.combine_mask16x8(self.simd_eq_mask16x8(a0, b0), self.simd_eq_mask16x8(a1, b1))
4726    }
4727    #[doc = "Compare two masks element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
4728    #[inline(always)]
4729    fn simd_ne_mask16x16(self, a: mask16x16<Self>, b: mask16x16<Self>) -> mask16x16<Self> {
4730        self.not_mask16x16(self.simd_eq_mask16x16(a, b))
4731    }
4732    #[doc = "Returns true if any logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
4733    #[inline(always)]
4734    fn any_true_mask16x16(self, a: mask16x16<Self>) -> bool {
4735        let (a0, a1) = self.split_mask16x16(a);
4736        self.any_true_mask16x8(self.or_mask16x8(a0, a1))
4737    }
4738    #[doc = "Returns true if all logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
4739    #[inline(always)]
4740    fn all_true_mask16x16(self, a: mask16x16<Self>) -> bool {
4741        let (a0, a1) = self.split_mask16x16(a);
4742        self.all_true_mask16x8(self.and_mask16x8(a0, a1))
4743    }
4744    #[doc = "Returns true if any logical lanes in this mask are false.\n\nThis is logically equivalent to `!all_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
4745    #[inline(always)]
4746    fn any_false_mask16x16(self, a: mask16x16<Self>) -> bool {
4747        let (a0, a1) = self.split_mask16x16(a);
4748        self.any_false_mask16x8(self.and_mask16x8(a0, a1))
4749    }
4750    #[doc = "Returns true if all logical lanes in this mask are false.\n\nThis is logically equivalent to `!any_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
4751    #[inline(always)]
4752    fn all_false_mask16x16(self, a: mask16x16<Self>) -> bool {
4753        let (a0, a1) = self.split_mask16x16(a);
4754        self.all_false_mask16x8(self.or_mask16x8(a0, a1))
4755    }
4756    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
4757    fn combine_mask16x16(self, a: mask16x16<Self>, b: mask16x16<Self>) -> mask16x32<Self>;
4758    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
4759    fn split_mask16x16(self, a: mask16x16<Self>) -> (mask16x8<Self>, mask16x8<Self>);
4760    #[doc = "Widen each boolean lane into two masks of the same logical width, preserving its value.\n\nThe first result contains the lower lanes and the second contains the upper lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
4761    #[inline(always)]
4762    fn widen_mask16x16(self, a: mask16x16<Self>) -> (mask32x8<Self>, mask32x8<Self>) {
4763        let (a0, a1) = self.split_mask16x16(a);
4764        let (a00, a01) = self.widen_mask16x8(a0);
4765        let (a10, a11) = self.widen_mask16x8(a1);
4766        (
4767            self.combine_mask32x4(a00, a01),
4768            self.combine_mask32x4(a10, a11),
4769        )
4770    }
4771    #[doc = "Narrow each boolean lane of two masks and concatenate them into one mask of the same logical width, preserving each value.\n\n`a` supplies the lower result lanes and `b` supplies the upper result lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
4772    #[inline(always)]
4773    fn narrow_mask16x16(self, a: mask16x16<Self>, b: mask16x16<Self>) -> mask8x32<Self> {
4774        let (a0, a1) = self.split_mask16x16(a);
4775        let (b0, b1) = self.split_mask16x16(b);
4776        self.combine_mask8x16(self.narrow_mask16x8(a0, a1), self.narrow_mask16x8(b0, b1))
4777    }
4778    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
4779    #[inline(always)]
4780    fn abs_i32x8(self, a: i32x8<Self>) -> i32x8<Self> {
4781        let (a0, a1) = self.split_i32x8(a);
4782        self.combine_i32x4(self.abs_i32x4(a0), self.abs_i32x4(a1))
4783    }
4784    #[doc = "Create a SIMD vector with all elements set to the given value."]
4785    #[inline(always)]
4786    fn splat_i32x8(self, val: i32) -> i32x8<Self> {
4787        let half = self.splat_i32x4(val);
4788        self.combine_i32x4(half, half)
4789    }
4790    #[doc = "Reverse the order of the vector's elements."]
4791    #[inline(always)]
4792    fn reverse_i32x8(self, a: i32x8<Self>) -> i32x8<Self> {
4793        let (a0, a1) = self.split_i32x8(a);
4794        self.combine_i32x4(self.reverse_i32x4(a1), self.reverse_i32x4(a0))
4795    }
4796    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
4797    fn slide_i32x8<const SHIFT: usize>(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self>;
4798    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
4799    #[inline(always)]
4800    fn slide_within_blocks_i32x8<const SHIFT: usize>(
4801        self,
4802        a: i32x8<Self>,
4803        b: i32x8<Self>,
4804    ) -> i32x8<Self> {
4805        let (a0, a1) = self.split_i32x8(a);
4806        let (b0, b1) = self.split_i32x8(b);
4807        self.combine_i32x4(
4808            self.slide_within_blocks_i32x4::<SHIFT>(a0, b0),
4809            self.slide_within_blocks_i32x4::<SHIFT>(a1, b1),
4810        )
4811    }
4812    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
4813    #[inline(always)]
4814    fn swizzle_dyn_within_blocks_i32x8(self, a: i32x8<Self>, indices: u8x32<Self>) -> i32x8<Self> {
4815        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x32(Bytes::to_bytes(a), indices))
4816    }
4817    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
4818    #[inline(always)]
4819    fn swizzle_dyn_i32x8(self, a: i32x8<Self>, indices: u8x32<Self>) -> i32x8<Self> {
4820        Bytes::from_bytes(self.swizzle_dyn_u8x32(Bytes::to_bytes(a), indices))
4821    }
4822    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
4823    #[inline(always)]
4824    fn swizzle_dyn_precise_i32x8(self, a: i32x8<Self>, indices: u8x32<Self>) -> i32x8<Self> {
4825        Bytes::from_bytes(self.swizzle_dyn_precise_u8x32(Bytes::to_bytes(a), indices))
4826    }
4827    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
4828    #[inline(always)]
4829    fn concat_swizzle_dyn_i32x8(
4830        self,
4831        a: i32x8<Self>,
4832        b: i32x8<Self>,
4833        indices: u8x32<Self>,
4834    ) -> i32x8<Self> {
4835        Bytes::from_bytes(self.concat_swizzle_dyn_u8x32(
4836            Bytes::to_bytes(a),
4837            Bytes::to_bytes(b),
4838            indices,
4839        ))
4840    }
4841    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
4842    #[inline(always)]
4843    fn concat_swizzle_dyn_precise_i32x8(
4844        self,
4845        a: i32x8<Self>,
4846        b: i32x8<Self>,
4847        indices: u8x32<Self>,
4848    ) -> i32x8<Self> {
4849        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x32(
4850            Bytes::to_bytes(a),
4851            Bytes::to_bytes(b),
4852            indices,
4853        ))
4854    }
4855    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
4856    fn compress_i32x8(self, values: i32x8<Self>, mask: mask32x8<Self>) -> i32x8<Self>;
4857    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
4858    fn compress_merge_i32x8(
4859        self,
4860        values: i32x8<Self>,
4861        mask: mask32x8<Self>,
4862        merge: i32x8<Self>,
4863    ) -> i32x8<Self>;
4864    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
4865    fn expand_i32x8(self, values: i32x8<Self>, mask: mask32x8<Self>) -> i32x8<Self>;
4866    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
4867    fn expand_merge_i32x8(
4868        self,
4869        values: i32x8<Self>,
4870        mask: mask32x8<Self>,
4871        merge: i32x8<Self>,
4872    ) -> i32x8<Self>;
4873    #[doc = "Return the number of ones in the binary representation of each element."]
4874    #[inline(always)]
4875    fn count_ones_i32x8(self, a: i32x8<Self>) -> i32x8<Self> {
4876        let (a0, a1) = self.split_i32x8(a);
4877        self.combine_i32x4(self.count_ones_i32x4(a0), self.count_ones_i32x4(a1))
4878    }
4879    #[doc = "Return the number of zeros in the binary representation of each element."]
4880    #[inline(always)]
4881    fn count_zeros_i32x8(self, a: i32x8<Self>) -> i32x8<Self> {
4882        let (a0, a1) = self.split_i32x8(a);
4883        self.combine_i32x4(self.count_zeros_i32x4(a0), self.count_zeros_i32x4(a1))
4884    }
4885    #[doc = "Add two vectors element-wise, wrapping on overflow."]
4886    #[inline(always)]
4887    fn add_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
4888        let (a0, a1) = self.split_i32x8(a);
4889        let (b0, b1) = self.split_i32x8(b);
4890        self.combine_i32x4(self.add_i32x4(a0, b0), self.add_i32x4(a1, b1))
4891    }
4892    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
4893    #[inline(always)]
4894    fn saturating_add_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
4895        let (a0, a1) = self.split_i32x8(a);
4896        let (b0, b1) = self.split_i32x8(b);
4897        self.combine_i32x4(
4898            self.saturating_add_i32x4(a0, b0),
4899            self.saturating_add_i32x4(a1, b1),
4900        )
4901    }
4902    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
4903    #[inline(always)]
4904    fn sub_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
4905        let (a0, a1) = self.split_i32x8(a);
4906        let (b0, b1) = self.split_i32x8(b);
4907        self.combine_i32x4(self.sub_i32x4(a0, b0), self.sub_i32x4(a1, b1))
4908    }
4909    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
4910    #[inline(always)]
4911    fn saturating_sub_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
4912        let (a0, a1) = self.split_i32x8(a);
4913        let (b0, b1) = self.split_i32x8(b);
4914        self.combine_i32x4(
4915            self.saturating_sub_i32x4(a0, b0),
4916            self.saturating_sub_i32x4(a1, b1),
4917        )
4918    }
4919    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
4920    #[inline(always)]
4921    fn mul_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
4922        let (a0, a1) = self.split_i32x8(a);
4923        let (b0, b1) = self.split_i32x8(b);
4924        self.combine_i32x4(self.mul_i32x4(a0, b0), self.mul_i32x4(a1, b1))
4925    }
4926    #[doc = "Compute the bitwise AND of two vectors."]
4927    #[inline(always)]
4928    fn and_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
4929        let (a0, a1) = self.split_i32x8(a);
4930        let (b0, b1) = self.split_i32x8(b);
4931        self.combine_i32x4(self.and_i32x4(a0, b0), self.and_i32x4(a1, b1))
4932    }
4933    #[doc = "Compute the bitwise OR of two vectors."]
4934    #[inline(always)]
4935    fn or_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
4936        let (a0, a1) = self.split_i32x8(a);
4937        let (b0, b1) = self.split_i32x8(b);
4938        self.combine_i32x4(self.or_i32x4(a0, b0), self.or_i32x4(a1, b1))
4939    }
4940    #[doc = "Compute the bitwise XOR of two vectors."]
4941    #[inline(always)]
4942    fn xor_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
4943        let (a0, a1) = self.split_i32x8(a);
4944        let (b0, b1) = self.split_i32x8(b);
4945        self.combine_i32x4(self.xor_i32x4(a0, b0), self.xor_i32x4(a1, b1))
4946    }
4947    #[doc = "Compute the bitwise NOT of the vector."]
4948    #[inline(always)]
4949    fn not_i32x8(self, a: i32x8<Self>) -> i32x8<Self> {
4950        let (a0, a1) = self.split_i32x8(a);
4951        self.combine_i32x4(self.not_i32x4(a0), self.not_i32x4(a1))
4952    }
4953    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
4954    #[inline(always)]
4955    fn shl_i32x8(self, a: i32x8<Self>, shift: u32) -> i32x8<Self> {
4956        let (a0, a1) = self.split_i32x8(a);
4957        self.combine_i32x4(self.shl_i32x4(a0, shift), self.shl_i32x4(a1, shift))
4958    }
4959    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
4960    #[inline(always)]
4961    fn shlv_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
4962        let (a0, a1) = self.split_i32x8(a);
4963        let (b0, b1) = self.split_i32x8(b);
4964        self.combine_i32x4(self.shlv_i32x4(a0, b0), self.shlv_i32x4(a1, b1))
4965    }
4966    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
4967    #[inline(always)]
4968    fn shr_i32x8(self, a: i32x8<Self>, shift: u32) -> i32x8<Self> {
4969        let (a0, a1) = self.split_i32x8(a);
4970        self.combine_i32x4(self.shr_i32x4(a0, shift), self.shr_i32x4(a1, shift))
4971    }
4972    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
4973    #[inline(always)]
4974    fn shrv_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
4975        let (a0, a1) = self.split_i32x8(a);
4976        let (b0, b1) = self.split_i32x8(b);
4977        self.combine_i32x4(self.shrv_i32x4(a0, b0), self.shrv_i32x4(a1, b1))
4978    }
4979    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
4980    #[inline(always)]
4981    fn reduce_max_i32x8(self, a: i32x8<Self>) -> i32 {
4982        let (a0, a1) = self.split_i32x8(a);
4983        self.reduce_max_i32x4(self.max_i32x4(a0, a1))
4984    }
4985    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
4986    #[inline(always)]
4987    fn reduce_min_i32x8(self, a: i32x8<Self>) -> i32 {
4988        let (a0, a1) = self.split_i32x8(a);
4989        self.reduce_min_i32x4(self.min_i32x4(a0, a1))
4990    }
4991    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
4992    #[inline(always)]
4993    fn reduce_sum_i32x8(self, a: i32x8<Self>) -> i32 {
4994        let (a0, a1) = self.split_i32x8(a);
4995        self.reduce_sum_i32x4(self.add_i32x4(a0, a1))
4996    }
4997    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
4998    #[inline(always)]
4999    fn reduce_product_i32x8(self, a: i32x8<Self>) -> i32 {
5000        let (a0, a1) = self.split_i32x8(a);
5001        self.reduce_product_i32x4(self.mul_i32x4(a0, a1))
5002    }
5003    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
5004    #[inline(always)]
5005    fn max_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
5006        let (a0, a1) = self.split_i32x8(a);
5007        let (b0, b1) = self.split_i32x8(b);
5008        self.combine_i32x4(self.max_i32x4(a0, b0), self.max_i32x4(a1, b1))
5009    }
5010    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
5011    #[inline(always)]
5012    fn min_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
5013        let (a0, a1) = self.split_i32x8(a);
5014        let (b0, b1) = self.split_i32x8(b);
5015        self.combine_i32x4(self.min_i32x4(a0, b0), self.min_i32x4(a1, b1))
5016    }
5017    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
5018    #[inline(always)]
5019    fn clamp_i32x8(self, a: i32x8<Self>, b: i32x8<Self>, c: i32x8<Self>) -> i32x8<Self> {
5020        let (a0, a1) = self.split_i32x8(a);
5021        let (b0, b1) = self.split_i32x8(b);
5022        let (c0, c1) = self.split_i32x8(c);
5023        self.combine_i32x4(self.clamp_i32x4(a0, b0, c0), self.clamp_i32x4(a1, b1, c1))
5024    }
5025    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
5026    #[inline(always)]
5027    fn simd_eq_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> mask32x8<Self> {
5028        let (a0, a1) = self.split_i32x8(a);
5029        let (b0, b1) = self.split_i32x8(b);
5030        self.combine_mask32x4(self.simd_eq_i32x4(a0, b0), self.simd_eq_i32x4(a1, b1))
5031    }
5032    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
5033    #[inline(always)]
5034    fn simd_ne_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> mask32x8<Self> {
5035        self.not_mask32x8(self.simd_eq_i32x8(a, b))
5036    }
5037    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
5038    #[inline(always)]
5039    fn simd_lt_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> mask32x8<Self> {
5040        let (a0, a1) = self.split_i32x8(a);
5041        let (b0, b1) = self.split_i32x8(b);
5042        self.combine_mask32x4(self.simd_lt_i32x4(a0, b0), self.simd_lt_i32x4(a1, b1))
5043    }
5044    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
5045    #[inline(always)]
5046    fn simd_le_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> mask32x8<Self> {
5047        let (a0, a1) = self.split_i32x8(a);
5048        let (b0, b1) = self.split_i32x8(b);
5049        self.combine_mask32x4(self.simd_le_i32x4(a0, b0), self.simd_le_i32x4(a1, b1))
5050    }
5051    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
5052    #[inline(always)]
5053    fn simd_ge_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> mask32x8<Self> {
5054        self.simd_le_i32x8(b, a)
5055    }
5056    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
5057    #[inline(always)]
5058    fn simd_gt_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> mask32x8<Self> {
5059        self.simd_lt_i32x8(b, a)
5060    }
5061    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
5062    #[inline(always)]
5063    fn zip_low_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
5064        let (a0, _) = self.split_i32x8(a);
5065        let (b0, _) = self.split_i32x8(b);
5066        self.combine_i32x4(self.zip_low_i32x4(a0, b0), self.zip_high_i32x4(a0, b0))
5067    }
5068    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
5069    #[inline(always)]
5070    fn zip_high_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
5071        let (_, a1) = self.split_i32x8(a);
5072        let (_, b1) = self.split_i32x8(b);
5073        self.combine_i32x4(self.zip_low_i32x4(a1, b1), self.zip_high_i32x4(a1, b1))
5074    }
5075    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
5076    #[inline(always)]
5077    fn unzip_low_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
5078        let (a0, a1) = self.split_i32x8(a);
5079        let (b0, b1) = self.split_i32x8(b);
5080        self.combine_i32x4(self.unzip_low_i32x4(a0, a1), self.unzip_low_i32x4(b0, b1))
5081    }
5082    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
5083    #[inline(always)]
5084    fn unzip_high_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x8<Self> {
5085        let (a0, a1) = self.split_i32x8(a);
5086        let (b0, b1) = self.split_i32x8(b);
5087        self.combine_i32x4(self.unzip_high_i32x4(a0, a1), self.unzip_high_i32x4(b0, b1))
5088    }
5089    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
5090    #[inline(always)]
5091    fn interleave_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> (i32x8<Self>, i32x8<Self>) {
5092        let (a0, a1) = self.split_i32x8(a);
5093        let (b0, b1) = self.split_i32x8(b);
5094        let lo_lo = self.zip_low_i32x4(a0, b0);
5095        let lo_hi = self.zip_high_i32x4(a0, b0);
5096        let hi_lo = self.zip_low_i32x4(a1, b1);
5097        let hi_hi = self.zip_high_i32x4(a1, b1);
5098        (
5099            self.combine_i32x4(lo_lo, lo_hi),
5100            self.combine_i32x4(hi_lo, hi_hi),
5101        )
5102    }
5103    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
5104    #[inline(always)]
5105    fn deinterleave_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> (i32x8<Self>, i32x8<Self>) {
5106        let (a0, a1) = self.split_i32x8(a);
5107        let (b0, b1) = self.split_i32x8(b);
5108        let lo_even = self.unzip_low_i32x4(a0, a1);
5109        let lo_odd = self.unzip_high_i32x4(a0, a1);
5110        let hi_even = self.unzip_low_i32x4(b0, b1);
5111        let hi_odd = self.unzip_high_i32x4(b0, b1);
5112        (
5113            self.combine_i32x4(lo_even, hi_even),
5114            self.combine_i32x4(lo_odd, hi_odd),
5115        )
5116    }
5117    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
5118    #[inline(always)]
5119    fn select_i32x8(self, a: mask32x8<Self>, b: i32x8<Self>, c: i32x8<Self>) -> i32x8<Self> {
5120        let (a0, a1) = self.split_mask32x8(a);
5121        let (b0, b1) = self.split_i32x8(b);
5122        let (c0, c1) = self.split_i32x8(c);
5123        self.combine_i32x4(self.select_i32x4(a0, b0, c0), self.select_i32x4(a1, b1, c1))
5124    }
5125    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
5126    fn combine_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i32x16<Self>;
5127    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
5128    fn split_i32x8(self, a: i32x8<Self>) -> (i32x4<Self>, i32x4<Self>);
5129    #[doc = "Negate each element of the vector, wrapping on overflow."]
5130    #[inline(always)]
5131    fn neg_i32x8(self, a: i32x8<Self>) -> i32x8<Self> {
5132        let (a0, a1) = self.split_i32x8(a);
5133        self.combine_i32x4(self.neg_i32x4(a0), self.neg_i32x4(a1))
5134    }
5135    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
5136    #[inline(always)]
5137    fn widen_i32x8(self, a: i32x8<Self>) -> (i64x4<Self>, i64x4<Self>) {
5138        let (a0, a1) = self.split_i32x8(a);
5139        let (a00, a01) = self.widen_i32x4(a0);
5140        let (a10, a11) = self.widen_i32x4(a1);
5141        (self.combine_i64x2(a00, a01), self.combine_i64x2(a10, a11))
5142    }
5143    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
5144    #[inline(always)]
5145    fn widening_mul_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> (i64x4<Self>, i64x4<Self>) {
5146        let (a0, a1) = self.split_i32x8(a);
5147        let (b0, b1) = self.split_i32x8(b);
5148        let (low0, low1) = self.widening_mul_i32x4(a0, b0);
5149        let (high0, high1) = self.widening_mul_i32x4(a1, b1);
5150        (
5151            self.combine_i64x2(low0, low1),
5152            self.combine_i64x2(high0, high1),
5153        )
5154    }
5155    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
5156    #[inline(always)]
5157    fn widening_add_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> (i64x4<Self>, i64x4<Self>) {
5158        let (a0, a1) = self.split_i32x8(a);
5159        let (b0, b1) = self.split_i32x8(b);
5160        let (low0, low1) = self.widening_add_i32x4(a0, b0);
5161        let (high0, high1) = self.widening_add_i32x4(a1, b1);
5162        (
5163            self.combine_i64x2(low0, low1),
5164            self.combine_i64x2(high0, high1),
5165        )
5166    }
5167    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
5168    #[inline(always)]
5169    fn pairwise_widening_add_i32x8(self, a: i32x8<Self>) -> i64x4<Self> {
5170        let (a0, a1) = self.split_i32x8(a);
5171        self.combine_i64x2(
5172            self.pairwise_widening_add_i32x4(a0),
5173            self.pairwise_widening_add_i32x4(a1),
5174        )
5175    }
5176    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
5177    #[inline(always)]
5178    fn pairwise_dot_product_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i64x4<Self> {
5179        let (a0, a1) = self.split_i32x8(a);
5180        let (b0, b1) = self.split_i32x8(b);
5181        self.combine_i64x2(
5182            self.pairwise_dot_product_i32x4(a0, b0),
5183            self.pairwise_dot_product_i32x4(a1, b1),
5184        )
5185    }
5186    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
5187    #[inline(always)]
5188    fn narrow_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i16x16<Self> {
5189        let (a0, a1) = self.split_i32x8(a);
5190        let (b0, b1) = self.split_i32x8(b);
5191        self.combine_i16x8(self.narrow_i32x4(a0, a1), self.narrow_i32x4(b0, b1))
5192    }
5193    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
5194    #[inline(always)]
5195    fn saturating_narrow_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i16x16<Self> {
5196        let (a0, a1) = self.split_i32x8(a);
5197        let (b0, b1) = self.split_i32x8(b);
5198        self.combine_i16x8(
5199            self.saturating_narrow_i32x4(a0, a1),
5200            self.saturating_narrow_i32x4(b0, b1),
5201        )
5202    }
5203    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
5204    #[inline(always)]
5205    fn relaxed_narrow_i32x8(self, a: i32x8<Self>, b: i32x8<Self>) -> i16x16<Self> {
5206        let (a0, a1) = self.split_i32x8(a);
5207        let (b0, b1) = self.split_i32x8(b);
5208        self.combine_i16x8(
5209            self.relaxed_narrow_i32x4(a0, a1),
5210            self.relaxed_narrow_i32x4(b0, b1),
5211        )
5212    }
5213    #[doc = "Convert each signed 32-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
5214    #[inline(always)]
5215    fn cvt_f32_i32x8(self, a: i32x8<Self>) -> f32x8<Self> {
5216        let (a0, a1) = self.split_i32x8(a);
5217        self.combine_f32x4(self.cvt_f32_i32x4(a0), self.cvt_f32_i32x4(a1))
5218    }
5219    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
5220    #[inline(always)]
5221    fn abs_u32x8(self, a: u32x8<Self>) -> u32x8<Self> {
5222        a
5223    }
5224    #[doc = "Create a SIMD vector with all elements set to the given value."]
5225    #[inline(always)]
5226    fn splat_u32x8(self, val: u32) -> u32x8<Self> {
5227        let half = self.splat_u32x4(val);
5228        self.combine_u32x4(half, half)
5229    }
5230    #[doc = "Reverse the order of the vector's elements."]
5231    #[inline(always)]
5232    fn reverse_u32x8(self, a: u32x8<Self>) -> u32x8<Self> {
5233        let (a0, a1) = self.split_u32x8(a);
5234        self.combine_u32x4(self.reverse_u32x4(a1), self.reverse_u32x4(a0))
5235    }
5236    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
5237    fn slide_u32x8<const SHIFT: usize>(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self>;
5238    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
5239    #[inline(always)]
5240    fn slide_within_blocks_u32x8<const SHIFT: usize>(
5241        self,
5242        a: u32x8<Self>,
5243        b: u32x8<Self>,
5244    ) -> u32x8<Self> {
5245        let (a0, a1) = self.split_u32x8(a);
5246        let (b0, b1) = self.split_u32x8(b);
5247        self.combine_u32x4(
5248            self.slide_within_blocks_u32x4::<SHIFT>(a0, b0),
5249            self.slide_within_blocks_u32x4::<SHIFT>(a1, b1),
5250        )
5251    }
5252    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
5253    #[inline(always)]
5254    fn swizzle_dyn_within_blocks_u32x8(self, a: u32x8<Self>, indices: u8x32<Self>) -> u32x8<Self> {
5255        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x32(Bytes::to_bytes(a), indices))
5256    }
5257    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
5258    #[inline(always)]
5259    fn swizzle_dyn_u32x8(self, a: u32x8<Self>, indices: u8x32<Self>) -> u32x8<Self> {
5260        Bytes::from_bytes(self.swizzle_dyn_u8x32(Bytes::to_bytes(a), indices))
5261    }
5262    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
5263    #[inline(always)]
5264    fn swizzle_dyn_precise_u32x8(self, a: u32x8<Self>, indices: u8x32<Self>) -> u32x8<Self> {
5265        Bytes::from_bytes(self.swizzle_dyn_precise_u8x32(Bytes::to_bytes(a), indices))
5266    }
5267    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
5268    #[inline(always)]
5269    fn concat_swizzle_dyn_u32x8(
5270        self,
5271        a: u32x8<Self>,
5272        b: u32x8<Self>,
5273        indices: u8x32<Self>,
5274    ) -> u32x8<Self> {
5275        Bytes::from_bytes(self.concat_swizzle_dyn_u8x32(
5276            Bytes::to_bytes(a),
5277            Bytes::to_bytes(b),
5278            indices,
5279        ))
5280    }
5281    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
5282    #[inline(always)]
5283    fn concat_swizzle_dyn_precise_u32x8(
5284        self,
5285        a: u32x8<Self>,
5286        b: u32x8<Self>,
5287        indices: u8x32<Self>,
5288    ) -> u32x8<Self> {
5289        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x32(
5290            Bytes::to_bytes(a),
5291            Bytes::to_bytes(b),
5292            indices,
5293        ))
5294    }
5295    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
5296    fn compress_u32x8(self, values: u32x8<Self>, mask: mask32x8<Self>) -> u32x8<Self>;
5297    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
5298    fn compress_merge_u32x8(
5299        self,
5300        values: u32x8<Self>,
5301        mask: mask32x8<Self>,
5302        merge: u32x8<Self>,
5303    ) -> u32x8<Self>;
5304    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
5305    fn expand_u32x8(self, values: u32x8<Self>, mask: mask32x8<Self>) -> u32x8<Self>;
5306    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
5307    fn expand_merge_u32x8(
5308        self,
5309        values: u32x8<Self>,
5310        mask: mask32x8<Self>,
5311        merge: u32x8<Self>,
5312    ) -> u32x8<Self>;
5313    #[doc = "Return the number of ones in the binary representation of each element."]
5314    #[inline(always)]
5315    fn count_ones_u32x8(self, a: u32x8<Self>) -> u32x8<Self> {
5316        let (a0, a1) = self.split_u32x8(a);
5317        self.combine_u32x4(self.count_ones_u32x4(a0), self.count_ones_u32x4(a1))
5318    }
5319    #[doc = "Return the number of zeros in the binary representation of each element."]
5320    #[inline(always)]
5321    fn count_zeros_u32x8(self, a: u32x8<Self>) -> u32x8<Self> {
5322        let (a0, a1) = self.split_u32x8(a);
5323        self.combine_u32x4(self.count_zeros_u32x4(a0), self.count_zeros_u32x4(a1))
5324    }
5325    #[doc = "Add two vectors element-wise, wrapping on overflow."]
5326    #[inline(always)]
5327    fn add_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
5328        let (a0, a1) = self.split_u32x8(a);
5329        let (b0, b1) = self.split_u32x8(b);
5330        self.combine_u32x4(self.add_u32x4(a0, b0), self.add_u32x4(a1, b1))
5331    }
5332    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
5333    #[inline(always)]
5334    fn saturating_add_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
5335        let (a0, a1) = self.split_u32x8(a);
5336        let (b0, b1) = self.split_u32x8(b);
5337        self.combine_u32x4(
5338            self.saturating_add_u32x4(a0, b0),
5339            self.saturating_add_u32x4(a1, b1),
5340        )
5341    }
5342    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
5343    #[inline(always)]
5344    fn sub_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
5345        let (a0, a1) = self.split_u32x8(a);
5346        let (b0, b1) = self.split_u32x8(b);
5347        self.combine_u32x4(self.sub_u32x4(a0, b0), self.sub_u32x4(a1, b1))
5348    }
5349    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
5350    #[inline(always)]
5351    fn saturating_sub_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
5352        let (a0, a1) = self.split_u32x8(a);
5353        let (b0, b1) = self.split_u32x8(b);
5354        self.combine_u32x4(
5355            self.saturating_sub_u32x4(a0, b0),
5356            self.saturating_sub_u32x4(a1, b1),
5357        )
5358    }
5359    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
5360    #[inline(always)]
5361    fn mul_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
5362        let (a0, a1) = self.split_u32x8(a);
5363        let (b0, b1) = self.split_u32x8(b);
5364        self.combine_u32x4(self.mul_u32x4(a0, b0), self.mul_u32x4(a1, b1))
5365    }
5366    #[doc = "Compute the bitwise AND of two vectors."]
5367    #[inline(always)]
5368    fn and_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
5369        let (a0, a1) = self.split_u32x8(a);
5370        let (b0, b1) = self.split_u32x8(b);
5371        self.combine_u32x4(self.and_u32x4(a0, b0), self.and_u32x4(a1, b1))
5372    }
5373    #[doc = "Compute the bitwise OR of two vectors."]
5374    #[inline(always)]
5375    fn or_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
5376        let (a0, a1) = self.split_u32x8(a);
5377        let (b0, b1) = self.split_u32x8(b);
5378        self.combine_u32x4(self.or_u32x4(a0, b0), self.or_u32x4(a1, b1))
5379    }
5380    #[doc = "Compute the bitwise XOR of two vectors."]
5381    #[inline(always)]
5382    fn xor_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
5383        let (a0, a1) = self.split_u32x8(a);
5384        let (b0, b1) = self.split_u32x8(b);
5385        self.combine_u32x4(self.xor_u32x4(a0, b0), self.xor_u32x4(a1, b1))
5386    }
5387    #[doc = "Compute the bitwise NOT of the vector."]
5388    #[inline(always)]
5389    fn not_u32x8(self, a: u32x8<Self>) -> u32x8<Self> {
5390        let (a0, a1) = self.split_u32x8(a);
5391        self.combine_u32x4(self.not_u32x4(a0), self.not_u32x4(a1))
5392    }
5393    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
5394    #[inline(always)]
5395    fn shl_u32x8(self, a: u32x8<Self>, shift: u32) -> u32x8<Self> {
5396        let (a0, a1) = self.split_u32x8(a);
5397        self.combine_u32x4(self.shl_u32x4(a0, shift), self.shl_u32x4(a1, shift))
5398    }
5399    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
5400    #[inline(always)]
5401    fn shlv_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
5402        let (a0, a1) = self.split_u32x8(a);
5403        let (b0, b1) = self.split_u32x8(b);
5404        self.combine_u32x4(self.shlv_u32x4(a0, b0), self.shlv_u32x4(a1, b1))
5405    }
5406    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
5407    #[inline(always)]
5408    fn shr_u32x8(self, a: u32x8<Self>, shift: u32) -> u32x8<Self> {
5409        let (a0, a1) = self.split_u32x8(a);
5410        self.combine_u32x4(self.shr_u32x4(a0, shift), self.shr_u32x4(a1, shift))
5411    }
5412    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
5413    #[inline(always)]
5414    fn shrv_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
5415        let (a0, a1) = self.split_u32x8(a);
5416        let (b0, b1) = self.split_u32x8(b);
5417        self.combine_u32x4(self.shrv_u32x4(a0, b0), self.shrv_u32x4(a1, b1))
5418    }
5419    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
5420    #[inline(always)]
5421    fn reduce_max_u32x8(self, a: u32x8<Self>) -> u32 {
5422        let (a0, a1) = self.split_u32x8(a);
5423        self.reduce_max_u32x4(self.max_u32x4(a0, a1))
5424    }
5425    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
5426    #[inline(always)]
5427    fn reduce_min_u32x8(self, a: u32x8<Self>) -> u32 {
5428        let (a0, a1) = self.split_u32x8(a);
5429        self.reduce_min_u32x4(self.min_u32x4(a0, a1))
5430    }
5431    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
5432    #[inline(always)]
5433    fn reduce_sum_u32x8(self, a: u32x8<Self>) -> u32 {
5434        let (a0, a1) = self.split_u32x8(a);
5435        self.reduce_sum_u32x4(self.add_u32x4(a0, a1))
5436    }
5437    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
5438    #[inline(always)]
5439    fn reduce_product_u32x8(self, a: u32x8<Self>) -> u32 {
5440        let (a0, a1) = self.split_u32x8(a);
5441        self.reduce_product_u32x4(self.mul_u32x4(a0, a1))
5442    }
5443    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
5444    #[inline(always)]
5445    fn max_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
5446        let (a0, a1) = self.split_u32x8(a);
5447        let (b0, b1) = self.split_u32x8(b);
5448        self.combine_u32x4(self.max_u32x4(a0, b0), self.max_u32x4(a1, b1))
5449    }
5450    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
5451    #[inline(always)]
5452    fn min_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
5453        let (a0, a1) = self.split_u32x8(a);
5454        let (b0, b1) = self.split_u32x8(b);
5455        self.combine_u32x4(self.min_u32x4(a0, b0), self.min_u32x4(a1, b1))
5456    }
5457    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
5458    #[inline(always)]
5459    fn clamp_u32x8(self, a: u32x8<Self>, b: u32x8<Self>, c: u32x8<Self>) -> u32x8<Self> {
5460        let (a0, a1) = self.split_u32x8(a);
5461        let (b0, b1) = self.split_u32x8(b);
5462        let (c0, c1) = self.split_u32x8(c);
5463        self.combine_u32x4(self.clamp_u32x4(a0, b0, c0), self.clamp_u32x4(a1, b1, c1))
5464    }
5465    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
5466    #[inline(always)]
5467    fn simd_eq_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> mask32x8<Self> {
5468        let (a0, a1) = self.split_u32x8(a);
5469        let (b0, b1) = self.split_u32x8(b);
5470        self.combine_mask32x4(self.simd_eq_u32x4(a0, b0), self.simd_eq_u32x4(a1, b1))
5471    }
5472    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
5473    #[inline(always)]
5474    fn simd_ne_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> mask32x8<Self> {
5475        self.not_mask32x8(self.simd_eq_u32x8(a, b))
5476    }
5477    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
5478    #[inline(always)]
5479    fn simd_lt_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> mask32x8<Self> {
5480        let (a0, a1) = self.split_u32x8(a);
5481        let (b0, b1) = self.split_u32x8(b);
5482        self.combine_mask32x4(self.simd_lt_u32x4(a0, b0), self.simd_lt_u32x4(a1, b1))
5483    }
5484    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
5485    #[inline(always)]
5486    fn simd_le_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> mask32x8<Self> {
5487        let (a0, a1) = self.split_u32x8(a);
5488        let (b0, b1) = self.split_u32x8(b);
5489        self.combine_mask32x4(self.simd_le_u32x4(a0, b0), self.simd_le_u32x4(a1, b1))
5490    }
5491    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
5492    #[inline(always)]
5493    fn simd_ge_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> mask32x8<Self> {
5494        self.simd_le_u32x8(b, a)
5495    }
5496    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
5497    #[inline(always)]
5498    fn simd_gt_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> mask32x8<Self> {
5499        self.simd_lt_u32x8(b, a)
5500    }
5501    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
5502    #[inline(always)]
5503    fn zip_low_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
5504        let (a0, _) = self.split_u32x8(a);
5505        let (b0, _) = self.split_u32x8(b);
5506        self.combine_u32x4(self.zip_low_u32x4(a0, b0), self.zip_high_u32x4(a0, b0))
5507    }
5508    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
5509    #[inline(always)]
5510    fn zip_high_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
5511        let (_, a1) = self.split_u32x8(a);
5512        let (_, b1) = self.split_u32x8(b);
5513        self.combine_u32x4(self.zip_low_u32x4(a1, b1), self.zip_high_u32x4(a1, b1))
5514    }
5515    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
5516    #[inline(always)]
5517    fn unzip_low_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
5518        let (a0, a1) = self.split_u32x8(a);
5519        let (b0, b1) = self.split_u32x8(b);
5520        self.combine_u32x4(self.unzip_low_u32x4(a0, a1), self.unzip_low_u32x4(b0, b1))
5521    }
5522    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
5523    #[inline(always)]
5524    fn unzip_high_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x8<Self> {
5525        let (a0, a1) = self.split_u32x8(a);
5526        let (b0, b1) = self.split_u32x8(b);
5527        self.combine_u32x4(self.unzip_high_u32x4(a0, a1), self.unzip_high_u32x4(b0, b1))
5528    }
5529    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
5530    #[inline(always)]
5531    fn interleave_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> (u32x8<Self>, u32x8<Self>) {
5532        let (a0, a1) = self.split_u32x8(a);
5533        let (b0, b1) = self.split_u32x8(b);
5534        let lo_lo = self.zip_low_u32x4(a0, b0);
5535        let lo_hi = self.zip_high_u32x4(a0, b0);
5536        let hi_lo = self.zip_low_u32x4(a1, b1);
5537        let hi_hi = self.zip_high_u32x4(a1, b1);
5538        (
5539            self.combine_u32x4(lo_lo, lo_hi),
5540            self.combine_u32x4(hi_lo, hi_hi),
5541        )
5542    }
5543    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
5544    #[inline(always)]
5545    fn deinterleave_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> (u32x8<Self>, u32x8<Self>) {
5546        let (a0, a1) = self.split_u32x8(a);
5547        let (b0, b1) = self.split_u32x8(b);
5548        let lo_even = self.unzip_low_u32x4(a0, a1);
5549        let lo_odd = self.unzip_high_u32x4(a0, a1);
5550        let hi_even = self.unzip_low_u32x4(b0, b1);
5551        let hi_odd = self.unzip_high_u32x4(b0, b1);
5552        (
5553            self.combine_u32x4(lo_even, hi_even),
5554            self.combine_u32x4(lo_odd, hi_odd),
5555        )
5556    }
5557    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
5558    #[inline(always)]
5559    fn select_u32x8(self, a: mask32x8<Self>, b: u32x8<Self>, c: u32x8<Self>) -> u32x8<Self> {
5560        let (a0, a1) = self.split_mask32x8(a);
5561        let (b0, b1) = self.split_u32x8(b);
5562        let (c0, c1) = self.split_u32x8(c);
5563        self.combine_u32x4(self.select_u32x4(a0, b0, c0), self.select_u32x4(a1, b1, c1))
5564    }
5565    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
5566    fn combine_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u32x16<Self>;
5567    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
5568    fn split_u32x8(self, a: u32x8<Self>) -> (u32x4<Self>, u32x4<Self>);
5569    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
5570    #[inline(always)]
5571    fn widen_u32x8(self, a: u32x8<Self>) -> (u64x4<Self>, u64x4<Self>) {
5572        let (a0, a1) = self.split_u32x8(a);
5573        let (a00, a01) = self.widen_u32x4(a0);
5574        let (a10, a11) = self.widen_u32x4(a1);
5575        (self.combine_u64x2(a00, a01), self.combine_u64x2(a10, a11))
5576    }
5577    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
5578    #[inline(always)]
5579    fn widening_mul_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> (u64x4<Self>, u64x4<Self>) {
5580        let (a0, a1) = self.split_u32x8(a);
5581        let (b0, b1) = self.split_u32x8(b);
5582        let (low0, low1) = self.widening_mul_u32x4(a0, b0);
5583        let (high0, high1) = self.widening_mul_u32x4(a1, b1);
5584        (
5585            self.combine_u64x2(low0, low1),
5586            self.combine_u64x2(high0, high1),
5587        )
5588    }
5589    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
5590    #[inline(always)]
5591    fn widening_add_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> (u64x4<Self>, u64x4<Self>) {
5592        let (a0, a1) = self.split_u32x8(a);
5593        let (b0, b1) = self.split_u32x8(b);
5594        let (low0, low1) = self.widening_add_u32x4(a0, b0);
5595        let (high0, high1) = self.widening_add_u32x4(a1, b1);
5596        (
5597            self.combine_u64x2(low0, low1),
5598            self.combine_u64x2(high0, high1),
5599        )
5600    }
5601    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
5602    #[inline(always)]
5603    fn pairwise_widening_add_u32x8(self, a: u32x8<Self>) -> u64x4<Self> {
5604        let (a0, a1) = self.split_u32x8(a);
5605        self.combine_u64x2(
5606            self.pairwise_widening_add_u32x4(a0),
5607            self.pairwise_widening_add_u32x4(a1),
5608        )
5609    }
5610    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
5611    #[inline(always)]
5612    fn pairwise_dot_product_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u64x4<Self> {
5613        let (a0, a1) = self.split_u32x8(a);
5614        let (b0, b1) = self.split_u32x8(b);
5615        self.combine_u64x2(
5616            self.pairwise_dot_product_u32x4(a0, b0),
5617            self.pairwise_dot_product_u32x4(a1, b1),
5618        )
5619    }
5620    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
5621    #[inline(always)]
5622    fn narrow_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u16x16<Self> {
5623        let (a0, a1) = self.split_u32x8(a);
5624        let (b0, b1) = self.split_u32x8(b);
5625        self.combine_u16x8(self.narrow_u32x4(a0, a1), self.narrow_u32x4(b0, b1))
5626    }
5627    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
5628    #[inline(always)]
5629    fn saturating_narrow_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u16x16<Self> {
5630        let (a0, a1) = self.split_u32x8(a);
5631        let (b0, b1) = self.split_u32x8(b);
5632        self.combine_u16x8(
5633            self.saturating_narrow_u32x4(a0, a1),
5634            self.saturating_narrow_u32x4(b0, b1),
5635        )
5636    }
5637    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
5638    #[inline(always)]
5639    fn relaxed_narrow_u32x8(self, a: u32x8<Self>, b: u32x8<Self>) -> u16x16<Self> {
5640        let (a0, a1) = self.split_u32x8(a);
5641        let (b0, b1) = self.split_u32x8(b);
5642        self.combine_u16x8(
5643            self.relaxed_narrow_u32x4(a0, a1),
5644            self.relaxed_narrow_u32x4(b0, b1),
5645        )
5646    }
5647    #[doc = "Convert each unsigned 32-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
5648    #[inline(always)]
5649    fn cvt_f32_u32x8(self, a: u32x8<Self>) -> f32x8<Self> {
5650        let (a0, a1) = self.split_u32x8(a);
5651        self.combine_f32x4(self.cvt_f32_u32x4(a0), self.cvt_f32_u32x4(a1))
5652    }
5653    #[doc = "Create a SIMD mask with all lanes set from the given boolean value."]
5654    #[inline(always)]
5655    fn splat_mask32x8(self, val: bool) -> mask32x8<Self> {
5656        let half = self.splat_mask32x4(val);
5657        self.combine_mask32x4(half, half)
5658    }
5659    #[doc = "Create a SIMD mask from a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are ignored."]
5660    #[inline(always)]
5661    fn from_bitmask_mask32x8(self, bits: u64) -> mask32x8<Self> {
5662        let lo = self.from_bitmask_mask32x4(bits);
5663        let hi = self.from_bitmask_mask32x4(bits >> 4usize);
5664        self.combine_mask32x4(lo, hi)
5665    }
5666    #[doc = "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared."]
5667    #[inline(always)]
5668    fn to_bitmask_mask32x8(self, a: mask32x8<Self>) -> u64 {
5669        let (lo, hi) = self.split_mask32x8(a);
5670        let lo = self.to_bitmask_mask32x4(lo);
5671        let hi = self.to_bitmask_mask32x4(hi);
5672        lo | (hi << 4usize)
5673    }
5674    #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."]
5675    fn from_vector_mask32x8(self, vector: i32x8<Self>) -> mask32x8<Self>;
5676    #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."]
5677    fn to_vector_mask32x8(self, a: mask32x8<Self>) -> i32x8<Self>;
5678    #[doc = "Set one logical lane of a SIMD mask."]
5679    fn set_mask32x8(self, a: &mut mask32x8<Self>, index: usize, value: bool) -> ();
5680    #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
5681    fn rotate_elements_left_mask32x8<const OFFSET: usize>(
5682        self,
5683        a: mask32x8<Self>,
5684    ) -> mask32x8<Self>;
5685    #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
5686    fn rotate_elements_right_mask32x8<const OFFSET: usize>(
5687        self,
5688        a: mask32x8<Self>,
5689    ) -> mask32x8<Self>;
5690    #[doc = "Compute the logical AND of two masks."]
5691    #[inline(always)]
5692    fn and_mask32x8(self, a: mask32x8<Self>, b: mask32x8<Self>) -> mask32x8<Self> {
5693        let (a0, a1) = self.split_mask32x8(a);
5694        let (b0, b1) = self.split_mask32x8(b);
5695        self.combine_mask32x4(self.and_mask32x4(a0, b0), self.and_mask32x4(a1, b1))
5696    }
5697    #[doc = "Compute the logical OR of two masks."]
5698    #[inline(always)]
5699    fn or_mask32x8(self, a: mask32x8<Self>, b: mask32x8<Self>) -> mask32x8<Self> {
5700        let (a0, a1) = self.split_mask32x8(a);
5701        let (b0, b1) = self.split_mask32x8(b);
5702        self.combine_mask32x4(self.or_mask32x4(a0, b0), self.or_mask32x4(a1, b1))
5703    }
5704    #[doc = "Compute the logical XOR of two masks."]
5705    #[inline(always)]
5706    fn xor_mask32x8(self, a: mask32x8<Self>, b: mask32x8<Self>) -> mask32x8<Self> {
5707        let (a0, a1) = self.split_mask32x8(a);
5708        let (b0, b1) = self.split_mask32x8(b);
5709        self.combine_mask32x4(self.xor_mask32x4(a0, b0), self.xor_mask32x4(a1, b1))
5710    }
5711    #[doc = "Compute the logical NOT of the mask."]
5712    #[inline(always)]
5713    fn not_mask32x8(self, a: mask32x8<Self>) -> mask32x8<Self> {
5714        let (a0, a1) = self.split_mask32x8(a);
5715        self.combine_mask32x4(self.not_mask32x4(a0), self.not_mask32x4(a1))
5716    }
5717    #[doc = "Reverse the order of the mask's logical lanes."]
5718    #[inline(always)]
5719    fn reverse_mask32x8(self, a: mask32x8<Self>) -> mask32x8<Self> {
5720        let (a0, a1) = self.split_mask32x8(a);
5721        self.combine_mask32x4(self.reverse_mask32x4(a1), self.reverse_mask32x4(a0))
5722    }
5723    #[doc = "Select elements from `b` and `c` based on the mask operand `a`.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
5724    #[inline(always)]
5725    fn select_mask32x8(
5726        self,
5727        a: mask32x8<Self>,
5728        b: mask32x8<Self>,
5729        c: mask32x8<Self>,
5730    ) -> mask32x8<Self> {
5731        let (a0, a1) = self.split_mask32x8(a);
5732        let (b0, b1) = self.split_mask32x8(b);
5733        let (c0, c1) = self.split_mask32x8(c);
5734        self.combine_mask32x4(
5735            self.select_mask32x4(a0, b0, c0),
5736            self.select_mask32x4(a1, b1, c1),
5737        )
5738    }
5739    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
5740    #[inline(always)]
5741    fn simd_eq_mask32x8(self, a: mask32x8<Self>, b: mask32x8<Self>) -> mask32x8<Self> {
5742        let (a0, a1) = self.split_mask32x8(a);
5743        let (b0, b1) = self.split_mask32x8(b);
5744        self.combine_mask32x4(self.simd_eq_mask32x4(a0, b0), self.simd_eq_mask32x4(a1, b1))
5745    }
5746    #[doc = "Compare two masks element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
5747    #[inline(always)]
5748    fn simd_ne_mask32x8(self, a: mask32x8<Self>, b: mask32x8<Self>) -> mask32x8<Self> {
5749        self.not_mask32x8(self.simd_eq_mask32x8(a, b))
5750    }
5751    #[doc = "Returns true if any logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
5752    #[inline(always)]
5753    fn any_true_mask32x8(self, a: mask32x8<Self>) -> bool {
5754        let (a0, a1) = self.split_mask32x8(a);
5755        self.any_true_mask32x4(self.or_mask32x4(a0, a1))
5756    }
5757    #[doc = "Returns true if all logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
5758    #[inline(always)]
5759    fn all_true_mask32x8(self, a: mask32x8<Self>) -> bool {
5760        let (a0, a1) = self.split_mask32x8(a);
5761        self.all_true_mask32x4(self.and_mask32x4(a0, a1))
5762    }
5763    #[doc = "Returns true if any logical lanes in this mask are false.\n\nThis is logically equivalent to `!all_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
5764    #[inline(always)]
5765    fn any_false_mask32x8(self, a: mask32x8<Self>) -> bool {
5766        let (a0, a1) = self.split_mask32x8(a);
5767        self.any_false_mask32x4(self.and_mask32x4(a0, a1))
5768    }
5769    #[doc = "Returns true if all logical lanes in this mask are false.\n\nThis is logically equivalent to `!any_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
5770    #[inline(always)]
5771    fn all_false_mask32x8(self, a: mask32x8<Self>) -> bool {
5772        let (a0, a1) = self.split_mask32x8(a);
5773        self.all_false_mask32x4(self.or_mask32x4(a0, a1))
5774    }
5775    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
5776    fn combine_mask32x8(self, a: mask32x8<Self>, b: mask32x8<Self>) -> mask32x16<Self>;
5777    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
5778    fn split_mask32x8(self, a: mask32x8<Self>) -> (mask32x4<Self>, mask32x4<Self>);
5779    #[doc = "Widen each boolean lane into two masks of the same logical width, preserving its value.\n\nThe first result contains the lower lanes and the second contains the upper lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
5780    #[inline(always)]
5781    fn widen_mask32x8(self, a: mask32x8<Self>) -> (mask64x4<Self>, mask64x4<Self>) {
5782        let (a0, a1) = self.split_mask32x8(a);
5783        let (a00, a01) = self.widen_mask32x4(a0);
5784        let (a10, a11) = self.widen_mask32x4(a1);
5785        (
5786            self.combine_mask64x2(a00, a01),
5787            self.combine_mask64x2(a10, a11),
5788        )
5789    }
5790    #[doc = "Narrow each boolean lane of two masks and concatenate them into one mask of the same logical width, preserving each value.\n\n`a` supplies the lower result lanes and `b` supplies the upper result lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
5791    #[inline(always)]
5792    fn narrow_mask32x8(self, a: mask32x8<Self>, b: mask32x8<Self>) -> mask16x16<Self> {
5793        let (a0, a1) = self.split_mask32x8(a);
5794        let (b0, b1) = self.split_mask32x8(b);
5795        self.combine_mask16x8(self.narrow_mask32x4(a0, a1), self.narrow_mask32x4(b0, b1))
5796    }
5797    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
5798    #[inline(always)]
5799    fn abs_f64x4(self, a: f64x4<Self>) -> f64x4<Self> {
5800        let (a0, a1) = self.split_f64x4(a);
5801        self.combine_f64x2(self.abs_f64x2(a0), self.abs_f64x2(a1))
5802    }
5803    #[doc = "Create a SIMD vector with all elements set to the given value."]
5804    #[inline(always)]
5805    fn splat_f64x4(self, val: f64) -> f64x4<Self> {
5806        let half = self.splat_f64x2(val);
5807        self.combine_f64x2(half, half)
5808    }
5809    #[doc = "Reverse the order of the vector's elements."]
5810    #[inline(always)]
5811    fn reverse_f64x4(self, a: f64x4<Self>) -> f64x4<Self> {
5812        let (a0, a1) = self.split_f64x4(a);
5813        self.combine_f64x2(self.reverse_f64x2(a1), self.reverse_f64x2(a0))
5814    }
5815    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
5816    fn slide_f64x4<const SHIFT: usize>(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x4<Self>;
5817    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
5818    #[inline(always)]
5819    fn slide_within_blocks_f64x4<const SHIFT: usize>(
5820        self,
5821        a: f64x4<Self>,
5822        b: f64x4<Self>,
5823    ) -> f64x4<Self> {
5824        let (a0, a1) = self.split_f64x4(a);
5825        let (b0, b1) = self.split_f64x4(b);
5826        self.combine_f64x2(
5827            self.slide_within_blocks_f64x2::<SHIFT>(a0, b0),
5828            self.slide_within_blocks_f64x2::<SHIFT>(a1, b1),
5829        )
5830    }
5831    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
5832    #[inline(always)]
5833    fn swizzle_dyn_within_blocks_f64x4(self, a: f64x4<Self>, indices: u8x32<Self>) -> f64x4<Self> {
5834        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x32(Bytes::to_bytes(a), indices))
5835    }
5836    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
5837    #[inline(always)]
5838    fn swizzle_dyn_f64x4(self, a: f64x4<Self>, indices: u8x32<Self>) -> f64x4<Self> {
5839        Bytes::from_bytes(self.swizzle_dyn_u8x32(Bytes::to_bytes(a), indices))
5840    }
5841    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
5842    #[inline(always)]
5843    fn swizzle_dyn_precise_f64x4(self, a: f64x4<Self>, indices: u8x32<Self>) -> f64x4<Self> {
5844        Bytes::from_bytes(self.swizzle_dyn_precise_u8x32(Bytes::to_bytes(a), indices))
5845    }
5846    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
5847    #[inline(always)]
5848    fn concat_swizzle_dyn_f64x4(
5849        self,
5850        a: f64x4<Self>,
5851        b: f64x4<Self>,
5852        indices: u8x32<Self>,
5853    ) -> f64x4<Self> {
5854        Bytes::from_bytes(self.concat_swizzle_dyn_u8x32(
5855            Bytes::to_bytes(a),
5856            Bytes::to_bytes(b),
5857            indices,
5858        ))
5859    }
5860    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
5861    #[inline(always)]
5862    fn concat_swizzle_dyn_precise_f64x4(
5863        self,
5864        a: f64x4<Self>,
5865        b: f64x4<Self>,
5866        indices: u8x32<Self>,
5867    ) -> f64x4<Self> {
5868        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x32(
5869            Bytes::to_bytes(a),
5870            Bytes::to_bytes(b),
5871            indices,
5872        ))
5873    }
5874    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
5875    fn compress_f64x4(self, values: f64x4<Self>, mask: mask64x4<Self>) -> f64x4<Self>;
5876    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
5877    fn compress_merge_f64x4(
5878        self,
5879        values: f64x4<Self>,
5880        mask: mask64x4<Self>,
5881        merge: f64x4<Self>,
5882    ) -> f64x4<Self>;
5883    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
5884    fn expand_f64x4(self, values: f64x4<Self>, mask: mask64x4<Self>) -> f64x4<Self>;
5885    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
5886    fn expand_merge_f64x4(
5887        self,
5888        values: f64x4<Self>,
5889        mask: mask64x4<Self>,
5890        merge: f64x4<Self>,
5891    ) -> f64x4<Self>;
5892    #[doc = "Negate each element of the vector."]
5893    #[inline(always)]
5894    fn neg_f64x4(self, a: f64x4<Self>) -> f64x4<Self> {
5895        let (a0, a1) = self.split_f64x4(a);
5896        self.combine_f64x2(self.neg_f64x2(a0), self.neg_f64x2(a1))
5897    }
5898    #[doc = "Compute the square root of each element.\n\nNegative elements other than `-0.0` will become NaN."]
5899    #[inline(always)]
5900    fn sqrt_f64x4(self, a: f64x4<Self>) -> f64x4<Self> {
5901        let (a0, a1) = self.split_f64x4(a);
5902        self.combine_f64x2(self.sqrt_f64x2(a0), self.sqrt_f64x2(a1))
5903    }
5904    #[doc = "Compute an approximate reciprocal (`1. / x`) for each element.\n\nThis uses a fast hardware estimate where available, and falls back to exact division otherwise.\n\nOn x86 for `f32`, this has a relative error less than `1.5 × 2^-12`. On `AArch64` (`f32` and `f64`), this has a relative error less than `2^-8`. The precision of this operation may change as new platform support is added."]
5905    #[inline(always)]
5906    fn approximate_recip_f64x4(self, a: f64x4<Self>) -> f64x4<Self> {
5907        let (a0, a1) = self.split_f64x4(a);
5908        self.combine_f64x2(
5909            self.approximate_recip_f64x2(a0),
5910            self.approximate_recip_f64x2(a1),
5911        )
5912    }
5913    #[doc = "Add two vectors element-wise."]
5914    #[inline(always)]
5915    fn add_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x4<Self> {
5916        let (a0, a1) = self.split_f64x4(a);
5917        let (b0, b1) = self.split_f64x4(b);
5918        self.combine_f64x2(self.add_f64x2(a0, b0), self.add_f64x2(a1, b1))
5919    }
5920    #[doc = "Subtract two vectors element-wise."]
5921    #[inline(always)]
5922    fn sub_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x4<Self> {
5923        let (a0, a1) = self.split_f64x4(a);
5924        let (b0, b1) = self.split_f64x4(b);
5925        self.combine_f64x2(self.sub_f64x2(a0, b0), self.sub_f64x2(a1, b1))
5926    }
5927    #[doc = "Multiply two vectors element-wise."]
5928    #[inline(always)]
5929    fn mul_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x4<Self> {
5930        let (a0, a1) = self.split_f64x4(a);
5931        let (b0, b1) = self.split_f64x4(b);
5932        self.combine_f64x2(self.mul_f64x2(a0, b0), self.mul_f64x2(a1, b1))
5933    }
5934    #[doc = "Divide two vectors element-wise."]
5935    #[inline(always)]
5936    fn div_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x4<Self> {
5937        let (a0, a1) = self.split_f64x4(a);
5938        let (b0, b1) = self.split_f64x4(b);
5939        self.combine_f64x2(self.div_f64x2(a0, b0), self.div_f64x2(a1, b1))
5940    }
5941    #[doc = "Return a vector with the magnitude of `a` and the sign of `b` for each element.\n\nThis operation copies the sign bit, so if an input element is NaN, the output element will be a NaN with the same payload and a copied sign bit."]
5942    #[inline(always)]
5943    fn copysign_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x4<Self> {
5944        let (a0, a1) = self.split_f64x4(a);
5945        let (b0, b1) = self.split_f64x4(b);
5946        self.combine_f64x2(self.copysign_f64x2(a0, b0), self.copysign_f64x2(a1, b1))
5947    }
5948    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
5949    #[inline(always)]
5950    fn reduce_max_f64x4(self, a: f64x4<Self>) -> f64 {
5951        let (a0, a1) = self.split_f64x4(a);
5952        self.reduce_max_f64x2(self.max_f64x2(a0, a1))
5953    }
5954    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
5955    #[inline(always)]
5956    fn reduce_min_f64x4(self, a: f64x4<Self>) -> f64 {
5957        let (a0, a1) = self.split_f64x4(a);
5958        self.reduce_min_f64x2(self.min_f64x2(a0, a1))
5959    }
5960    #[doc = "Return the maximum element in the vector, ignoring quiet NaNs.\n\nFor integer vectors, this operation is the same as `reduce_max`.\n\nFor floating-point vectors, quiet NaNs are ignored. If there is at least one numeric lane, this returns the true maximum of the numeric lanes. If all lanes are quiet NaNs, this returns NaN, with an unspecified payload and sign.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned.\n\nIf any lane is a *signaling* NaN, the result is fully non-deterministic: it may be NaN or a numeric lane and is not guaranteed to be the true maximum.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
5961    #[inline(always)]
5962    fn reduce_max_precise_f64x4(self, a: f64x4<Self>) -> f64 {
5963        let (a0, a1) = self.split_f64x4(a);
5964        self.reduce_max_precise_f64x2(self.max_precise_f64x2(a0, a1))
5965    }
5966    #[doc = "Return the minimum element in the vector, ignoring quiet NaNs.\n\nFor integer vectors, this operation is the same as `reduce_min`.\n\nFor floating-point vectors, quiet NaNs are ignored. If there is at least one numeric lane, this returns the true minimum of the numeric lanes. If all lanes are quiet NaNs, this returns NaN, with an unspecified payload and sign.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned.\n\nIf any lane is a *signaling* NaN, the result is fully non-deterministic: it may be NaN or a numeric lane and is not guaranteed to be the true minimum.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
5967    #[inline(always)]
5968    fn reduce_min_precise_f64x4(self, a: f64x4<Self>) -> f64 {
5969        let (a0, a1) = self.split_f64x4(a);
5970        self.reduce_min_precise_f64x2(self.min_precise_f64x2(a0, a1))
5971    }
5972    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
5973    #[inline(always)]
5974    fn reduce_sum_f64x4(self, a: f64x4<Self>) -> f64 {
5975        let (a0, a1) = self.split_f64x4(a);
5976        self.reduce_sum_f64x2(self.add_f64x2(a0, a1))
5977    }
5978    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
5979    #[inline(always)]
5980    fn reduce_product_f64x4(self, a: f64x4<Self>) -> f64 {
5981        let (a0, a1) = self.split_f64x4(a);
5982        self.reduce_product_f64x2(self.mul_f64x2(a0, a1))
5983    }
5984    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
5985    #[inline(always)]
5986    fn max_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x4<Self> {
5987        let (a0, a1) = self.split_f64x4(a);
5988        let (b0, b1) = self.split_f64x4(b);
5989        self.combine_f64x2(self.max_f64x2(a0, b0), self.max_f64x2(a1, b1))
5990    }
5991    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
5992    #[inline(always)]
5993    fn min_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x4<Self> {
5994        let (a0, a1) = self.split_f64x4(a);
5995        let (b0, b1) = self.split_f64x4(b);
5996        self.combine_f64x2(self.min_f64x2(a0, b0), self.min_f64x2(a1, b1))
5997    }
5998    #[doc = "Return the element-wise maximum of two vectors.\n\nFor integer vectors, this operation is the same as `max`.\n\nFor floating-point vectors, if one operand is a quiet NaN and the other is not, this operation will choose the non-NaN operand.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\nIf a floating-point operand is a *signaling* NaN, the result is not just implementation-defined, but fully non-deterministic: it may be either NaN or the non-NaN operand.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
5999    #[inline(always)]
6000    fn max_precise_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x4<Self> {
6001        let (a0, a1) = self.split_f64x4(a);
6002        let (b0, b1) = self.split_f64x4(b);
6003        self.combine_f64x2(
6004            self.max_precise_f64x2(a0, b0),
6005            self.max_precise_f64x2(a1, b1),
6006        )
6007    }
6008    #[doc = "Return the element-wise minimum of two vectors.\n\nFor integer vectors, this operation is the same as `min`.\n\nFor floating-point vectors, if one operand is a quiet NaN and the other is not, this operation will choose the non-NaN operand.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\nIf a floating-point operand is a *signaling* NaN, the result is not just implementation-defined, but fully non-deterministic: it may be either NaN or the non-NaN operand.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
6009    #[inline(always)]
6010    fn min_precise_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x4<Self> {
6011        let (a0, a1) = self.split_f64x4(a);
6012        let (b0, b1) = self.split_f64x4(b);
6013        self.combine_f64x2(
6014            self.min_precise_f64x2(a0, b0),
6015            self.min_precise_f64x2(a1, b1),
6016        )
6017    }
6018    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
6019    #[inline(always)]
6020    fn clamp_f64x4(self, a: f64x4<Self>, b: f64x4<Self>, c: f64x4<Self>) -> f64x4<Self> {
6021        let (a0, a1) = self.split_f64x4(a);
6022        let (b0, b1) = self.split_f64x4(b);
6023        let (c0, c1) = self.split_f64x4(c);
6024        self.combine_f64x2(self.clamp_f64x2(a0, b0, c0), self.clamp_f64x2(a1, b1, c1))
6025    }
6026    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
6027    #[inline(always)]
6028    fn simd_eq_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> mask64x4<Self> {
6029        let (a0, a1) = self.split_f64x4(a);
6030        let (b0, b1) = self.split_f64x4(b);
6031        self.combine_mask64x2(self.simd_eq_f64x2(a0, b0), self.simd_eq_f64x2(a1, b1))
6032    }
6033    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
6034    #[inline(always)]
6035    fn simd_ne_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> mask64x4<Self> {
6036        self.not_mask64x4(self.simd_eq_f64x4(a, b))
6037    }
6038    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
6039    #[inline(always)]
6040    fn simd_lt_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> mask64x4<Self> {
6041        let (a0, a1) = self.split_f64x4(a);
6042        let (b0, b1) = self.split_f64x4(b);
6043        self.combine_mask64x2(self.simd_lt_f64x2(a0, b0), self.simd_lt_f64x2(a1, b1))
6044    }
6045    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
6046    #[inline(always)]
6047    fn simd_le_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> mask64x4<Self> {
6048        let (a0, a1) = self.split_f64x4(a);
6049        let (b0, b1) = self.split_f64x4(b);
6050        self.combine_mask64x2(self.simd_le_f64x2(a0, b0), self.simd_le_f64x2(a1, b1))
6051    }
6052    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
6053    #[inline(always)]
6054    fn simd_ge_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> mask64x4<Self> {
6055        self.simd_le_f64x4(b, a)
6056    }
6057    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
6058    #[inline(always)]
6059    fn simd_gt_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> mask64x4<Self> {
6060        self.simd_lt_f64x4(b, a)
6061    }
6062    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
6063    #[inline(always)]
6064    fn zip_low_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x4<Self> {
6065        let (a0, _) = self.split_f64x4(a);
6066        let (b0, _) = self.split_f64x4(b);
6067        self.combine_f64x2(self.zip_low_f64x2(a0, b0), self.zip_high_f64x2(a0, b0))
6068    }
6069    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
6070    #[inline(always)]
6071    fn zip_high_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x4<Self> {
6072        let (_, a1) = self.split_f64x4(a);
6073        let (_, b1) = self.split_f64x4(b);
6074        self.combine_f64x2(self.zip_low_f64x2(a1, b1), self.zip_high_f64x2(a1, b1))
6075    }
6076    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
6077    #[inline(always)]
6078    fn unzip_low_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x4<Self> {
6079        let (a0, a1) = self.split_f64x4(a);
6080        let (b0, b1) = self.split_f64x4(b);
6081        self.combine_f64x2(self.unzip_low_f64x2(a0, a1), self.unzip_low_f64x2(b0, b1))
6082    }
6083    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
6084    #[inline(always)]
6085    fn unzip_high_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x4<Self> {
6086        let (a0, a1) = self.split_f64x4(a);
6087        let (b0, b1) = self.split_f64x4(b);
6088        self.combine_f64x2(self.unzip_high_f64x2(a0, a1), self.unzip_high_f64x2(b0, b1))
6089    }
6090    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
6091    #[inline(always)]
6092    fn interleave_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> (f64x4<Self>, f64x4<Self>) {
6093        let (a0, a1) = self.split_f64x4(a);
6094        let (b0, b1) = self.split_f64x4(b);
6095        let lo_lo = self.zip_low_f64x2(a0, b0);
6096        let lo_hi = self.zip_high_f64x2(a0, b0);
6097        let hi_lo = self.zip_low_f64x2(a1, b1);
6098        let hi_hi = self.zip_high_f64x2(a1, b1);
6099        (
6100            self.combine_f64x2(lo_lo, lo_hi),
6101            self.combine_f64x2(hi_lo, hi_hi),
6102        )
6103    }
6104    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
6105    #[inline(always)]
6106    fn deinterleave_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> (f64x4<Self>, f64x4<Self>) {
6107        let (a0, a1) = self.split_f64x4(a);
6108        let (b0, b1) = self.split_f64x4(b);
6109        let lo_even = self.unzip_low_f64x2(a0, a1);
6110        let lo_odd = self.unzip_high_f64x2(a0, a1);
6111        let hi_even = self.unzip_low_f64x2(b0, b1);
6112        let hi_odd = self.unzip_high_f64x2(b0, b1);
6113        (
6114            self.combine_f64x2(lo_even, hi_even),
6115            self.combine_f64x2(lo_odd, hi_odd),
6116        )
6117    }
6118    #[doc = "Compute `(a * b) + c` (fused multiply-add) for each element.\n\nDepending on platform support, the result may be computed with only one rounding error, or may be implemented as a regular multiply followed by an add, which will result in two rounding errors."]
6119    #[inline(always)]
6120    fn mul_add_f64x4(self, a: f64x4<Self>, b: f64x4<Self>, c: f64x4<Self>) -> f64x4<Self> {
6121        let (a0, a1) = self.split_f64x4(a);
6122        let (b0, b1) = self.split_f64x4(b);
6123        let (c0, c1) = self.split_f64x4(c);
6124        self.combine_f64x2(
6125            self.mul_add_f64x2(a0, b0, c0),
6126            self.mul_add_f64x2(a1, b1, c1),
6127        )
6128    }
6129    #[doc = "Compute `(a * b) + c` for each element, with a single rounding at the end.\n\nThe result is the infinite-precision product-plus-add rounded once to the element type. This may be substantially slower than `mul_add` on platforms without fused multiply-add instructions, including WebAssembly.\n\n# Precision guarantees\n\nThis function is **not** susceptible to [the bug](https://github.com/rust-lang/compiler-builtins/issues/1262) in Rust standard library and in musl libc that causes incorrect rounding for near-zero values on CPUs without hardware support for this operation.\n\nOn the tier-2 i586-* targets, this function is correct if and only if SSE2 is available on the CPU.\n\nThe exact `NaN` payloads as well as signaling `NaN`s are not preserved."]
6130    #[inline(always)]
6131    fn mul_add_precise_f64x4(self, a: f64x4<Self>, b: f64x4<Self>, c: f64x4<Self>) -> f64x4<Self> {
6132        let (a0, a1) = self.split_f64x4(a);
6133        let (b0, b1) = self.split_f64x4(b);
6134        let (c0, c1) = self.split_f64x4(c);
6135        self.combine_f64x2(
6136            self.mul_add_precise_f64x2(a0, b0, c0),
6137            self.mul_add_precise_f64x2(a1, b1, c1),
6138        )
6139    }
6140    #[doc = "Compute `(a * b) - c` (fused multiply-subtract) for each element.\n\nDepending on platform support, the result may be computed with only one rounding error, or may be implemented as a regular multiply followed by a subtract, which will result in two rounding errors."]
6141    #[inline(always)]
6142    fn mul_sub_f64x4(self, a: f64x4<Self>, b: f64x4<Self>, c: f64x4<Self>) -> f64x4<Self> {
6143        let (a0, a1) = self.split_f64x4(a);
6144        let (b0, b1) = self.split_f64x4(b);
6145        let (c0, c1) = self.split_f64x4(c);
6146        self.combine_f64x2(
6147            self.mul_sub_f64x2(a0, b0, c0),
6148            self.mul_sub_f64x2(a1, b1, c1),
6149        )
6150    }
6151    #[doc = "Compute `(a * b) - c` for each element, with a single rounding at the end.\n\nThe result is the infinite-precision product-minus-subtrahend rounded once to the element type. This may be substantially slower than `mul_sub` on platforms without fused multiply-add instructions, including WebAssembly.\n        # Precision guarantees\n\nThis function is **not** susceptible to [the bug](https://github.com/rust-lang/compiler-builtins/issues/1262) in Rust standard library and in musl libc that causes incorrect rounding for near-zero values on CPUs without hardware support for this operation.\n\nOn the tier-2 i586-* targets, this function is correct if and only if SSE2 is available on the CPU.\n\nThe exact `NaN` payloads as well as signaling `NaN`s are not preserved."]
6152    #[inline(always)]
6153    fn mul_sub_precise_f64x4(self, a: f64x4<Self>, b: f64x4<Self>, c: f64x4<Self>) -> f64x4<Self> {
6154        let (a0, a1) = self.split_f64x4(a);
6155        let (b0, b1) = self.split_f64x4(b);
6156        let (c0, c1) = self.split_f64x4(c);
6157        self.combine_f64x2(
6158            self.mul_sub_precise_f64x2(a0, b0, c0),
6159            self.mul_sub_precise_f64x2(a1, b1, c1),
6160        )
6161    }
6162    #[doc = "Return the largest integer less than or equal to each element, that is, round towards negative infinity."]
6163    #[inline(always)]
6164    fn floor_f64x4(self, a: f64x4<Self>) -> f64x4<Self> {
6165        let (a0, a1) = self.split_f64x4(a);
6166        self.combine_f64x2(self.floor_f64x2(a0), self.floor_f64x2(a1))
6167    }
6168    #[doc = "Return the smallest integer greater than or equal to each element, that is, round towards positive infinity."]
6169    #[inline(always)]
6170    fn ceil_f64x4(self, a: f64x4<Self>) -> f64x4<Self> {
6171        let (a0, a1) = self.split_f64x4(a);
6172        self.combine_f64x2(self.ceil_f64x2(a0), self.ceil_f64x2(a1))
6173    }
6174    #[doc = "Round each element to the nearest integer, with ties rounding to the nearest even integer."]
6175    #[inline(always)]
6176    fn round_ties_even_f64x4(self, a: f64x4<Self>) -> f64x4<Self> {
6177        let (a0, a1) = self.split_f64x4(a);
6178        self.combine_f64x2(
6179            self.round_ties_even_f64x2(a0),
6180            self.round_ties_even_f64x2(a1),
6181        )
6182    }
6183    #[doc = "Round each element to the nearest integer, with ties rounding away from zero.\n\n## Performance considerations\n\nOnly `AArch64` has native instructions for this operation. `round` has to be emulated on all other platforms which is around 2-4x slower than `round_ties_even`. Prefer using [`round_ties_even`](SimdFloat::round_ties_even) if possible."]
6184    #[inline(always)]
6185    fn round_f64x4(self, a: f64x4<Self>) -> f64x4<Self> {
6186        let (a0, a1) = self.split_f64x4(a);
6187        self.combine_f64x2(self.round_f64x2(a0), self.round_f64x2(a1))
6188    }
6189    #[doc = "Return the fractional part of each element.\n\nThis is equivalent to `a - a.trunc()`."]
6190    #[inline(always)]
6191    fn fract_f64x4(self, a: f64x4<Self>) -> f64x4<Self> {
6192        let (a0, a1) = self.split_f64x4(a);
6193        self.combine_f64x2(self.fract_f64x2(a0), self.fract_f64x2(a1))
6194    }
6195    #[doc = "Return the integer part of each element, rounding towards zero."]
6196    #[inline(always)]
6197    fn trunc_f64x4(self, a: f64x4<Self>) -> f64x4<Self> {
6198        let (a0, a1) = self.split_f64x4(a);
6199        self.combine_f64x2(self.trunc_f64x2(a0), self.trunc_f64x2(a1))
6200    }
6201    #[doc = "Converts radians to degrees.\n\nThe precision of this function is non-deterministic. This means it varies by platform, Rust version, and can even differ within the same execution from one invocation to the next."]
6202    #[inline(always)]
6203    fn to_degrees_f64x4(self, a: f64x4<Self>) -> f64x4<Self> {
6204        let (a0, a1) = self.split_f64x4(a);
6205        self.combine_f64x2(self.to_degrees_f64x2(a0), self.to_degrees_f64x2(a1))
6206    }
6207    #[doc = "Converts degrees to radians.\n\nThe precision of this function is non-deterministic. This means it varies by platform, Rust version, and can even differ within the same execution from one invocation to the next."]
6208    #[inline(always)]
6209    fn to_radians_f64x4(self, a: f64x4<Self>) -> f64x4<Self> {
6210        let (a0, a1) = self.split_f64x4(a);
6211        self.combine_f64x2(self.to_radians_f64x2(a0), self.to_radians_f64x2(a1))
6212    }
6213    #[doc = "Return a mask indicating which elements are NaN."]
6214    fn is_nan_f64x4(self, a: f64x4<Self>) -> mask64x4<Self>;
6215    #[doc = "Return a mask indicating which elements are positive or negative infinite."]
6216    fn is_infinite_f64x4(self, a: f64x4<Self>) -> mask64x4<Self>;
6217    #[doc = "Return a mask indicating which elements are neither infinite nor NaN."]
6218    fn is_finite_f64x4(self, a: f64x4<Self>) -> mask64x4<Self>;
6219    #[doc = "Return a mask indicating which elements are subnormal.\n\nThis classifies the stored bit pattern, even when floating-point operations treat subnormals as zero."]
6220    fn is_subnormal_f64x4(self, a: f64x4<Self>) -> mask64x4<Self>;
6221    #[doc = "Return a mask indicating which elements are neither zero, infinite, subnormal, or NaN."]
6222    fn is_normal_f64x4(self, a: f64x4<Self>) -> mask64x4<Self>;
6223    #[doc = "Return a mask indicating which elements have a positive sign, including `+0.0`, NaNs with positive sign bit and positive infinity.\n\nNaN inputs may produce an unexpected or non-portable result, see [`f32::is_sign_positive`] for details."]
6224    fn is_sign_positive_f64x4(self, a: f64x4<Self>) -> mask64x4<Self>;
6225    #[doc = "Return a mask indicating which elements have a negative sign, including `-0.0`, NaNs with negative sign bit and negative infinity.\n\nNaN inputs may produce an unexpected or non-portable result, see [`f32::is_sign_negative`] for details."]
6226    fn is_sign_negative_f64x4(self, a: f64x4<Self>) -> mask64x4<Self>;
6227    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
6228    #[inline(always)]
6229    fn select_f64x4(self, a: mask64x4<Self>, b: f64x4<Self>, c: f64x4<Self>) -> f64x4<Self> {
6230        let (a0, a1) = self.split_mask64x4(a);
6231        let (b0, b1) = self.split_f64x4(b);
6232        let (c0, c1) = self.split_f64x4(c);
6233        self.combine_f64x2(self.select_f64x2(a0, b0, c0), self.select_f64x2(a1, b1, c1))
6234    }
6235    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
6236    fn combine_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f64x8<Self>;
6237    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
6238    fn split_f64x4(self, a: f64x4<Self>) -> (f64x2<Self>, f64x2<Self>);
6239    #[doc = "Convert the lanes of two `f64` vectors to `f32` and concatenate them into one same-width vector.\n\nValues are rounded to the nearest representable `f32`, with ties resolved to even; overflow produces signed infinity.This is the same as the `as` operator, and follows the IEEE 754 narrowing behavior in round-to-even mode.\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
6240    #[inline(always)]
6241    fn narrow_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f32x8<Self> {
6242        let (a0, a1) = self.split_f64x4(a);
6243        let (b0, b1) = self.split_f64x4(b);
6244        self.combine_f32x4(self.narrow_f64x2(a0, a1), self.narrow_f64x2(b0, b1))
6245    }
6246    #[doc = "Convert the lanes of two `f64` vectors to `f32` and concatenate them into one same-width vector.\n\nFor floating-point vectors this is identical to `narrow`, including its rounding and overflow behavior.\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
6247    #[inline(always)]
6248    fn saturating_narrow_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f32x8<Self> {
6249        let (a0, a1) = self.split_f64x4(a);
6250        let (b0, b1) = self.split_f64x4(b);
6251        self.combine_f32x4(
6252            self.saturating_narrow_f64x2(a0, a1),
6253            self.saturating_narrow_f64x2(b0, b1),
6254        )
6255    }
6256    #[doc = "Convert the lanes of two `f64` vectors to `f32` and concatenate them into one same-width vector.\n\nFor floating-point vectors this is identical to `narrow`, including its rounding and overflow behavior.\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
6257    #[inline(always)]
6258    fn relaxed_narrow_f64x4(self, a: f64x4<Self>, b: f64x4<Self>) -> f32x8<Self> {
6259        let (a0, a1) = self.split_f64x4(a);
6260        let (b0, b1) = self.split_f64x4(b);
6261        self.combine_f32x4(
6262            self.relaxed_narrow_f64x2(a0, a1),
6263            self.relaxed_narrow_f64x2(b0, b1),
6264        )
6265    }
6266    #[doc = "Convert each floating-point element to an unsigned 64-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
6267    #[inline(always)]
6268    fn cvt_u64_f64x4(self, a: f64x4<Self>) -> u64x4<Self> {
6269        let (a0, a1) = self.split_f64x4(a);
6270        self.combine_u64x2(self.cvt_u64_f64x2(a0), self.cvt_u64_f64x2(a1))
6271    }
6272    #[doc = "Convert each floating-point element to an unsigned 64-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
6273    #[inline(always)]
6274    fn cvt_u64_precise_f64x4(self, a: f64x4<Self>) -> u64x4<Self> {
6275        let (a0, a1) = self.split_f64x4(a);
6276        self.combine_u64x2(
6277            self.cvt_u64_precise_f64x2(a0),
6278            self.cvt_u64_precise_f64x2(a1),
6279        )
6280    }
6281    #[doc = "Convert each floating-point element to a signed 64-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
6282    #[inline(always)]
6283    fn cvt_i64_f64x4(self, a: f64x4<Self>) -> i64x4<Self> {
6284        let (a0, a1) = self.split_f64x4(a);
6285        self.combine_i64x2(self.cvt_i64_f64x2(a0), self.cvt_i64_f64x2(a1))
6286    }
6287    #[doc = "Convert each floating-point element to a signed 64-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
6288    #[inline(always)]
6289    fn cvt_i64_precise_f64x4(self, a: f64x4<Self>) -> i64x4<Self> {
6290        let (a0, a1) = self.split_f64x4(a);
6291        self.combine_i64x2(
6292            self.cvt_i64_precise_f64x2(a0),
6293            self.cvt_i64_precise_f64x2(a1),
6294        )
6295    }
6296    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
6297    #[inline(always)]
6298    fn abs_i64x4(self, a: i64x4<Self>) -> i64x4<Self> {
6299        let (a0, a1) = self.split_i64x4(a);
6300        self.combine_i64x2(self.abs_i64x2(a0), self.abs_i64x2(a1))
6301    }
6302    #[doc = "Create a SIMD vector with all elements set to the given value."]
6303    #[inline(always)]
6304    fn splat_i64x4(self, val: i64) -> i64x4<Self> {
6305        let half = self.splat_i64x2(val);
6306        self.combine_i64x2(half, half)
6307    }
6308    #[doc = "Reverse the order of the vector's elements."]
6309    #[inline(always)]
6310    fn reverse_i64x4(self, a: i64x4<Self>) -> i64x4<Self> {
6311        let (a0, a1) = self.split_i64x4(a);
6312        self.combine_i64x2(self.reverse_i64x2(a1), self.reverse_i64x2(a0))
6313    }
6314    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
6315    fn slide_i64x4<const SHIFT: usize>(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self>;
6316    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
6317    #[inline(always)]
6318    fn slide_within_blocks_i64x4<const SHIFT: usize>(
6319        self,
6320        a: i64x4<Self>,
6321        b: i64x4<Self>,
6322    ) -> i64x4<Self> {
6323        let (a0, a1) = self.split_i64x4(a);
6324        let (b0, b1) = self.split_i64x4(b);
6325        self.combine_i64x2(
6326            self.slide_within_blocks_i64x2::<SHIFT>(a0, b0),
6327            self.slide_within_blocks_i64x2::<SHIFT>(a1, b1),
6328        )
6329    }
6330    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
6331    #[inline(always)]
6332    fn swizzle_dyn_within_blocks_i64x4(self, a: i64x4<Self>, indices: u8x32<Self>) -> i64x4<Self> {
6333        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x32(Bytes::to_bytes(a), indices))
6334    }
6335    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
6336    #[inline(always)]
6337    fn swizzle_dyn_i64x4(self, a: i64x4<Self>, indices: u8x32<Self>) -> i64x4<Self> {
6338        Bytes::from_bytes(self.swizzle_dyn_u8x32(Bytes::to_bytes(a), indices))
6339    }
6340    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
6341    #[inline(always)]
6342    fn swizzle_dyn_precise_i64x4(self, a: i64x4<Self>, indices: u8x32<Self>) -> i64x4<Self> {
6343        Bytes::from_bytes(self.swizzle_dyn_precise_u8x32(Bytes::to_bytes(a), indices))
6344    }
6345    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
6346    #[inline(always)]
6347    fn concat_swizzle_dyn_i64x4(
6348        self,
6349        a: i64x4<Self>,
6350        b: i64x4<Self>,
6351        indices: u8x32<Self>,
6352    ) -> i64x4<Self> {
6353        Bytes::from_bytes(self.concat_swizzle_dyn_u8x32(
6354            Bytes::to_bytes(a),
6355            Bytes::to_bytes(b),
6356            indices,
6357        ))
6358    }
6359    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
6360    #[inline(always)]
6361    fn concat_swizzle_dyn_precise_i64x4(
6362        self,
6363        a: i64x4<Self>,
6364        b: i64x4<Self>,
6365        indices: u8x32<Self>,
6366    ) -> i64x4<Self> {
6367        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x32(
6368            Bytes::to_bytes(a),
6369            Bytes::to_bytes(b),
6370            indices,
6371        ))
6372    }
6373    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
6374    fn compress_i64x4(self, values: i64x4<Self>, mask: mask64x4<Self>) -> i64x4<Self>;
6375    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
6376    fn compress_merge_i64x4(
6377        self,
6378        values: i64x4<Self>,
6379        mask: mask64x4<Self>,
6380        merge: i64x4<Self>,
6381    ) -> i64x4<Self>;
6382    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
6383    fn expand_i64x4(self, values: i64x4<Self>, mask: mask64x4<Self>) -> i64x4<Self>;
6384    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
6385    fn expand_merge_i64x4(
6386        self,
6387        values: i64x4<Self>,
6388        mask: mask64x4<Self>,
6389        merge: i64x4<Self>,
6390    ) -> i64x4<Self>;
6391    #[doc = "Return the number of ones in the binary representation of each element."]
6392    #[inline(always)]
6393    fn count_ones_i64x4(self, a: i64x4<Self>) -> i64x4<Self> {
6394        let (a0, a1) = self.split_i64x4(a);
6395        self.combine_i64x2(self.count_ones_i64x2(a0), self.count_ones_i64x2(a1))
6396    }
6397    #[doc = "Return the number of zeros in the binary representation of each element."]
6398    #[inline(always)]
6399    fn count_zeros_i64x4(self, a: i64x4<Self>) -> i64x4<Self> {
6400        let (a0, a1) = self.split_i64x4(a);
6401        self.combine_i64x2(self.count_zeros_i64x2(a0), self.count_zeros_i64x2(a1))
6402    }
6403    #[doc = "Add two vectors element-wise, wrapping on overflow."]
6404    #[inline(always)]
6405    fn add_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
6406        let (a0, a1) = self.split_i64x4(a);
6407        let (b0, b1) = self.split_i64x4(b);
6408        self.combine_i64x2(self.add_i64x2(a0, b0), self.add_i64x2(a1, b1))
6409    }
6410    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
6411    #[inline(always)]
6412    fn saturating_add_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
6413        let (a0, a1) = self.split_i64x4(a);
6414        let (b0, b1) = self.split_i64x4(b);
6415        self.combine_i64x2(
6416            self.saturating_add_i64x2(a0, b0),
6417            self.saturating_add_i64x2(a1, b1),
6418        )
6419    }
6420    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
6421    #[inline(always)]
6422    fn sub_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
6423        let (a0, a1) = self.split_i64x4(a);
6424        let (b0, b1) = self.split_i64x4(b);
6425        self.combine_i64x2(self.sub_i64x2(a0, b0), self.sub_i64x2(a1, b1))
6426    }
6427    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
6428    #[inline(always)]
6429    fn saturating_sub_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
6430        let (a0, a1) = self.split_i64x4(a);
6431        let (b0, b1) = self.split_i64x4(b);
6432        self.combine_i64x2(
6433            self.saturating_sub_i64x2(a0, b0),
6434            self.saturating_sub_i64x2(a1, b1),
6435        )
6436    }
6437    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
6438    #[inline(always)]
6439    fn mul_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
6440        let (a0, a1) = self.split_i64x4(a);
6441        let (b0, b1) = self.split_i64x4(b);
6442        self.combine_i64x2(self.mul_i64x2(a0, b0), self.mul_i64x2(a1, b1))
6443    }
6444    #[doc = "Compute the bitwise AND of two vectors."]
6445    #[inline(always)]
6446    fn and_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
6447        let (a0, a1) = self.split_i64x4(a);
6448        let (b0, b1) = self.split_i64x4(b);
6449        self.combine_i64x2(self.and_i64x2(a0, b0), self.and_i64x2(a1, b1))
6450    }
6451    #[doc = "Compute the bitwise OR of two vectors."]
6452    #[inline(always)]
6453    fn or_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
6454        let (a0, a1) = self.split_i64x4(a);
6455        let (b0, b1) = self.split_i64x4(b);
6456        self.combine_i64x2(self.or_i64x2(a0, b0), self.or_i64x2(a1, b1))
6457    }
6458    #[doc = "Compute the bitwise XOR of two vectors."]
6459    #[inline(always)]
6460    fn xor_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
6461        let (a0, a1) = self.split_i64x4(a);
6462        let (b0, b1) = self.split_i64x4(b);
6463        self.combine_i64x2(self.xor_i64x2(a0, b0), self.xor_i64x2(a1, b1))
6464    }
6465    #[doc = "Compute the bitwise NOT of the vector."]
6466    #[inline(always)]
6467    fn not_i64x4(self, a: i64x4<Self>) -> i64x4<Self> {
6468        let (a0, a1) = self.split_i64x4(a);
6469        self.combine_i64x2(self.not_i64x2(a0), self.not_i64x2(a1))
6470    }
6471    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
6472    #[inline(always)]
6473    fn shl_i64x4(self, a: i64x4<Self>, shift: u32) -> i64x4<Self> {
6474        let (a0, a1) = self.split_i64x4(a);
6475        self.combine_i64x2(self.shl_i64x2(a0, shift), self.shl_i64x2(a1, shift))
6476    }
6477    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
6478    #[inline(always)]
6479    fn shlv_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
6480        let (a0, a1) = self.split_i64x4(a);
6481        let (b0, b1) = self.split_i64x4(b);
6482        self.combine_i64x2(self.shlv_i64x2(a0, b0), self.shlv_i64x2(a1, b1))
6483    }
6484    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
6485    #[inline(always)]
6486    fn shr_i64x4(self, a: i64x4<Self>, shift: u32) -> i64x4<Self> {
6487        let (a0, a1) = self.split_i64x4(a);
6488        self.combine_i64x2(self.shr_i64x2(a0, shift), self.shr_i64x2(a1, shift))
6489    }
6490    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
6491    #[inline(always)]
6492    fn shrv_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
6493        let (a0, a1) = self.split_i64x4(a);
6494        let (b0, b1) = self.split_i64x4(b);
6495        self.combine_i64x2(self.shrv_i64x2(a0, b0), self.shrv_i64x2(a1, b1))
6496    }
6497    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
6498    #[inline(always)]
6499    fn reduce_max_i64x4(self, a: i64x4<Self>) -> i64 {
6500        let (a0, a1) = self.split_i64x4(a);
6501        self.reduce_max_i64x2(self.max_i64x2(a0, a1))
6502    }
6503    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
6504    #[inline(always)]
6505    fn reduce_min_i64x4(self, a: i64x4<Self>) -> i64 {
6506        let (a0, a1) = self.split_i64x4(a);
6507        self.reduce_min_i64x2(self.min_i64x2(a0, a1))
6508    }
6509    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
6510    #[inline(always)]
6511    fn reduce_sum_i64x4(self, a: i64x4<Self>) -> i64 {
6512        let (a0, a1) = self.split_i64x4(a);
6513        self.reduce_sum_i64x2(self.add_i64x2(a0, a1))
6514    }
6515    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
6516    #[inline(always)]
6517    fn reduce_product_i64x4(self, a: i64x4<Self>) -> i64 {
6518        let (a0, a1) = self.split_i64x4(a);
6519        self.reduce_product_i64x2(self.mul_i64x2(a0, a1))
6520    }
6521    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
6522    #[inline(always)]
6523    fn max_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
6524        let (a0, a1) = self.split_i64x4(a);
6525        let (b0, b1) = self.split_i64x4(b);
6526        self.combine_i64x2(self.max_i64x2(a0, b0), self.max_i64x2(a1, b1))
6527    }
6528    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
6529    #[inline(always)]
6530    fn min_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
6531        let (a0, a1) = self.split_i64x4(a);
6532        let (b0, b1) = self.split_i64x4(b);
6533        self.combine_i64x2(self.min_i64x2(a0, b0), self.min_i64x2(a1, b1))
6534    }
6535    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
6536    #[inline(always)]
6537    fn clamp_i64x4(self, a: i64x4<Self>, b: i64x4<Self>, c: i64x4<Self>) -> i64x4<Self> {
6538        let (a0, a1) = self.split_i64x4(a);
6539        let (b0, b1) = self.split_i64x4(b);
6540        let (c0, c1) = self.split_i64x4(c);
6541        self.combine_i64x2(self.clamp_i64x2(a0, b0, c0), self.clamp_i64x2(a1, b1, c1))
6542    }
6543    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
6544    #[inline(always)]
6545    fn simd_eq_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> mask64x4<Self> {
6546        let (a0, a1) = self.split_i64x4(a);
6547        let (b0, b1) = self.split_i64x4(b);
6548        self.combine_mask64x2(self.simd_eq_i64x2(a0, b0), self.simd_eq_i64x2(a1, b1))
6549    }
6550    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
6551    #[inline(always)]
6552    fn simd_ne_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> mask64x4<Self> {
6553        self.not_mask64x4(self.simd_eq_i64x4(a, b))
6554    }
6555    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
6556    #[inline(always)]
6557    fn simd_lt_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> mask64x4<Self> {
6558        let (a0, a1) = self.split_i64x4(a);
6559        let (b0, b1) = self.split_i64x4(b);
6560        self.combine_mask64x2(self.simd_lt_i64x2(a0, b0), self.simd_lt_i64x2(a1, b1))
6561    }
6562    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
6563    #[inline(always)]
6564    fn simd_le_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> mask64x4<Self> {
6565        let (a0, a1) = self.split_i64x4(a);
6566        let (b0, b1) = self.split_i64x4(b);
6567        self.combine_mask64x2(self.simd_le_i64x2(a0, b0), self.simd_le_i64x2(a1, b1))
6568    }
6569    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
6570    #[inline(always)]
6571    fn simd_ge_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> mask64x4<Self> {
6572        self.simd_le_i64x4(b, a)
6573    }
6574    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
6575    #[inline(always)]
6576    fn simd_gt_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> mask64x4<Self> {
6577        self.simd_lt_i64x4(b, a)
6578    }
6579    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
6580    #[inline(always)]
6581    fn zip_low_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
6582        let (a0, _) = self.split_i64x4(a);
6583        let (b0, _) = self.split_i64x4(b);
6584        self.combine_i64x2(self.zip_low_i64x2(a0, b0), self.zip_high_i64x2(a0, b0))
6585    }
6586    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
6587    #[inline(always)]
6588    fn zip_high_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
6589        let (_, a1) = self.split_i64x4(a);
6590        let (_, b1) = self.split_i64x4(b);
6591        self.combine_i64x2(self.zip_low_i64x2(a1, b1), self.zip_high_i64x2(a1, b1))
6592    }
6593    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
6594    #[inline(always)]
6595    fn unzip_low_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
6596        let (a0, a1) = self.split_i64x4(a);
6597        let (b0, b1) = self.split_i64x4(b);
6598        self.combine_i64x2(self.unzip_low_i64x2(a0, a1), self.unzip_low_i64x2(b0, b1))
6599    }
6600    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
6601    #[inline(always)]
6602    fn unzip_high_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x4<Self> {
6603        let (a0, a1) = self.split_i64x4(a);
6604        let (b0, b1) = self.split_i64x4(b);
6605        self.combine_i64x2(self.unzip_high_i64x2(a0, a1), self.unzip_high_i64x2(b0, b1))
6606    }
6607    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
6608    #[inline(always)]
6609    fn interleave_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> (i64x4<Self>, i64x4<Self>) {
6610        let (a0, a1) = self.split_i64x4(a);
6611        let (b0, b1) = self.split_i64x4(b);
6612        let lo_lo = self.zip_low_i64x2(a0, b0);
6613        let lo_hi = self.zip_high_i64x2(a0, b0);
6614        let hi_lo = self.zip_low_i64x2(a1, b1);
6615        let hi_hi = self.zip_high_i64x2(a1, b1);
6616        (
6617            self.combine_i64x2(lo_lo, lo_hi),
6618            self.combine_i64x2(hi_lo, hi_hi),
6619        )
6620    }
6621    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
6622    #[inline(always)]
6623    fn deinterleave_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> (i64x4<Self>, i64x4<Self>) {
6624        let (a0, a1) = self.split_i64x4(a);
6625        let (b0, b1) = self.split_i64x4(b);
6626        let lo_even = self.unzip_low_i64x2(a0, a1);
6627        let lo_odd = self.unzip_high_i64x2(a0, a1);
6628        let hi_even = self.unzip_low_i64x2(b0, b1);
6629        let hi_odd = self.unzip_high_i64x2(b0, b1);
6630        (
6631            self.combine_i64x2(lo_even, hi_even),
6632            self.combine_i64x2(lo_odd, hi_odd),
6633        )
6634    }
6635    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
6636    #[inline(always)]
6637    fn select_i64x4(self, a: mask64x4<Self>, b: i64x4<Self>, c: i64x4<Self>) -> i64x4<Self> {
6638        let (a0, a1) = self.split_mask64x4(a);
6639        let (b0, b1) = self.split_i64x4(b);
6640        let (c0, c1) = self.split_i64x4(c);
6641        self.combine_i64x2(self.select_i64x2(a0, b0, c0), self.select_i64x2(a1, b1, c1))
6642    }
6643    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
6644    fn combine_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i64x8<Self>;
6645    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
6646    fn split_i64x4(self, a: i64x4<Self>) -> (i64x2<Self>, i64x2<Self>);
6647    #[doc = "Negate each element of the vector, wrapping on overflow."]
6648    #[inline(always)]
6649    fn neg_i64x4(self, a: i64x4<Self>) -> i64x4<Self> {
6650        let (a0, a1) = self.split_i64x4(a);
6651        self.combine_i64x2(self.neg_i64x2(a0), self.neg_i64x2(a1))
6652    }
6653    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
6654    #[inline(always)]
6655    fn narrow_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i32x8<Self> {
6656        let (a0, a1) = self.split_i64x4(a);
6657        let (b0, b1) = self.split_i64x4(b);
6658        self.combine_i32x4(self.narrow_i64x2(a0, a1), self.narrow_i64x2(b0, b1))
6659    }
6660    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
6661    #[inline(always)]
6662    fn saturating_narrow_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i32x8<Self> {
6663        let (a0, a1) = self.split_i64x4(a);
6664        let (b0, b1) = self.split_i64x4(b);
6665        self.combine_i32x4(
6666            self.saturating_narrow_i64x2(a0, a1),
6667            self.saturating_narrow_i64x2(b0, b1),
6668        )
6669    }
6670    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
6671    #[inline(always)]
6672    fn relaxed_narrow_i64x4(self, a: i64x4<Self>, b: i64x4<Self>) -> i32x8<Self> {
6673        let (a0, a1) = self.split_i64x4(a);
6674        let (b0, b1) = self.split_i64x4(b);
6675        self.combine_i32x4(
6676            self.relaxed_narrow_i64x2(a0, a1),
6677            self.relaxed_narrow_i64x2(b0, b1),
6678        )
6679    }
6680    #[doc = "Convert each signed 64-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
6681    #[inline(always)]
6682    fn cvt_f64_i64x4(self, a: i64x4<Self>) -> f64x4<Self> {
6683        let (a0, a1) = self.split_i64x4(a);
6684        self.combine_f64x2(self.cvt_f64_i64x2(a0), self.cvt_f64_i64x2(a1))
6685    }
6686    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
6687    #[inline(always)]
6688    fn abs_u64x4(self, a: u64x4<Self>) -> u64x4<Self> {
6689        a
6690    }
6691    #[doc = "Create a SIMD vector with all elements set to the given value."]
6692    #[inline(always)]
6693    fn splat_u64x4(self, val: u64) -> u64x4<Self> {
6694        let half = self.splat_u64x2(val);
6695        self.combine_u64x2(half, half)
6696    }
6697    #[doc = "Reverse the order of the vector's elements."]
6698    #[inline(always)]
6699    fn reverse_u64x4(self, a: u64x4<Self>) -> u64x4<Self> {
6700        let (a0, a1) = self.split_u64x4(a);
6701        self.combine_u64x2(self.reverse_u64x2(a1), self.reverse_u64x2(a0))
6702    }
6703    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
6704    fn slide_u64x4<const SHIFT: usize>(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self>;
6705    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
6706    #[inline(always)]
6707    fn slide_within_blocks_u64x4<const SHIFT: usize>(
6708        self,
6709        a: u64x4<Self>,
6710        b: u64x4<Self>,
6711    ) -> u64x4<Self> {
6712        let (a0, a1) = self.split_u64x4(a);
6713        let (b0, b1) = self.split_u64x4(b);
6714        self.combine_u64x2(
6715            self.slide_within_blocks_u64x2::<SHIFT>(a0, b0),
6716            self.slide_within_blocks_u64x2::<SHIFT>(a1, b1),
6717        )
6718    }
6719    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
6720    #[inline(always)]
6721    fn swizzle_dyn_within_blocks_u64x4(self, a: u64x4<Self>, indices: u8x32<Self>) -> u64x4<Self> {
6722        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x32(Bytes::to_bytes(a), indices))
6723    }
6724    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
6725    #[inline(always)]
6726    fn swizzle_dyn_u64x4(self, a: u64x4<Self>, indices: u8x32<Self>) -> u64x4<Self> {
6727        Bytes::from_bytes(self.swizzle_dyn_u8x32(Bytes::to_bytes(a), indices))
6728    }
6729    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
6730    #[inline(always)]
6731    fn swizzle_dyn_precise_u64x4(self, a: u64x4<Self>, indices: u8x32<Self>) -> u64x4<Self> {
6732        Bytes::from_bytes(self.swizzle_dyn_precise_u8x32(Bytes::to_bytes(a), indices))
6733    }
6734    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
6735    #[inline(always)]
6736    fn concat_swizzle_dyn_u64x4(
6737        self,
6738        a: u64x4<Self>,
6739        b: u64x4<Self>,
6740        indices: u8x32<Self>,
6741    ) -> u64x4<Self> {
6742        Bytes::from_bytes(self.concat_swizzle_dyn_u8x32(
6743            Bytes::to_bytes(a),
6744            Bytes::to_bytes(b),
6745            indices,
6746        ))
6747    }
6748    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
6749    #[inline(always)]
6750    fn concat_swizzle_dyn_precise_u64x4(
6751        self,
6752        a: u64x4<Self>,
6753        b: u64x4<Self>,
6754        indices: u8x32<Self>,
6755    ) -> u64x4<Self> {
6756        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x32(
6757            Bytes::to_bytes(a),
6758            Bytes::to_bytes(b),
6759            indices,
6760        ))
6761    }
6762    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
6763    fn compress_u64x4(self, values: u64x4<Self>, mask: mask64x4<Self>) -> u64x4<Self>;
6764    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
6765    fn compress_merge_u64x4(
6766        self,
6767        values: u64x4<Self>,
6768        mask: mask64x4<Self>,
6769        merge: u64x4<Self>,
6770    ) -> u64x4<Self>;
6771    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
6772    fn expand_u64x4(self, values: u64x4<Self>, mask: mask64x4<Self>) -> u64x4<Self>;
6773    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
6774    fn expand_merge_u64x4(
6775        self,
6776        values: u64x4<Self>,
6777        mask: mask64x4<Self>,
6778        merge: u64x4<Self>,
6779    ) -> u64x4<Self>;
6780    #[doc = "Return the number of ones in the binary representation of each element."]
6781    #[inline(always)]
6782    fn count_ones_u64x4(self, a: u64x4<Self>) -> u64x4<Self> {
6783        let (a0, a1) = self.split_u64x4(a);
6784        self.combine_u64x2(self.count_ones_u64x2(a0), self.count_ones_u64x2(a1))
6785    }
6786    #[doc = "Return the number of zeros in the binary representation of each element."]
6787    #[inline(always)]
6788    fn count_zeros_u64x4(self, a: u64x4<Self>) -> u64x4<Self> {
6789        let (a0, a1) = self.split_u64x4(a);
6790        self.combine_u64x2(self.count_zeros_u64x2(a0), self.count_zeros_u64x2(a1))
6791    }
6792    #[doc = "Add two vectors element-wise, wrapping on overflow."]
6793    #[inline(always)]
6794    fn add_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
6795        let (a0, a1) = self.split_u64x4(a);
6796        let (b0, b1) = self.split_u64x4(b);
6797        self.combine_u64x2(self.add_u64x2(a0, b0), self.add_u64x2(a1, b1))
6798    }
6799    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
6800    #[inline(always)]
6801    fn saturating_add_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
6802        let (a0, a1) = self.split_u64x4(a);
6803        let (b0, b1) = self.split_u64x4(b);
6804        self.combine_u64x2(
6805            self.saturating_add_u64x2(a0, b0),
6806            self.saturating_add_u64x2(a1, b1),
6807        )
6808    }
6809    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
6810    #[inline(always)]
6811    fn sub_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
6812        let (a0, a1) = self.split_u64x4(a);
6813        let (b0, b1) = self.split_u64x4(b);
6814        self.combine_u64x2(self.sub_u64x2(a0, b0), self.sub_u64x2(a1, b1))
6815    }
6816    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
6817    #[inline(always)]
6818    fn saturating_sub_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
6819        let (a0, a1) = self.split_u64x4(a);
6820        let (b0, b1) = self.split_u64x4(b);
6821        self.combine_u64x2(
6822            self.saturating_sub_u64x2(a0, b0),
6823            self.saturating_sub_u64x2(a1, b1),
6824        )
6825    }
6826    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
6827    #[inline(always)]
6828    fn mul_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
6829        let (a0, a1) = self.split_u64x4(a);
6830        let (b0, b1) = self.split_u64x4(b);
6831        self.combine_u64x2(self.mul_u64x2(a0, b0), self.mul_u64x2(a1, b1))
6832    }
6833    #[doc = "Compute the bitwise AND of two vectors."]
6834    #[inline(always)]
6835    fn and_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
6836        let (a0, a1) = self.split_u64x4(a);
6837        let (b0, b1) = self.split_u64x4(b);
6838        self.combine_u64x2(self.and_u64x2(a0, b0), self.and_u64x2(a1, b1))
6839    }
6840    #[doc = "Compute the bitwise OR of two vectors."]
6841    #[inline(always)]
6842    fn or_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
6843        let (a0, a1) = self.split_u64x4(a);
6844        let (b0, b1) = self.split_u64x4(b);
6845        self.combine_u64x2(self.or_u64x2(a0, b0), self.or_u64x2(a1, b1))
6846    }
6847    #[doc = "Compute the bitwise XOR of two vectors."]
6848    #[inline(always)]
6849    fn xor_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
6850        let (a0, a1) = self.split_u64x4(a);
6851        let (b0, b1) = self.split_u64x4(b);
6852        self.combine_u64x2(self.xor_u64x2(a0, b0), self.xor_u64x2(a1, b1))
6853    }
6854    #[doc = "Compute the bitwise NOT of the vector."]
6855    #[inline(always)]
6856    fn not_u64x4(self, a: u64x4<Self>) -> u64x4<Self> {
6857        let (a0, a1) = self.split_u64x4(a);
6858        self.combine_u64x2(self.not_u64x2(a0), self.not_u64x2(a1))
6859    }
6860    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
6861    #[inline(always)]
6862    fn shl_u64x4(self, a: u64x4<Self>, shift: u32) -> u64x4<Self> {
6863        let (a0, a1) = self.split_u64x4(a);
6864        self.combine_u64x2(self.shl_u64x2(a0, shift), self.shl_u64x2(a1, shift))
6865    }
6866    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
6867    #[inline(always)]
6868    fn shlv_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
6869        let (a0, a1) = self.split_u64x4(a);
6870        let (b0, b1) = self.split_u64x4(b);
6871        self.combine_u64x2(self.shlv_u64x2(a0, b0), self.shlv_u64x2(a1, b1))
6872    }
6873    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
6874    #[inline(always)]
6875    fn shr_u64x4(self, a: u64x4<Self>, shift: u32) -> u64x4<Self> {
6876        let (a0, a1) = self.split_u64x4(a);
6877        self.combine_u64x2(self.shr_u64x2(a0, shift), self.shr_u64x2(a1, shift))
6878    }
6879    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
6880    #[inline(always)]
6881    fn shrv_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
6882        let (a0, a1) = self.split_u64x4(a);
6883        let (b0, b1) = self.split_u64x4(b);
6884        self.combine_u64x2(self.shrv_u64x2(a0, b0), self.shrv_u64x2(a1, b1))
6885    }
6886    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
6887    #[inline(always)]
6888    fn reduce_max_u64x4(self, a: u64x4<Self>) -> u64 {
6889        let (a0, a1) = self.split_u64x4(a);
6890        self.reduce_max_u64x2(self.max_u64x2(a0, a1))
6891    }
6892    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
6893    #[inline(always)]
6894    fn reduce_min_u64x4(self, a: u64x4<Self>) -> u64 {
6895        let (a0, a1) = self.split_u64x4(a);
6896        self.reduce_min_u64x2(self.min_u64x2(a0, a1))
6897    }
6898    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
6899    #[inline(always)]
6900    fn reduce_sum_u64x4(self, a: u64x4<Self>) -> u64 {
6901        let (a0, a1) = self.split_u64x4(a);
6902        self.reduce_sum_u64x2(self.add_u64x2(a0, a1))
6903    }
6904    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
6905    #[inline(always)]
6906    fn reduce_product_u64x4(self, a: u64x4<Self>) -> u64 {
6907        let (a0, a1) = self.split_u64x4(a);
6908        self.reduce_product_u64x2(self.mul_u64x2(a0, a1))
6909    }
6910    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
6911    #[inline(always)]
6912    fn max_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
6913        let (a0, a1) = self.split_u64x4(a);
6914        let (b0, b1) = self.split_u64x4(b);
6915        self.combine_u64x2(self.max_u64x2(a0, b0), self.max_u64x2(a1, b1))
6916    }
6917    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
6918    #[inline(always)]
6919    fn min_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
6920        let (a0, a1) = self.split_u64x4(a);
6921        let (b0, b1) = self.split_u64x4(b);
6922        self.combine_u64x2(self.min_u64x2(a0, b0), self.min_u64x2(a1, b1))
6923    }
6924    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
6925    #[inline(always)]
6926    fn clamp_u64x4(self, a: u64x4<Self>, b: u64x4<Self>, c: u64x4<Self>) -> u64x4<Self> {
6927        let (a0, a1) = self.split_u64x4(a);
6928        let (b0, b1) = self.split_u64x4(b);
6929        let (c0, c1) = self.split_u64x4(c);
6930        self.combine_u64x2(self.clamp_u64x2(a0, b0, c0), self.clamp_u64x2(a1, b1, c1))
6931    }
6932    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
6933    #[inline(always)]
6934    fn simd_eq_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> mask64x4<Self> {
6935        let (a0, a1) = self.split_u64x4(a);
6936        let (b0, b1) = self.split_u64x4(b);
6937        self.combine_mask64x2(self.simd_eq_u64x2(a0, b0), self.simd_eq_u64x2(a1, b1))
6938    }
6939    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
6940    #[inline(always)]
6941    fn simd_ne_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> mask64x4<Self> {
6942        self.not_mask64x4(self.simd_eq_u64x4(a, b))
6943    }
6944    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
6945    #[inline(always)]
6946    fn simd_lt_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> mask64x4<Self> {
6947        let (a0, a1) = self.split_u64x4(a);
6948        let (b0, b1) = self.split_u64x4(b);
6949        self.combine_mask64x2(self.simd_lt_u64x2(a0, b0), self.simd_lt_u64x2(a1, b1))
6950    }
6951    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
6952    #[inline(always)]
6953    fn simd_le_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> mask64x4<Self> {
6954        let (a0, a1) = self.split_u64x4(a);
6955        let (b0, b1) = self.split_u64x4(b);
6956        self.combine_mask64x2(self.simd_le_u64x2(a0, b0), self.simd_le_u64x2(a1, b1))
6957    }
6958    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
6959    #[inline(always)]
6960    fn simd_ge_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> mask64x4<Self> {
6961        self.simd_le_u64x4(b, a)
6962    }
6963    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
6964    #[inline(always)]
6965    fn simd_gt_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> mask64x4<Self> {
6966        self.simd_lt_u64x4(b, a)
6967    }
6968    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
6969    #[inline(always)]
6970    fn zip_low_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
6971        let (a0, _) = self.split_u64x4(a);
6972        let (b0, _) = self.split_u64x4(b);
6973        self.combine_u64x2(self.zip_low_u64x2(a0, b0), self.zip_high_u64x2(a0, b0))
6974    }
6975    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
6976    #[inline(always)]
6977    fn zip_high_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
6978        let (_, a1) = self.split_u64x4(a);
6979        let (_, b1) = self.split_u64x4(b);
6980        self.combine_u64x2(self.zip_low_u64x2(a1, b1), self.zip_high_u64x2(a1, b1))
6981    }
6982    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
6983    #[inline(always)]
6984    fn unzip_low_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
6985        let (a0, a1) = self.split_u64x4(a);
6986        let (b0, b1) = self.split_u64x4(b);
6987        self.combine_u64x2(self.unzip_low_u64x2(a0, a1), self.unzip_low_u64x2(b0, b1))
6988    }
6989    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
6990    #[inline(always)]
6991    fn unzip_high_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x4<Self> {
6992        let (a0, a1) = self.split_u64x4(a);
6993        let (b0, b1) = self.split_u64x4(b);
6994        self.combine_u64x2(self.unzip_high_u64x2(a0, a1), self.unzip_high_u64x2(b0, b1))
6995    }
6996    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
6997    #[inline(always)]
6998    fn interleave_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> (u64x4<Self>, u64x4<Self>) {
6999        let (a0, a1) = self.split_u64x4(a);
7000        let (b0, b1) = self.split_u64x4(b);
7001        let lo_lo = self.zip_low_u64x2(a0, b0);
7002        let lo_hi = self.zip_high_u64x2(a0, b0);
7003        let hi_lo = self.zip_low_u64x2(a1, b1);
7004        let hi_hi = self.zip_high_u64x2(a1, b1);
7005        (
7006            self.combine_u64x2(lo_lo, lo_hi),
7007            self.combine_u64x2(hi_lo, hi_hi),
7008        )
7009    }
7010    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
7011    #[inline(always)]
7012    fn deinterleave_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> (u64x4<Self>, u64x4<Self>) {
7013        let (a0, a1) = self.split_u64x4(a);
7014        let (b0, b1) = self.split_u64x4(b);
7015        let lo_even = self.unzip_low_u64x2(a0, a1);
7016        let lo_odd = self.unzip_high_u64x2(a0, a1);
7017        let hi_even = self.unzip_low_u64x2(b0, b1);
7018        let hi_odd = self.unzip_high_u64x2(b0, b1);
7019        (
7020            self.combine_u64x2(lo_even, hi_even),
7021            self.combine_u64x2(lo_odd, hi_odd),
7022        )
7023    }
7024    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
7025    #[inline(always)]
7026    fn select_u64x4(self, a: mask64x4<Self>, b: u64x4<Self>, c: u64x4<Self>) -> u64x4<Self> {
7027        let (a0, a1) = self.split_mask64x4(a);
7028        let (b0, b1) = self.split_u64x4(b);
7029        let (c0, c1) = self.split_u64x4(c);
7030        self.combine_u64x2(self.select_u64x2(a0, b0, c0), self.select_u64x2(a1, b1, c1))
7031    }
7032    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
7033    fn combine_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u64x8<Self>;
7034    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
7035    fn split_u64x4(self, a: u64x4<Self>) -> (u64x2<Self>, u64x2<Self>);
7036    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
7037    #[inline(always)]
7038    fn narrow_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u32x8<Self> {
7039        let (a0, a1) = self.split_u64x4(a);
7040        let (b0, b1) = self.split_u64x4(b);
7041        self.combine_u32x4(self.narrow_u64x2(a0, a1), self.narrow_u64x2(b0, b1))
7042    }
7043    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
7044    #[inline(always)]
7045    fn saturating_narrow_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u32x8<Self> {
7046        let (a0, a1) = self.split_u64x4(a);
7047        let (b0, b1) = self.split_u64x4(b);
7048        self.combine_u32x4(
7049            self.saturating_narrow_u64x2(a0, a1),
7050            self.saturating_narrow_u64x2(b0, b1),
7051        )
7052    }
7053    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
7054    #[inline(always)]
7055    fn relaxed_narrow_u64x4(self, a: u64x4<Self>, b: u64x4<Self>) -> u32x8<Self> {
7056        let (a0, a1) = self.split_u64x4(a);
7057        let (b0, b1) = self.split_u64x4(b);
7058        self.combine_u32x4(
7059            self.relaxed_narrow_u64x2(a0, a1),
7060            self.relaxed_narrow_u64x2(b0, b1),
7061        )
7062    }
7063    #[doc = "Convert each unsigned 64-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
7064    #[inline(always)]
7065    fn cvt_f64_u64x4(self, a: u64x4<Self>) -> f64x4<Self> {
7066        let (a0, a1) = self.split_u64x4(a);
7067        self.combine_f64x2(self.cvt_f64_u64x2(a0), self.cvt_f64_u64x2(a1))
7068    }
7069    #[doc = "Create a SIMD mask with all lanes set from the given boolean value."]
7070    #[inline(always)]
7071    fn splat_mask64x4(self, val: bool) -> mask64x4<Self> {
7072        let half = self.splat_mask64x2(val);
7073        self.combine_mask64x2(half, half)
7074    }
7075    #[doc = "Create a SIMD mask from a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are ignored."]
7076    #[inline(always)]
7077    fn from_bitmask_mask64x4(self, bits: u64) -> mask64x4<Self> {
7078        let lo = self.from_bitmask_mask64x2(bits);
7079        let hi = self.from_bitmask_mask64x2(bits >> 2usize);
7080        self.combine_mask64x2(lo, hi)
7081    }
7082    #[doc = "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared."]
7083    #[inline(always)]
7084    fn to_bitmask_mask64x4(self, a: mask64x4<Self>) -> u64 {
7085        let (lo, hi) = self.split_mask64x4(a);
7086        let lo = self.to_bitmask_mask64x2(lo);
7087        let hi = self.to_bitmask_mask64x2(hi);
7088        lo | (hi << 2usize)
7089    }
7090    #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."]
7091    fn from_vector_mask64x4(self, vector: i64x4<Self>) -> mask64x4<Self>;
7092    #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."]
7093    fn to_vector_mask64x4(self, a: mask64x4<Self>) -> i64x4<Self>;
7094    #[doc = "Set one logical lane of a SIMD mask."]
7095    fn set_mask64x4(self, a: &mut mask64x4<Self>, index: usize, value: bool) -> ();
7096    #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
7097    fn rotate_elements_left_mask64x4<const OFFSET: usize>(
7098        self,
7099        a: mask64x4<Self>,
7100    ) -> mask64x4<Self>;
7101    #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
7102    fn rotate_elements_right_mask64x4<const OFFSET: usize>(
7103        self,
7104        a: mask64x4<Self>,
7105    ) -> mask64x4<Self>;
7106    #[doc = "Compute the logical AND of two masks."]
7107    #[inline(always)]
7108    fn and_mask64x4(self, a: mask64x4<Self>, b: mask64x4<Self>) -> mask64x4<Self> {
7109        let (a0, a1) = self.split_mask64x4(a);
7110        let (b0, b1) = self.split_mask64x4(b);
7111        self.combine_mask64x2(self.and_mask64x2(a0, b0), self.and_mask64x2(a1, b1))
7112    }
7113    #[doc = "Compute the logical OR of two masks."]
7114    #[inline(always)]
7115    fn or_mask64x4(self, a: mask64x4<Self>, b: mask64x4<Self>) -> mask64x4<Self> {
7116        let (a0, a1) = self.split_mask64x4(a);
7117        let (b0, b1) = self.split_mask64x4(b);
7118        self.combine_mask64x2(self.or_mask64x2(a0, b0), self.or_mask64x2(a1, b1))
7119    }
7120    #[doc = "Compute the logical XOR of two masks."]
7121    #[inline(always)]
7122    fn xor_mask64x4(self, a: mask64x4<Self>, b: mask64x4<Self>) -> mask64x4<Self> {
7123        let (a0, a1) = self.split_mask64x4(a);
7124        let (b0, b1) = self.split_mask64x4(b);
7125        self.combine_mask64x2(self.xor_mask64x2(a0, b0), self.xor_mask64x2(a1, b1))
7126    }
7127    #[doc = "Compute the logical NOT of the mask."]
7128    #[inline(always)]
7129    fn not_mask64x4(self, a: mask64x4<Self>) -> mask64x4<Self> {
7130        let (a0, a1) = self.split_mask64x4(a);
7131        self.combine_mask64x2(self.not_mask64x2(a0), self.not_mask64x2(a1))
7132    }
7133    #[doc = "Reverse the order of the mask's logical lanes."]
7134    #[inline(always)]
7135    fn reverse_mask64x4(self, a: mask64x4<Self>) -> mask64x4<Self> {
7136        let (a0, a1) = self.split_mask64x4(a);
7137        self.combine_mask64x2(self.reverse_mask64x2(a1), self.reverse_mask64x2(a0))
7138    }
7139    #[doc = "Select elements from `b` and `c` based on the mask operand `a`.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
7140    #[inline(always)]
7141    fn select_mask64x4(
7142        self,
7143        a: mask64x4<Self>,
7144        b: mask64x4<Self>,
7145        c: mask64x4<Self>,
7146    ) -> mask64x4<Self> {
7147        let (a0, a1) = self.split_mask64x4(a);
7148        let (b0, b1) = self.split_mask64x4(b);
7149        let (c0, c1) = self.split_mask64x4(c);
7150        self.combine_mask64x2(
7151            self.select_mask64x2(a0, b0, c0),
7152            self.select_mask64x2(a1, b1, c1),
7153        )
7154    }
7155    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
7156    #[inline(always)]
7157    fn simd_eq_mask64x4(self, a: mask64x4<Self>, b: mask64x4<Self>) -> mask64x4<Self> {
7158        let (a0, a1) = self.split_mask64x4(a);
7159        let (b0, b1) = self.split_mask64x4(b);
7160        self.combine_mask64x2(self.simd_eq_mask64x2(a0, b0), self.simd_eq_mask64x2(a1, b1))
7161    }
7162    #[doc = "Compare two masks element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
7163    #[inline(always)]
7164    fn simd_ne_mask64x4(self, a: mask64x4<Self>, b: mask64x4<Self>) -> mask64x4<Self> {
7165        self.not_mask64x4(self.simd_eq_mask64x4(a, b))
7166    }
7167    #[doc = "Returns true if any logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
7168    #[inline(always)]
7169    fn any_true_mask64x4(self, a: mask64x4<Self>) -> bool {
7170        let (a0, a1) = self.split_mask64x4(a);
7171        self.any_true_mask64x2(self.or_mask64x2(a0, a1))
7172    }
7173    #[doc = "Returns true if all logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
7174    #[inline(always)]
7175    fn all_true_mask64x4(self, a: mask64x4<Self>) -> bool {
7176        let (a0, a1) = self.split_mask64x4(a);
7177        self.all_true_mask64x2(self.and_mask64x2(a0, a1))
7178    }
7179    #[doc = "Returns true if any logical lanes in this mask are false.\n\nThis is logically equivalent to `!all_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
7180    #[inline(always)]
7181    fn any_false_mask64x4(self, a: mask64x4<Self>) -> bool {
7182        let (a0, a1) = self.split_mask64x4(a);
7183        self.any_false_mask64x2(self.and_mask64x2(a0, a1))
7184    }
7185    #[doc = "Returns true if all logical lanes in this mask are false.\n\nThis is logically equivalent to `!any_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
7186    #[inline(always)]
7187    fn all_false_mask64x4(self, a: mask64x4<Self>) -> bool {
7188        let (a0, a1) = self.split_mask64x4(a);
7189        self.all_false_mask64x2(self.or_mask64x2(a0, a1))
7190    }
7191    #[doc = "Combine two vectors into a single vector with twice the width.\n\n`a` provides the lower elements and `b` provides the upper elements."]
7192    fn combine_mask64x4(self, a: mask64x4<Self>, b: mask64x4<Self>) -> mask64x8<Self>;
7193    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
7194    fn split_mask64x4(self, a: mask64x4<Self>) -> (mask64x2<Self>, mask64x2<Self>);
7195    #[doc = "Narrow each boolean lane of two masks and concatenate them into one mask of the same logical width, preserving each value.\n\n`a` supplies the lower result lanes and `b` supplies the upper result lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
7196    #[inline(always)]
7197    fn narrow_mask64x4(self, a: mask64x4<Self>, b: mask64x4<Self>) -> mask32x8<Self> {
7198        let (a0, a1) = self.split_mask64x4(a);
7199        let (b0, b1) = self.split_mask64x4(b);
7200        self.combine_mask32x4(self.narrow_mask64x2(a0, a1), self.narrow_mask64x2(b0, b1))
7201    }
7202    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
7203    #[inline(always)]
7204    fn abs_f32x16(self, a: f32x16<Self>) -> f32x16<Self> {
7205        let (a0, a1) = self.split_f32x16(a);
7206        self.combine_f32x8(self.abs_f32x8(a0), self.abs_f32x8(a1))
7207    }
7208    #[doc = "Create a SIMD vector with all elements set to the given value."]
7209    #[inline(always)]
7210    fn splat_f32x16(self, val: f32) -> f32x16<Self> {
7211        let half = self.splat_f32x8(val);
7212        self.combine_f32x8(half, half)
7213    }
7214    #[doc = "Reverse the order of the vector's elements."]
7215    #[inline(always)]
7216    fn reverse_f32x16(self, a: f32x16<Self>) -> f32x16<Self> {
7217        let (a0, a1) = self.split_f32x16(a);
7218        self.combine_f32x8(self.reverse_f32x8(a1), self.reverse_f32x8(a0))
7219    }
7220    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
7221    fn slide_f32x16<const SHIFT: usize>(self, a: f32x16<Self>, b: f32x16<Self>) -> f32x16<Self>;
7222    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
7223    #[inline(always)]
7224    fn slide_within_blocks_f32x16<const SHIFT: usize>(
7225        self,
7226        a: f32x16<Self>,
7227        b: f32x16<Self>,
7228    ) -> f32x16<Self> {
7229        let (a0, a1) = self.split_f32x16(a);
7230        let (b0, b1) = self.split_f32x16(b);
7231        self.combine_f32x8(
7232            self.slide_within_blocks_f32x8::<SHIFT>(a0, b0),
7233            self.slide_within_blocks_f32x8::<SHIFT>(a1, b1),
7234        )
7235    }
7236    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
7237    #[inline(always)]
7238    fn swizzle_dyn_within_blocks_f32x16(
7239        self,
7240        a: f32x16<Self>,
7241        indices: u8x64<Self>,
7242    ) -> f32x16<Self> {
7243        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x64(Bytes::to_bytes(a), indices))
7244    }
7245    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
7246    #[inline(always)]
7247    fn swizzle_dyn_f32x16(self, a: f32x16<Self>, indices: u8x64<Self>) -> f32x16<Self> {
7248        Bytes::from_bytes(self.swizzle_dyn_u8x64(Bytes::to_bytes(a), indices))
7249    }
7250    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
7251    #[inline(always)]
7252    fn swizzle_dyn_precise_f32x16(self, a: f32x16<Self>, indices: u8x64<Self>) -> f32x16<Self> {
7253        Bytes::from_bytes(self.swizzle_dyn_precise_u8x64(Bytes::to_bytes(a), indices))
7254    }
7255    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
7256    #[inline(always)]
7257    fn concat_swizzle_dyn_f32x16(
7258        self,
7259        a: f32x16<Self>,
7260        b: f32x16<Self>,
7261        indices: u8x64<Self>,
7262    ) -> f32x16<Self> {
7263        Bytes::from_bytes(self.concat_swizzle_dyn_u8x64(
7264            Bytes::to_bytes(a),
7265            Bytes::to_bytes(b),
7266            indices,
7267        ))
7268    }
7269    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
7270    #[inline(always)]
7271    fn concat_swizzle_dyn_precise_f32x16(
7272        self,
7273        a: f32x16<Self>,
7274        b: f32x16<Self>,
7275        indices: u8x64<Self>,
7276    ) -> f32x16<Self> {
7277        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x64(
7278            Bytes::to_bytes(a),
7279            Bytes::to_bytes(b),
7280            indices,
7281        ))
7282    }
7283    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
7284    fn compress_f32x16(self, values: f32x16<Self>, mask: mask32x16<Self>) -> f32x16<Self>;
7285    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
7286    fn compress_merge_f32x16(
7287        self,
7288        values: f32x16<Self>,
7289        mask: mask32x16<Self>,
7290        merge: f32x16<Self>,
7291    ) -> f32x16<Self>;
7292    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
7293    fn expand_f32x16(self, values: f32x16<Self>, mask: mask32x16<Self>) -> f32x16<Self>;
7294    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
7295    fn expand_merge_f32x16(
7296        self,
7297        values: f32x16<Self>,
7298        mask: mask32x16<Self>,
7299        merge: f32x16<Self>,
7300    ) -> f32x16<Self>;
7301    #[doc = "Negate each element of the vector."]
7302    #[inline(always)]
7303    fn neg_f32x16(self, a: f32x16<Self>) -> f32x16<Self> {
7304        let (a0, a1) = self.split_f32x16(a);
7305        self.combine_f32x8(self.neg_f32x8(a0), self.neg_f32x8(a1))
7306    }
7307    #[doc = "Compute the square root of each element.\n\nNegative elements other than `-0.0` will become NaN."]
7308    #[inline(always)]
7309    fn sqrt_f32x16(self, a: f32x16<Self>) -> f32x16<Self> {
7310        let (a0, a1) = self.split_f32x16(a);
7311        self.combine_f32x8(self.sqrt_f32x8(a0), self.sqrt_f32x8(a1))
7312    }
7313    #[doc = "Compute an approximate reciprocal (`1. / x`) for each element.\n\nThis uses a fast hardware estimate where available, and falls back to exact division otherwise.\n\nOn x86 for `f32`, this has a relative error less than `1.5 × 2^-12`. On `AArch64` (`f32` and `f64`), this has a relative error less than `2^-8`. The precision of this operation may change as new platform support is added."]
7314    #[inline(always)]
7315    fn approximate_recip_f32x16(self, a: f32x16<Self>) -> f32x16<Self> {
7316        let (a0, a1) = self.split_f32x16(a);
7317        self.combine_f32x8(
7318            self.approximate_recip_f32x8(a0),
7319            self.approximate_recip_f32x8(a1),
7320        )
7321    }
7322    #[doc = "Add two vectors element-wise."]
7323    #[inline(always)]
7324    fn add_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> f32x16<Self> {
7325        let (a0, a1) = self.split_f32x16(a);
7326        let (b0, b1) = self.split_f32x16(b);
7327        self.combine_f32x8(self.add_f32x8(a0, b0), self.add_f32x8(a1, b1))
7328    }
7329    #[doc = "Subtract two vectors element-wise."]
7330    #[inline(always)]
7331    fn sub_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> f32x16<Self> {
7332        let (a0, a1) = self.split_f32x16(a);
7333        let (b0, b1) = self.split_f32x16(b);
7334        self.combine_f32x8(self.sub_f32x8(a0, b0), self.sub_f32x8(a1, b1))
7335    }
7336    #[doc = "Multiply two vectors element-wise."]
7337    #[inline(always)]
7338    fn mul_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> f32x16<Self> {
7339        let (a0, a1) = self.split_f32x16(a);
7340        let (b0, b1) = self.split_f32x16(b);
7341        self.combine_f32x8(self.mul_f32x8(a0, b0), self.mul_f32x8(a1, b1))
7342    }
7343    #[doc = "Divide two vectors element-wise."]
7344    #[inline(always)]
7345    fn div_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> f32x16<Self> {
7346        let (a0, a1) = self.split_f32x16(a);
7347        let (b0, b1) = self.split_f32x16(b);
7348        self.combine_f32x8(self.div_f32x8(a0, b0), self.div_f32x8(a1, b1))
7349    }
7350    #[doc = "Return a vector with the magnitude of `a` and the sign of `b` for each element.\n\nThis operation copies the sign bit, so if an input element is NaN, the output element will be a NaN with the same payload and a copied sign bit."]
7351    #[inline(always)]
7352    fn copysign_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> f32x16<Self> {
7353        let (a0, a1) = self.split_f32x16(a);
7354        let (b0, b1) = self.split_f32x16(b);
7355        self.combine_f32x8(self.copysign_f32x8(a0, b0), self.copysign_f32x8(a1, b1))
7356    }
7357    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
7358    #[inline(always)]
7359    fn reduce_max_f32x16(self, a: f32x16<Self>) -> f32 {
7360        let (a0, a1) = self.split_f32x16(a);
7361        self.reduce_max_f32x8(self.max_f32x8(a0, a1))
7362    }
7363    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
7364    #[inline(always)]
7365    fn reduce_min_f32x16(self, a: f32x16<Self>) -> f32 {
7366        let (a0, a1) = self.split_f32x16(a);
7367        self.reduce_min_f32x8(self.min_f32x8(a0, a1))
7368    }
7369    #[doc = "Return the maximum element in the vector, ignoring quiet NaNs.\n\nFor integer vectors, this operation is the same as `reduce_max`.\n\nFor floating-point vectors, quiet NaNs are ignored. If there is at least one numeric lane, this returns the true maximum of the numeric lanes. If all lanes are quiet NaNs, this returns NaN, with an unspecified payload and sign.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned.\n\nIf any lane is a *signaling* NaN, the result is fully non-deterministic: it may be NaN or a numeric lane and is not guaranteed to be the true maximum.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
7370    #[inline(always)]
7371    fn reduce_max_precise_f32x16(self, a: f32x16<Self>) -> f32 {
7372        let (a0, a1) = self.split_f32x16(a);
7373        self.reduce_max_precise_f32x8(self.max_precise_f32x8(a0, a1))
7374    }
7375    #[doc = "Return the minimum element in the vector, ignoring quiet NaNs.\n\nFor integer vectors, this operation is the same as `reduce_min`.\n\nFor floating-point vectors, quiet NaNs are ignored. If there is at least one numeric lane, this returns the true minimum of the numeric lanes. If all lanes are quiet NaNs, this returns NaN, with an unspecified payload and sign.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned.\n\nIf any lane is a *signaling* NaN, the result is fully non-deterministic: it may be NaN or a numeric lane and is not guaranteed to be the true minimum.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
7376    #[inline(always)]
7377    fn reduce_min_precise_f32x16(self, a: f32x16<Self>) -> f32 {
7378        let (a0, a1) = self.split_f32x16(a);
7379        self.reduce_min_precise_f32x8(self.min_precise_f32x8(a0, a1))
7380    }
7381    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
7382    #[inline(always)]
7383    fn reduce_sum_f32x16(self, a: f32x16<Self>) -> f32 {
7384        let (a0, a1) = self.split_f32x16(a);
7385        self.reduce_sum_f32x8(self.add_f32x8(a0, a1))
7386    }
7387    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
7388    #[inline(always)]
7389    fn reduce_product_f32x16(self, a: f32x16<Self>) -> f32 {
7390        let (a0, a1) = self.split_f32x16(a);
7391        self.reduce_product_f32x8(self.mul_f32x8(a0, a1))
7392    }
7393    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
7394    #[inline(always)]
7395    fn max_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> f32x16<Self> {
7396        let (a0, a1) = self.split_f32x16(a);
7397        let (b0, b1) = self.split_f32x16(b);
7398        self.combine_f32x8(self.max_f32x8(a0, b0), self.max_f32x8(a1, b1))
7399    }
7400    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
7401    #[inline(always)]
7402    fn min_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> f32x16<Self> {
7403        let (a0, a1) = self.split_f32x16(a);
7404        let (b0, b1) = self.split_f32x16(b);
7405        self.combine_f32x8(self.min_f32x8(a0, b0), self.min_f32x8(a1, b1))
7406    }
7407    #[doc = "Return the element-wise maximum of two vectors.\n\nFor integer vectors, this operation is the same as `max`.\n\nFor floating-point vectors, if one operand is a quiet NaN and the other is not, this operation will choose the non-NaN operand.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\nIf a floating-point operand is a *signaling* NaN, the result is not just implementation-defined, but fully non-deterministic: it may be either NaN or the non-NaN operand.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
7408    #[inline(always)]
7409    fn max_precise_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> f32x16<Self> {
7410        let (a0, a1) = self.split_f32x16(a);
7411        let (b0, b1) = self.split_f32x16(b);
7412        self.combine_f32x8(
7413            self.max_precise_f32x8(a0, b0),
7414            self.max_precise_f32x8(a1, b1),
7415        )
7416    }
7417    #[doc = "Return the element-wise minimum of two vectors.\n\nFor integer vectors, this operation is the same as `min`.\n\nFor floating-point vectors, if one operand is a quiet NaN and the other is not, this operation will choose the non-NaN operand.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\nIf a floating-point operand is a *signaling* NaN, the result is not just implementation-defined, but fully non-deterministic: it may be either NaN or the non-NaN operand.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
7418    #[inline(always)]
7419    fn min_precise_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> f32x16<Self> {
7420        let (a0, a1) = self.split_f32x16(a);
7421        let (b0, b1) = self.split_f32x16(b);
7422        self.combine_f32x8(
7423            self.min_precise_f32x8(a0, b0),
7424            self.min_precise_f32x8(a1, b1),
7425        )
7426    }
7427    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
7428    #[inline(always)]
7429    fn clamp_f32x16(self, a: f32x16<Self>, b: f32x16<Self>, c: f32x16<Self>) -> f32x16<Self> {
7430        let (a0, a1) = self.split_f32x16(a);
7431        let (b0, b1) = self.split_f32x16(b);
7432        let (c0, c1) = self.split_f32x16(c);
7433        self.combine_f32x8(self.clamp_f32x8(a0, b0, c0), self.clamp_f32x8(a1, b1, c1))
7434    }
7435    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
7436    #[inline(always)]
7437    fn simd_eq_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> mask32x16<Self> {
7438        let (a0, a1) = self.split_f32x16(a);
7439        let (b0, b1) = self.split_f32x16(b);
7440        self.combine_mask32x8(self.simd_eq_f32x8(a0, b0), self.simd_eq_f32x8(a1, b1))
7441    }
7442    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
7443    #[inline(always)]
7444    fn simd_ne_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> mask32x16<Self> {
7445        self.not_mask32x16(self.simd_eq_f32x16(a, b))
7446    }
7447    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
7448    #[inline(always)]
7449    fn simd_lt_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> mask32x16<Self> {
7450        let (a0, a1) = self.split_f32x16(a);
7451        let (b0, b1) = self.split_f32x16(b);
7452        self.combine_mask32x8(self.simd_lt_f32x8(a0, b0), self.simd_lt_f32x8(a1, b1))
7453    }
7454    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
7455    #[inline(always)]
7456    fn simd_le_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> mask32x16<Self> {
7457        let (a0, a1) = self.split_f32x16(a);
7458        let (b0, b1) = self.split_f32x16(b);
7459        self.combine_mask32x8(self.simd_le_f32x8(a0, b0), self.simd_le_f32x8(a1, b1))
7460    }
7461    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
7462    #[inline(always)]
7463    fn simd_ge_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> mask32x16<Self> {
7464        self.simd_le_f32x16(b, a)
7465    }
7466    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
7467    #[inline(always)]
7468    fn simd_gt_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> mask32x16<Self> {
7469        self.simd_lt_f32x16(b, a)
7470    }
7471    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
7472    #[inline(always)]
7473    fn zip_low_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> f32x16<Self> {
7474        let (a0, _) = self.split_f32x16(a);
7475        let (b0, _) = self.split_f32x16(b);
7476        self.combine_f32x8(self.zip_low_f32x8(a0, b0), self.zip_high_f32x8(a0, b0))
7477    }
7478    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
7479    #[inline(always)]
7480    fn zip_high_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> f32x16<Self> {
7481        let (_, a1) = self.split_f32x16(a);
7482        let (_, b1) = self.split_f32x16(b);
7483        self.combine_f32x8(self.zip_low_f32x8(a1, b1), self.zip_high_f32x8(a1, b1))
7484    }
7485    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
7486    #[inline(always)]
7487    fn unzip_low_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> f32x16<Self> {
7488        let (a0, a1) = self.split_f32x16(a);
7489        let (b0, b1) = self.split_f32x16(b);
7490        self.combine_f32x8(self.unzip_low_f32x8(a0, a1), self.unzip_low_f32x8(b0, b1))
7491    }
7492    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
7493    #[inline(always)]
7494    fn unzip_high_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> f32x16<Self> {
7495        let (a0, a1) = self.split_f32x16(a);
7496        let (b0, b1) = self.split_f32x16(b);
7497        self.combine_f32x8(self.unzip_high_f32x8(a0, a1), self.unzip_high_f32x8(b0, b1))
7498    }
7499    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
7500    #[inline(always)]
7501    fn interleave_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> (f32x16<Self>, f32x16<Self>) {
7502        let (a0, a1) = self.split_f32x16(a);
7503        let (b0, b1) = self.split_f32x16(b);
7504        let lo_lo = self.zip_low_f32x8(a0, b0);
7505        let lo_hi = self.zip_high_f32x8(a0, b0);
7506        let hi_lo = self.zip_low_f32x8(a1, b1);
7507        let hi_hi = self.zip_high_f32x8(a1, b1);
7508        (
7509            self.combine_f32x8(lo_lo, lo_hi),
7510            self.combine_f32x8(hi_lo, hi_hi),
7511        )
7512    }
7513    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
7514    #[inline(always)]
7515    fn deinterleave_f32x16(self, a: f32x16<Self>, b: f32x16<Self>) -> (f32x16<Self>, f32x16<Self>) {
7516        let (a0, a1) = self.split_f32x16(a);
7517        let (b0, b1) = self.split_f32x16(b);
7518        let lo_even = self.unzip_low_f32x8(a0, a1);
7519        let lo_odd = self.unzip_high_f32x8(a0, a1);
7520        let hi_even = self.unzip_low_f32x8(b0, b1);
7521        let hi_odd = self.unzip_high_f32x8(b0, b1);
7522        (
7523            self.combine_f32x8(lo_even, hi_even),
7524            self.combine_f32x8(lo_odd, hi_odd),
7525        )
7526    }
7527    #[doc = "Compute `(a * b) + c` (fused multiply-add) for each element.\n\nDepending on platform support, the result may be computed with only one rounding error, or may be implemented as a regular multiply followed by an add, which will result in two rounding errors."]
7528    #[inline(always)]
7529    fn mul_add_f32x16(self, a: f32x16<Self>, b: f32x16<Self>, c: f32x16<Self>) -> f32x16<Self> {
7530        let (a0, a1) = self.split_f32x16(a);
7531        let (b0, b1) = self.split_f32x16(b);
7532        let (c0, c1) = self.split_f32x16(c);
7533        self.combine_f32x8(
7534            self.mul_add_f32x8(a0, b0, c0),
7535            self.mul_add_f32x8(a1, b1, c1),
7536        )
7537    }
7538    #[doc = "Compute `(a * b) + c` for each element, with a single rounding at the end.\n\nThe result is the infinite-precision product-plus-add rounded once to the element type. This may be substantially slower than `mul_add` on platforms without fused multiply-add instructions, including WebAssembly.\n\n# Precision guarantees\n\nThis function is **not** susceptible to [the bug](https://github.com/rust-lang/compiler-builtins/issues/1262) in Rust standard library and in musl libc that causes incorrect rounding for near-zero values on CPUs without hardware support for this operation.\n\nOn the tier-2 i586-* targets, this function is correct if and only if SSE2 is available on the CPU.\n\nThe exact `NaN` payloads as well as signaling `NaN`s are not preserved."]
7539    #[inline(always)]
7540    fn mul_add_precise_f32x16(
7541        self,
7542        a: f32x16<Self>,
7543        b: f32x16<Self>,
7544        c: f32x16<Self>,
7545    ) -> f32x16<Self> {
7546        let (a0, a1) = self.split_f32x16(a);
7547        let (b0, b1) = self.split_f32x16(b);
7548        let (c0, c1) = self.split_f32x16(c);
7549        self.combine_f32x8(
7550            self.mul_add_precise_f32x8(a0, b0, c0),
7551            self.mul_add_precise_f32x8(a1, b1, c1),
7552        )
7553    }
7554    #[doc = "Compute `(a * b) - c` (fused multiply-subtract) for each element.\n\nDepending on platform support, the result may be computed with only one rounding error, or may be implemented as a regular multiply followed by a subtract, which will result in two rounding errors."]
7555    #[inline(always)]
7556    fn mul_sub_f32x16(self, a: f32x16<Self>, b: f32x16<Self>, c: f32x16<Self>) -> f32x16<Self> {
7557        let (a0, a1) = self.split_f32x16(a);
7558        let (b0, b1) = self.split_f32x16(b);
7559        let (c0, c1) = self.split_f32x16(c);
7560        self.combine_f32x8(
7561            self.mul_sub_f32x8(a0, b0, c0),
7562            self.mul_sub_f32x8(a1, b1, c1),
7563        )
7564    }
7565    #[doc = "Compute `(a * b) - c` for each element, with a single rounding at the end.\n\nThe result is the infinite-precision product-minus-subtrahend rounded once to the element type. This may be substantially slower than `mul_sub` on platforms without fused multiply-add instructions, including WebAssembly.\n        # Precision guarantees\n\nThis function is **not** susceptible to [the bug](https://github.com/rust-lang/compiler-builtins/issues/1262) in Rust standard library and in musl libc that causes incorrect rounding for near-zero values on CPUs without hardware support for this operation.\n\nOn the tier-2 i586-* targets, this function is correct if and only if SSE2 is available on the CPU.\n\nThe exact `NaN` payloads as well as signaling `NaN`s are not preserved."]
7566    #[inline(always)]
7567    fn mul_sub_precise_f32x16(
7568        self,
7569        a: f32x16<Self>,
7570        b: f32x16<Self>,
7571        c: f32x16<Self>,
7572    ) -> f32x16<Self> {
7573        let (a0, a1) = self.split_f32x16(a);
7574        let (b0, b1) = self.split_f32x16(b);
7575        let (c0, c1) = self.split_f32x16(c);
7576        self.combine_f32x8(
7577            self.mul_sub_precise_f32x8(a0, b0, c0),
7578            self.mul_sub_precise_f32x8(a1, b1, c1),
7579        )
7580    }
7581    #[doc = "Return the largest integer less than or equal to each element, that is, round towards negative infinity."]
7582    #[inline(always)]
7583    fn floor_f32x16(self, a: f32x16<Self>) -> f32x16<Self> {
7584        let (a0, a1) = self.split_f32x16(a);
7585        self.combine_f32x8(self.floor_f32x8(a0), self.floor_f32x8(a1))
7586    }
7587    #[doc = "Return the smallest integer greater than or equal to each element, that is, round towards positive infinity."]
7588    #[inline(always)]
7589    fn ceil_f32x16(self, a: f32x16<Self>) -> f32x16<Self> {
7590        let (a0, a1) = self.split_f32x16(a);
7591        self.combine_f32x8(self.ceil_f32x8(a0), self.ceil_f32x8(a1))
7592    }
7593    #[doc = "Round each element to the nearest integer, with ties rounding to the nearest even integer."]
7594    #[inline(always)]
7595    fn round_ties_even_f32x16(self, a: f32x16<Self>) -> f32x16<Self> {
7596        let (a0, a1) = self.split_f32x16(a);
7597        self.combine_f32x8(
7598            self.round_ties_even_f32x8(a0),
7599            self.round_ties_even_f32x8(a1),
7600        )
7601    }
7602    #[doc = "Round each element to the nearest integer, with ties rounding away from zero.\n\n## Performance considerations\n\nOnly `AArch64` has native instructions for this operation. `round` has to be emulated on all other platforms which is around 2-4x slower than `round_ties_even`. Prefer using [`round_ties_even`](SimdFloat::round_ties_even) if possible."]
7603    #[inline(always)]
7604    fn round_f32x16(self, a: f32x16<Self>) -> f32x16<Self> {
7605        let (a0, a1) = self.split_f32x16(a);
7606        self.combine_f32x8(self.round_f32x8(a0), self.round_f32x8(a1))
7607    }
7608    #[doc = "Return the fractional part of each element.\n\nThis is equivalent to `a - a.trunc()`."]
7609    #[inline(always)]
7610    fn fract_f32x16(self, a: f32x16<Self>) -> f32x16<Self> {
7611        let (a0, a1) = self.split_f32x16(a);
7612        self.combine_f32x8(self.fract_f32x8(a0), self.fract_f32x8(a1))
7613    }
7614    #[doc = "Return the integer part of each element, rounding towards zero."]
7615    #[inline(always)]
7616    fn trunc_f32x16(self, a: f32x16<Self>) -> f32x16<Self> {
7617        let (a0, a1) = self.split_f32x16(a);
7618        self.combine_f32x8(self.trunc_f32x8(a0), self.trunc_f32x8(a1))
7619    }
7620    #[doc = "Converts radians to degrees.\n\nThe precision of this function is non-deterministic. This means it varies by platform, Rust version, and can even differ within the same execution from one invocation to the next."]
7621    #[inline(always)]
7622    fn to_degrees_f32x16(self, a: f32x16<Self>) -> f32x16<Self> {
7623        let (a0, a1) = self.split_f32x16(a);
7624        self.combine_f32x8(self.to_degrees_f32x8(a0), self.to_degrees_f32x8(a1))
7625    }
7626    #[doc = "Converts degrees to radians.\n\nThe precision of this function is non-deterministic. This means it varies by platform, Rust version, and can even differ within the same execution from one invocation to the next."]
7627    #[inline(always)]
7628    fn to_radians_f32x16(self, a: f32x16<Self>) -> f32x16<Self> {
7629        let (a0, a1) = self.split_f32x16(a);
7630        self.combine_f32x8(self.to_radians_f32x8(a0), self.to_radians_f32x8(a1))
7631    }
7632    #[doc = "Return a mask indicating which elements are NaN."]
7633    fn is_nan_f32x16(self, a: f32x16<Self>) -> mask32x16<Self>;
7634    #[doc = "Return a mask indicating which elements are positive or negative infinite."]
7635    fn is_infinite_f32x16(self, a: f32x16<Self>) -> mask32x16<Self>;
7636    #[doc = "Return a mask indicating which elements are neither infinite nor NaN."]
7637    fn is_finite_f32x16(self, a: f32x16<Self>) -> mask32x16<Self>;
7638    #[doc = "Return a mask indicating which elements are subnormal.\n\nThis classifies the stored bit pattern, even when floating-point operations treat subnormals as zero."]
7639    fn is_subnormal_f32x16(self, a: f32x16<Self>) -> mask32x16<Self>;
7640    #[doc = "Return a mask indicating which elements are neither zero, infinite, subnormal, or NaN."]
7641    fn is_normal_f32x16(self, a: f32x16<Self>) -> mask32x16<Self>;
7642    #[doc = "Return a mask indicating which elements have a positive sign, including `+0.0`, NaNs with positive sign bit and positive infinity.\n\nNaN inputs may produce an unexpected or non-portable result, see [`f32::is_sign_positive`] for details."]
7643    fn is_sign_positive_f32x16(self, a: f32x16<Self>) -> mask32x16<Self>;
7644    #[doc = "Return a mask indicating which elements have a negative sign, including `-0.0`, NaNs with negative sign bit and negative infinity.\n\nNaN inputs may produce an unexpected or non-portable result, see [`f32::is_sign_negative`] for details."]
7645    fn is_sign_negative_f32x16(self, a: f32x16<Self>) -> mask32x16<Self>;
7646    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
7647    #[inline(always)]
7648    fn select_f32x16(self, a: mask32x16<Self>, b: f32x16<Self>, c: f32x16<Self>) -> f32x16<Self> {
7649        let (a0, a1) = self.split_mask32x16(a);
7650        let (b0, b1) = self.split_f32x16(b);
7651        let (c0, c1) = self.split_f32x16(c);
7652        self.combine_f32x8(self.select_f32x8(a0, b0, c0), self.select_f32x8(a1, b1, c1))
7653    }
7654    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
7655    fn split_f32x16(self, a: f32x16<Self>) -> (f32x8<Self>, f32x8<Self>);
7656    #[doc = "Widen every `f32` lane exactly into two same-width `f64` vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
7657    #[inline(always)]
7658    fn widen_f32x16(self, a: f32x16<Self>) -> (f64x8<Self>, f64x8<Self>) {
7659        let (a0, a1) = self.split_f32x16(a);
7660        let (a00, a01) = self.widen_f32x8(a0);
7661        let (a10, a11) = self.widen_f32x8(a1);
7662        (self.combine_f64x4(a00, a01), self.combine_f64x4(a10, a11))
7663    }
7664    #[doc = "Convert each floating-point element to an unsigned 32-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results.\n\nOn x86 platforms below AVX-512, this operation will still be slower than converting to `i32`, because there is no native instruction for converting to `u32`.\nIf you know your values fit within range of an `i32`, you should convert to an `i32` and cast to your desired datatype afterwards."]
7665    #[inline(always)]
7666    fn cvt_u32_f32x16(self, a: f32x16<Self>) -> u32x16<Self> {
7667        let (a0, a1) = self.split_f32x16(a);
7668        self.combine_u32x8(self.cvt_u32_f32x8(a0), self.cvt_u32_f32x8(a1))
7669    }
7670    #[doc = "Convert each floating-point element to an unsigned 32-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
7671    #[inline(always)]
7672    fn cvt_u32_precise_f32x16(self, a: f32x16<Self>) -> u32x16<Self> {
7673        let (a0, a1) = self.split_f32x16(a);
7674        self.combine_u32x8(
7675            self.cvt_u32_precise_f32x8(a0),
7676            self.cvt_u32_precise_f32x8(a1),
7677        )
7678    }
7679    #[doc = "Convert each floating-point element to a signed 32-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
7680    #[inline(always)]
7681    fn cvt_i32_f32x16(self, a: f32x16<Self>) -> i32x16<Self> {
7682        let (a0, a1) = self.split_f32x16(a);
7683        self.combine_i32x8(self.cvt_i32_f32x8(a0), self.cvt_i32_f32x8(a1))
7684    }
7685    #[doc = "Convert each floating-point element to a signed 32-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
7686    #[inline(always)]
7687    fn cvt_i32_precise_f32x16(self, a: f32x16<Self>) -> i32x16<Self> {
7688        let (a0, a1) = self.split_f32x16(a);
7689        self.combine_i32x8(
7690            self.cvt_i32_precise_f32x8(a0),
7691            self.cvt_i32_precise_f32x8(a1),
7692        )
7693    }
7694    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
7695    #[inline(always)]
7696    fn abs_i8x64(self, a: i8x64<Self>) -> i8x64<Self> {
7697        let (a0, a1) = self.split_i8x64(a);
7698        self.combine_i8x32(self.abs_i8x32(a0), self.abs_i8x32(a1))
7699    }
7700    #[doc = "Create a SIMD vector with all elements set to the given value."]
7701    #[inline(always)]
7702    fn splat_i8x64(self, val: i8) -> i8x64<Self> {
7703        let half = self.splat_i8x32(val);
7704        self.combine_i8x32(half, half)
7705    }
7706    #[doc = "Reverse the order of the vector's elements."]
7707    #[inline(always)]
7708    fn reverse_i8x64(self, a: i8x64<Self>) -> i8x64<Self> {
7709        let (a0, a1) = self.split_i8x64(a);
7710        self.combine_i8x32(self.reverse_i8x32(a1), self.reverse_i8x32(a0))
7711    }
7712    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
7713    fn slide_i8x64<const SHIFT: usize>(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self>;
7714    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
7715    #[inline(always)]
7716    fn slide_within_blocks_i8x64<const SHIFT: usize>(
7717        self,
7718        a: i8x64<Self>,
7719        b: i8x64<Self>,
7720    ) -> i8x64<Self> {
7721        let (a0, a1) = self.split_i8x64(a);
7722        let (b0, b1) = self.split_i8x64(b);
7723        self.combine_i8x32(
7724            self.slide_within_blocks_i8x32::<SHIFT>(a0, b0),
7725            self.slide_within_blocks_i8x32::<SHIFT>(a1, b1),
7726        )
7727    }
7728    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
7729    #[inline(always)]
7730    fn swizzle_dyn_within_blocks_i8x64(self, a: i8x64<Self>, indices: u8x64<Self>) -> i8x64<Self> {
7731        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x64(Bytes::to_bytes(a), indices))
7732    }
7733    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
7734    #[inline(always)]
7735    fn swizzle_dyn_i8x64(self, a: i8x64<Self>, indices: u8x64<Self>) -> i8x64<Self> {
7736        Bytes::from_bytes(self.swizzle_dyn_u8x64(Bytes::to_bytes(a), indices))
7737    }
7738    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
7739    #[inline(always)]
7740    fn swizzle_dyn_precise_i8x64(self, a: i8x64<Self>, indices: u8x64<Self>) -> i8x64<Self> {
7741        Bytes::from_bytes(self.swizzle_dyn_precise_u8x64(Bytes::to_bytes(a), indices))
7742    }
7743    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
7744    #[inline(always)]
7745    fn concat_swizzle_dyn_i8x64(
7746        self,
7747        a: i8x64<Self>,
7748        b: i8x64<Self>,
7749        indices: u8x64<Self>,
7750    ) -> i8x64<Self> {
7751        Bytes::from_bytes(self.concat_swizzle_dyn_u8x64(
7752            Bytes::to_bytes(a),
7753            Bytes::to_bytes(b),
7754            indices,
7755        ))
7756    }
7757    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
7758    #[inline(always)]
7759    fn concat_swizzle_dyn_precise_i8x64(
7760        self,
7761        a: i8x64<Self>,
7762        b: i8x64<Self>,
7763        indices: u8x64<Self>,
7764    ) -> i8x64<Self> {
7765        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x64(
7766            Bytes::to_bytes(a),
7767            Bytes::to_bytes(b),
7768            indices,
7769        ))
7770    }
7771    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
7772    fn compress_i8x64(self, values: i8x64<Self>, mask: mask8x64<Self>) -> i8x64<Self>;
7773    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
7774    fn compress_merge_i8x64(
7775        self,
7776        values: i8x64<Self>,
7777        mask: mask8x64<Self>,
7778        merge: i8x64<Self>,
7779    ) -> i8x64<Self>;
7780    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
7781    fn expand_i8x64(self, values: i8x64<Self>, mask: mask8x64<Self>) -> i8x64<Self>;
7782    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
7783    fn expand_merge_i8x64(
7784        self,
7785        values: i8x64<Self>,
7786        mask: mask8x64<Self>,
7787        merge: i8x64<Self>,
7788    ) -> i8x64<Self>;
7789    #[doc = "Return the number of ones in the binary representation of each element."]
7790    #[inline(always)]
7791    fn count_ones_i8x64(self, a: i8x64<Self>) -> i8x64<Self> {
7792        let (a0, a1) = self.split_i8x64(a);
7793        self.combine_i8x32(self.count_ones_i8x32(a0), self.count_ones_i8x32(a1))
7794    }
7795    #[doc = "Return the number of zeros in the binary representation of each element."]
7796    #[inline(always)]
7797    fn count_zeros_i8x64(self, a: i8x64<Self>) -> i8x64<Self> {
7798        let (a0, a1) = self.split_i8x64(a);
7799        self.combine_i8x32(self.count_zeros_i8x32(a0), self.count_zeros_i8x32(a1))
7800    }
7801    #[doc = "Add two vectors element-wise, wrapping on overflow."]
7802    #[inline(always)]
7803    fn add_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
7804        let (a0, a1) = self.split_i8x64(a);
7805        let (b0, b1) = self.split_i8x64(b);
7806        self.combine_i8x32(self.add_i8x32(a0, b0), self.add_i8x32(a1, b1))
7807    }
7808    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
7809    #[inline(always)]
7810    fn saturating_add_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
7811        let (a0, a1) = self.split_i8x64(a);
7812        let (b0, b1) = self.split_i8x64(b);
7813        self.combine_i8x32(
7814            self.saturating_add_i8x32(a0, b0),
7815            self.saturating_add_i8x32(a1, b1),
7816        )
7817    }
7818    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
7819    #[inline(always)]
7820    fn sub_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
7821        let (a0, a1) = self.split_i8x64(a);
7822        let (b0, b1) = self.split_i8x64(b);
7823        self.combine_i8x32(self.sub_i8x32(a0, b0), self.sub_i8x32(a1, b1))
7824    }
7825    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
7826    #[inline(always)]
7827    fn saturating_sub_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
7828        let (a0, a1) = self.split_i8x64(a);
7829        let (b0, b1) = self.split_i8x64(b);
7830        self.combine_i8x32(
7831            self.saturating_sub_i8x32(a0, b0),
7832            self.saturating_sub_i8x32(a1, b1),
7833        )
7834    }
7835    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
7836    #[inline(always)]
7837    fn mul_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
7838        let (a0, a1) = self.split_i8x64(a);
7839        let (b0, b1) = self.split_i8x64(b);
7840        self.combine_i8x32(self.mul_i8x32(a0, b0), self.mul_i8x32(a1, b1))
7841    }
7842    #[doc = "Compute the bitwise AND of two vectors."]
7843    #[inline(always)]
7844    fn and_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
7845        let (a0, a1) = self.split_i8x64(a);
7846        let (b0, b1) = self.split_i8x64(b);
7847        self.combine_i8x32(self.and_i8x32(a0, b0), self.and_i8x32(a1, b1))
7848    }
7849    #[doc = "Compute the bitwise OR of two vectors."]
7850    #[inline(always)]
7851    fn or_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
7852        let (a0, a1) = self.split_i8x64(a);
7853        let (b0, b1) = self.split_i8x64(b);
7854        self.combine_i8x32(self.or_i8x32(a0, b0), self.or_i8x32(a1, b1))
7855    }
7856    #[doc = "Compute the bitwise XOR of two vectors."]
7857    #[inline(always)]
7858    fn xor_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
7859        let (a0, a1) = self.split_i8x64(a);
7860        let (b0, b1) = self.split_i8x64(b);
7861        self.combine_i8x32(self.xor_i8x32(a0, b0), self.xor_i8x32(a1, b1))
7862    }
7863    #[doc = "Compute the bitwise NOT of the vector."]
7864    #[inline(always)]
7865    fn not_i8x64(self, a: i8x64<Self>) -> i8x64<Self> {
7866        let (a0, a1) = self.split_i8x64(a);
7867        self.combine_i8x32(self.not_i8x32(a0), self.not_i8x32(a1))
7868    }
7869    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
7870    #[inline(always)]
7871    fn shl_i8x64(self, a: i8x64<Self>, shift: u32) -> i8x64<Self> {
7872        let (a0, a1) = self.split_i8x64(a);
7873        self.combine_i8x32(self.shl_i8x32(a0, shift), self.shl_i8x32(a1, shift))
7874    }
7875    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
7876    #[inline(always)]
7877    fn shlv_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
7878        let (a0, a1) = self.split_i8x64(a);
7879        let (b0, b1) = self.split_i8x64(b);
7880        self.combine_i8x32(self.shlv_i8x32(a0, b0), self.shlv_i8x32(a1, b1))
7881    }
7882    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
7883    #[inline(always)]
7884    fn shr_i8x64(self, a: i8x64<Self>, shift: u32) -> i8x64<Self> {
7885        let (a0, a1) = self.split_i8x64(a);
7886        self.combine_i8x32(self.shr_i8x32(a0, shift), self.shr_i8x32(a1, shift))
7887    }
7888    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
7889    #[inline(always)]
7890    fn shrv_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
7891        let (a0, a1) = self.split_i8x64(a);
7892        let (b0, b1) = self.split_i8x64(b);
7893        self.combine_i8x32(self.shrv_i8x32(a0, b0), self.shrv_i8x32(a1, b1))
7894    }
7895    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
7896    #[inline(always)]
7897    fn reduce_max_i8x64(self, a: i8x64<Self>) -> i8 {
7898        let (a0, a1) = self.split_i8x64(a);
7899        self.reduce_max_i8x32(self.max_i8x32(a0, a1))
7900    }
7901    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
7902    #[inline(always)]
7903    fn reduce_min_i8x64(self, a: i8x64<Self>) -> i8 {
7904        let (a0, a1) = self.split_i8x64(a);
7905        self.reduce_min_i8x32(self.min_i8x32(a0, a1))
7906    }
7907    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
7908    #[inline(always)]
7909    fn reduce_sum_i8x64(self, a: i8x64<Self>) -> i8 {
7910        let (a0, a1) = self.split_i8x64(a);
7911        self.reduce_sum_i8x32(self.add_i8x32(a0, a1))
7912    }
7913    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
7914    #[inline(always)]
7915    fn reduce_product_i8x64(self, a: i8x64<Self>) -> i8 {
7916        let (a0, a1) = self.split_i8x64(a);
7917        self.reduce_product_i8x32(self.mul_i8x32(a0, a1))
7918    }
7919    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
7920    #[inline(always)]
7921    fn max_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
7922        let (a0, a1) = self.split_i8x64(a);
7923        let (b0, b1) = self.split_i8x64(b);
7924        self.combine_i8x32(self.max_i8x32(a0, b0), self.max_i8x32(a1, b1))
7925    }
7926    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
7927    #[inline(always)]
7928    fn min_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
7929        let (a0, a1) = self.split_i8x64(a);
7930        let (b0, b1) = self.split_i8x64(b);
7931        self.combine_i8x32(self.min_i8x32(a0, b0), self.min_i8x32(a1, b1))
7932    }
7933    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
7934    #[inline(always)]
7935    fn clamp_i8x64(self, a: i8x64<Self>, b: i8x64<Self>, c: i8x64<Self>) -> i8x64<Self> {
7936        let (a0, a1) = self.split_i8x64(a);
7937        let (b0, b1) = self.split_i8x64(b);
7938        let (c0, c1) = self.split_i8x64(c);
7939        self.combine_i8x32(self.clamp_i8x32(a0, b0, c0), self.clamp_i8x32(a1, b1, c1))
7940    }
7941    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
7942    #[inline(always)]
7943    fn simd_eq_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> mask8x64<Self> {
7944        let (a0, a1) = self.split_i8x64(a);
7945        let (b0, b1) = self.split_i8x64(b);
7946        self.combine_mask8x32(self.simd_eq_i8x32(a0, b0), self.simd_eq_i8x32(a1, b1))
7947    }
7948    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
7949    #[inline(always)]
7950    fn simd_ne_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> mask8x64<Self> {
7951        self.not_mask8x64(self.simd_eq_i8x64(a, b))
7952    }
7953    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
7954    #[inline(always)]
7955    fn simd_lt_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> mask8x64<Self> {
7956        let (a0, a1) = self.split_i8x64(a);
7957        let (b0, b1) = self.split_i8x64(b);
7958        self.combine_mask8x32(self.simd_lt_i8x32(a0, b0), self.simd_lt_i8x32(a1, b1))
7959    }
7960    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
7961    #[inline(always)]
7962    fn simd_le_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> mask8x64<Self> {
7963        let (a0, a1) = self.split_i8x64(a);
7964        let (b0, b1) = self.split_i8x64(b);
7965        self.combine_mask8x32(self.simd_le_i8x32(a0, b0), self.simd_le_i8x32(a1, b1))
7966    }
7967    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
7968    #[inline(always)]
7969    fn simd_ge_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> mask8x64<Self> {
7970        self.simd_le_i8x64(b, a)
7971    }
7972    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
7973    #[inline(always)]
7974    fn simd_gt_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> mask8x64<Self> {
7975        self.simd_lt_i8x64(b, a)
7976    }
7977    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
7978    #[inline(always)]
7979    fn zip_low_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
7980        let (a0, _) = self.split_i8x64(a);
7981        let (b0, _) = self.split_i8x64(b);
7982        self.combine_i8x32(self.zip_low_i8x32(a0, b0), self.zip_high_i8x32(a0, b0))
7983    }
7984    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
7985    #[inline(always)]
7986    fn zip_high_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
7987        let (_, a1) = self.split_i8x64(a);
7988        let (_, b1) = self.split_i8x64(b);
7989        self.combine_i8x32(self.zip_low_i8x32(a1, b1), self.zip_high_i8x32(a1, b1))
7990    }
7991    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
7992    #[inline(always)]
7993    fn unzip_low_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
7994        let (a0, a1) = self.split_i8x64(a);
7995        let (b0, b1) = self.split_i8x64(b);
7996        self.combine_i8x32(self.unzip_low_i8x32(a0, a1), self.unzip_low_i8x32(b0, b1))
7997    }
7998    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
7999    #[inline(always)]
8000    fn unzip_high_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i8x64<Self> {
8001        let (a0, a1) = self.split_i8x64(a);
8002        let (b0, b1) = self.split_i8x64(b);
8003        self.combine_i8x32(self.unzip_high_i8x32(a0, a1), self.unzip_high_i8x32(b0, b1))
8004    }
8005    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
8006    #[inline(always)]
8007    fn interleave_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> (i8x64<Self>, i8x64<Self>) {
8008        let (a0, a1) = self.split_i8x64(a);
8009        let (b0, b1) = self.split_i8x64(b);
8010        let lo_lo = self.zip_low_i8x32(a0, b0);
8011        let lo_hi = self.zip_high_i8x32(a0, b0);
8012        let hi_lo = self.zip_low_i8x32(a1, b1);
8013        let hi_hi = self.zip_high_i8x32(a1, b1);
8014        (
8015            self.combine_i8x32(lo_lo, lo_hi),
8016            self.combine_i8x32(hi_lo, hi_hi),
8017        )
8018    }
8019    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
8020    #[inline(always)]
8021    fn deinterleave_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> (i8x64<Self>, i8x64<Self>) {
8022        let (a0, a1) = self.split_i8x64(a);
8023        let (b0, b1) = self.split_i8x64(b);
8024        let lo_even = self.unzip_low_i8x32(a0, a1);
8025        let lo_odd = self.unzip_high_i8x32(a0, a1);
8026        let hi_even = self.unzip_low_i8x32(b0, b1);
8027        let hi_odd = self.unzip_high_i8x32(b0, b1);
8028        (
8029            self.combine_i8x32(lo_even, hi_even),
8030            self.combine_i8x32(lo_odd, hi_odd),
8031        )
8032    }
8033    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
8034    #[inline(always)]
8035    fn select_i8x64(self, a: mask8x64<Self>, b: i8x64<Self>, c: i8x64<Self>) -> i8x64<Self> {
8036        let (a0, a1) = self.split_mask8x64(a);
8037        let (b0, b1) = self.split_i8x64(b);
8038        let (c0, c1) = self.split_i8x64(c);
8039        self.combine_i8x32(self.select_i8x32(a0, b0, c0), self.select_i8x32(a1, b1, c1))
8040    }
8041    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
8042    fn split_i8x64(self, a: i8x64<Self>) -> (i8x32<Self>, i8x32<Self>);
8043    #[doc = "Negate each element of the vector, wrapping on overflow."]
8044    #[inline(always)]
8045    fn neg_i8x64(self, a: i8x64<Self>) -> i8x64<Self> {
8046        let (a0, a1) = self.split_i8x64(a);
8047        self.combine_i8x32(self.neg_i8x32(a0), self.neg_i8x32(a1))
8048    }
8049    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
8050    #[inline(always)]
8051    fn widen_i8x64(self, a: i8x64<Self>) -> (i16x32<Self>, i16x32<Self>) {
8052        let (a0, a1) = self.split_i8x64(a);
8053        let (a00, a01) = self.widen_i8x32(a0);
8054        let (a10, a11) = self.widen_i8x32(a1);
8055        (self.combine_i16x16(a00, a01), self.combine_i16x16(a10, a11))
8056    }
8057    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
8058    #[inline(always)]
8059    fn widening_mul_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> (i16x32<Self>, i16x32<Self>) {
8060        let (a0, a1) = self.split_i8x64(a);
8061        let (b0, b1) = self.split_i8x64(b);
8062        let (low0, low1) = self.widening_mul_i8x32(a0, b0);
8063        let (high0, high1) = self.widening_mul_i8x32(a1, b1);
8064        (
8065            self.combine_i16x16(low0, low1),
8066            self.combine_i16x16(high0, high1),
8067        )
8068    }
8069    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
8070    #[inline(always)]
8071    fn widening_add_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> (i16x32<Self>, i16x32<Self>) {
8072        let (a0, a1) = self.split_i8x64(a);
8073        let (b0, b1) = self.split_i8x64(b);
8074        let (low0, low1) = self.widening_add_i8x32(a0, b0);
8075        let (high0, high1) = self.widening_add_i8x32(a1, b1);
8076        (
8077            self.combine_i16x16(low0, low1),
8078            self.combine_i16x16(high0, high1),
8079        )
8080    }
8081    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
8082    #[inline(always)]
8083    fn pairwise_widening_add_i8x64(self, a: i8x64<Self>) -> i16x32<Self> {
8084        let (a0, a1) = self.split_i8x64(a);
8085        self.combine_i16x16(
8086            self.pairwise_widening_add_i8x32(a0),
8087            self.pairwise_widening_add_i8x32(a1),
8088        )
8089    }
8090    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
8091    #[inline(always)]
8092    fn pairwise_dot_product_i8x64(self, a: i8x64<Self>, b: i8x64<Self>) -> i16x32<Self> {
8093        let (a0, a1) = self.split_i8x64(a);
8094        let (b0, b1) = self.split_i8x64(b);
8095        self.combine_i16x16(
8096            self.pairwise_dot_product_i8x32(a0, b0),
8097            self.pairwise_dot_product_i8x32(a1, b1),
8098        )
8099    }
8100    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
8101    #[inline(always)]
8102    fn abs_u8x64(self, a: u8x64<Self>) -> u8x64<Self> {
8103        a
8104    }
8105    #[doc = "Create a SIMD vector with all elements set to the given value."]
8106    #[inline(always)]
8107    fn splat_u8x64(self, val: u8) -> u8x64<Self> {
8108        let half = self.splat_u8x32(val);
8109        self.combine_u8x32(half, half)
8110    }
8111    #[doc = "Reverse the order of the vector's elements."]
8112    #[inline(always)]
8113    fn reverse_u8x64(self, a: u8x64<Self>) -> u8x64<Self> {
8114        let (a0, a1) = self.split_u8x64(a);
8115        self.combine_u8x32(self.reverse_u8x32(a1), self.reverse_u8x32(a0))
8116    }
8117    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
8118    fn slide_u8x64<const SHIFT: usize>(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self>;
8119    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
8120    #[inline(always)]
8121    fn slide_within_blocks_u8x64<const SHIFT: usize>(
8122        self,
8123        a: u8x64<Self>,
8124        b: u8x64<Self>,
8125    ) -> u8x64<Self> {
8126        let (a0, a1) = self.split_u8x64(a);
8127        let (b0, b1) = self.split_u8x64(b);
8128        self.combine_u8x32(
8129            self.slide_within_blocks_u8x32::<SHIFT>(a0, b0),
8130            self.slide_within_blocks_u8x32::<SHIFT>(a1, b1),
8131        )
8132    }
8133    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
8134    #[inline(always)]
8135    fn swizzle_dyn_within_blocks_u8x64(self, a: u8x64<Self>, indices: u8x64<Self>) -> u8x64<Self> {
8136        let (a0, a1) = self.split_u8x64(a);
8137        let (indices0, indices1) = self.split_u8x64(indices);
8138        self.combine_u8x32(
8139            self.swizzle_dyn_within_blocks_u8x32(a0, indices0),
8140            self.swizzle_dyn_within_blocks_u8x32(a1, indices1),
8141        )
8142    }
8143    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
8144    fn swizzle_dyn_u8x64(self, a: u8x64<Self>, indices: u8x64<Self>) -> u8x64<Self>;
8145    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
8146    fn swizzle_dyn_precise_u8x64(self, a: u8x64<Self>, indices: u8x64<Self>) -> u8x64<Self>;
8147    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
8148    fn concat_swizzle_dyn_u8x64(
8149        self,
8150        a: u8x64<Self>,
8151        b: u8x64<Self>,
8152        indices: u8x64<Self>,
8153    ) -> u8x64<Self>;
8154    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
8155    fn concat_swizzle_dyn_precise_u8x64(
8156        self,
8157        a: u8x64<Self>,
8158        b: u8x64<Self>,
8159        indices: u8x64<Self>,
8160    ) -> u8x64<Self>;
8161    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
8162    fn compress_u8x64(self, values: u8x64<Self>, mask: mask8x64<Self>) -> u8x64<Self>;
8163    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
8164    fn compress_merge_u8x64(
8165        self,
8166        values: u8x64<Self>,
8167        mask: mask8x64<Self>,
8168        merge: u8x64<Self>,
8169    ) -> u8x64<Self>;
8170    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
8171    fn expand_u8x64(self, values: u8x64<Self>, mask: mask8x64<Self>) -> u8x64<Self>;
8172    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
8173    fn expand_merge_u8x64(
8174        self,
8175        values: u8x64<Self>,
8176        mask: mask8x64<Self>,
8177        merge: u8x64<Self>,
8178    ) -> u8x64<Self>;
8179    #[doc = "Return the number of ones in the binary representation of each element."]
8180    #[inline(always)]
8181    fn count_ones_u8x64(self, a: u8x64<Self>) -> u8x64<Self> {
8182        let (a0, a1) = self.split_u8x64(a);
8183        self.combine_u8x32(self.count_ones_u8x32(a0), self.count_ones_u8x32(a1))
8184    }
8185    #[doc = "Return the number of zeros in the binary representation of each element."]
8186    #[inline(always)]
8187    fn count_zeros_u8x64(self, a: u8x64<Self>) -> u8x64<Self> {
8188        let (a0, a1) = self.split_u8x64(a);
8189        self.combine_u8x32(self.count_zeros_u8x32(a0), self.count_zeros_u8x32(a1))
8190    }
8191    #[doc = "Add two vectors element-wise, wrapping on overflow."]
8192    #[inline(always)]
8193    fn add_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
8194        let (a0, a1) = self.split_u8x64(a);
8195        let (b0, b1) = self.split_u8x64(b);
8196        self.combine_u8x32(self.add_u8x32(a0, b0), self.add_u8x32(a1, b1))
8197    }
8198    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
8199    #[inline(always)]
8200    fn saturating_add_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
8201        let (a0, a1) = self.split_u8x64(a);
8202        let (b0, b1) = self.split_u8x64(b);
8203        self.combine_u8x32(
8204            self.saturating_add_u8x32(a0, b0),
8205            self.saturating_add_u8x32(a1, b1),
8206        )
8207    }
8208    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
8209    #[inline(always)]
8210    fn sub_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
8211        let (a0, a1) = self.split_u8x64(a);
8212        let (b0, b1) = self.split_u8x64(b);
8213        self.combine_u8x32(self.sub_u8x32(a0, b0), self.sub_u8x32(a1, b1))
8214    }
8215    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
8216    #[inline(always)]
8217    fn saturating_sub_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
8218        let (a0, a1) = self.split_u8x64(a);
8219        let (b0, b1) = self.split_u8x64(b);
8220        self.combine_u8x32(
8221            self.saturating_sub_u8x32(a0, b0),
8222            self.saturating_sub_u8x32(a1, b1),
8223        )
8224    }
8225    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
8226    #[inline(always)]
8227    fn mul_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
8228        let (a0, a1) = self.split_u8x64(a);
8229        let (b0, b1) = self.split_u8x64(b);
8230        self.combine_u8x32(self.mul_u8x32(a0, b0), self.mul_u8x32(a1, b1))
8231    }
8232    #[doc = "Compute the bitwise AND of two vectors."]
8233    #[inline(always)]
8234    fn and_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
8235        let (a0, a1) = self.split_u8x64(a);
8236        let (b0, b1) = self.split_u8x64(b);
8237        self.combine_u8x32(self.and_u8x32(a0, b0), self.and_u8x32(a1, b1))
8238    }
8239    #[doc = "Compute the bitwise OR of two vectors."]
8240    #[inline(always)]
8241    fn or_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
8242        let (a0, a1) = self.split_u8x64(a);
8243        let (b0, b1) = self.split_u8x64(b);
8244        self.combine_u8x32(self.or_u8x32(a0, b0), self.or_u8x32(a1, b1))
8245    }
8246    #[doc = "Compute the bitwise XOR of two vectors."]
8247    #[inline(always)]
8248    fn xor_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
8249        let (a0, a1) = self.split_u8x64(a);
8250        let (b0, b1) = self.split_u8x64(b);
8251        self.combine_u8x32(self.xor_u8x32(a0, b0), self.xor_u8x32(a1, b1))
8252    }
8253    #[doc = "Compute the bitwise NOT of the vector."]
8254    #[inline(always)]
8255    fn not_u8x64(self, a: u8x64<Self>) -> u8x64<Self> {
8256        let (a0, a1) = self.split_u8x64(a);
8257        self.combine_u8x32(self.not_u8x32(a0), self.not_u8x32(a1))
8258    }
8259    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
8260    #[inline(always)]
8261    fn shl_u8x64(self, a: u8x64<Self>, shift: u32) -> u8x64<Self> {
8262        let (a0, a1) = self.split_u8x64(a);
8263        self.combine_u8x32(self.shl_u8x32(a0, shift), self.shl_u8x32(a1, shift))
8264    }
8265    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
8266    #[inline(always)]
8267    fn shlv_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
8268        let (a0, a1) = self.split_u8x64(a);
8269        let (b0, b1) = self.split_u8x64(b);
8270        self.combine_u8x32(self.shlv_u8x32(a0, b0), self.shlv_u8x32(a1, b1))
8271    }
8272    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
8273    #[inline(always)]
8274    fn shr_u8x64(self, a: u8x64<Self>, shift: u32) -> u8x64<Self> {
8275        let (a0, a1) = self.split_u8x64(a);
8276        self.combine_u8x32(self.shr_u8x32(a0, shift), self.shr_u8x32(a1, shift))
8277    }
8278    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
8279    #[inline(always)]
8280    fn shrv_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
8281        let (a0, a1) = self.split_u8x64(a);
8282        let (b0, b1) = self.split_u8x64(b);
8283        self.combine_u8x32(self.shrv_u8x32(a0, b0), self.shrv_u8x32(a1, b1))
8284    }
8285    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
8286    #[inline(always)]
8287    fn reduce_max_u8x64(self, a: u8x64<Self>) -> u8 {
8288        let (a0, a1) = self.split_u8x64(a);
8289        self.reduce_max_u8x32(self.max_u8x32(a0, a1))
8290    }
8291    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
8292    #[inline(always)]
8293    fn reduce_min_u8x64(self, a: u8x64<Self>) -> u8 {
8294        let (a0, a1) = self.split_u8x64(a);
8295        self.reduce_min_u8x32(self.min_u8x32(a0, a1))
8296    }
8297    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
8298    #[inline(always)]
8299    fn reduce_sum_u8x64(self, a: u8x64<Self>) -> u8 {
8300        let (a0, a1) = self.split_u8x64(a);
8301        self.reduce_sum_u8x32(self.add_u8x32(a0, a1))
8302    }
8303    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
8304    #[inline(always)]
8305    fn reduce_product_u8x64(self, a: u8x64<Self>) -> u8 {
8306        let (a0, a1) = self.split_u8x64(a);
8307        self.reduce_product_u8x32(self.mul_u8x32(a0, a1))
8308    }
8309    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
8310    #[inline(always)]
8311    fn max_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
8312        let (a0, a1) = self.split_u8x64(a);
8313        let (b0, b1) = self.split_u8x64(b);
8314        self.combine_u8x32(self.max_u8x32(a0, b0), self.max_u8x32(a1, b1))
8315    }
8316    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
8317    #[inline(always)]
8318    fn min_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
8319        let (a0, a1) = self.split_u8x64(a);
8320        let (b0, b1) = self.split_u8x64(b);
8321        self.combine_u8x32(self.min_u8x32(a0, b0), self.min_u8x32(a1, b1))
8322    }
8323    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
8324    #[inline(always)]
8325    fn clamp_u8x64(self, a: u8x64<Self>, b: u8x64<Self>, c: u8x64<Self>) -> u8x64<Self> {
8326        let (a0, a1) = self.split_u8x64(a);
8327        let (b0, b1) = self.split_u8x64(b);
8328        let (c0, c1) = self.split_u8x64(c);
8329        self.combine_u8x32(self.clamp_u8x32(a0, b0, c0), self.clamp_u8x32(a1, b1, c1))
8330    }
8331    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
8332    #[inline(always)]
8333    fn simd_eq_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> mask8x64<Self> {
8334        let (a0, a1) = self.split_u8x64(a);
8335        let (b0, b1) = self.split_u8x64(b);
8336        self.combine_mask8x32(self.simd_eq_u8x32(a0, b0), self.simd_eq_u8x32(a1, b1))
8337    }
8338    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
8339    #[inline(always)]
8340    fn simd_ne_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> mask8x64<Self> {
8341        self.not_mask8x64(self.simd_eq_u8x64(a, b))
8342    }
8343    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
8344    #[inline(always)]
8345    fn simd_lt_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> mask8x64<Self> {
8346        let (a0, a1) = self.split_u8x64(a);
8347        let (b0, b1) = self.split_u8x64(b);
8348        self.combine_mask8x32(self.simd_lt_u8x32(a0, b0), self.simd_lt_u8x32(a1, b1))
8349    }
8350    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
8351    #[inline(always)]
8352    fn simd_le_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> mask8x64<Self> {
8353        let (a0, a1) = self.split_u8x64(a);
8354        let (b0, b1) = self.split_u8x64(b);
8355        self.combine_mask8x32(self.simd_le_u8x32(a0, b0), self.simd_le_u8x32(a1, b1))
8356    }
8357    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
8358    #[inline(always)]
8359    fn simd_ge_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> mask8x64<Self> {
8360        self.simd_le_u8x64(b, a)
8361    }
8362    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
8363    #[inline(always)]
8364    fn simd_gt_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> mask8x64<Self> {
8365        self.simd_lt_u8x64(b, a)
8366    }
8367    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
8368    #[inline(always)]
8369    fn zip_low_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
8370        let (a0, _) = self.split_u8x64(a);
8371        let (b0, _) = self.split_u8x64(b);
8372        self.combine_u8x32(self.zip_low_u8x32(a0, b0), self.zip_high_u8x32(a0, b0))
8373    }
8374    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
8375    #[inline(always)]
8376    fn zip_high_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
8377        let (_, a1) = self.split_u8x64(a);
8378        let (_, b1) = self.split_u8x64(b);
8379        self.combine_u8x32(self.zip_low_u8x32(a1, b1), self.zip_high_u8x32(a1, b1))
8380    }
8381    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
8382    #[inline(always)]
8383    fn unzip_low_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
8384        let (a0, a1) = self.split_u8x64(a);
8385        let (b0, b1) = self.split_u8x64(b);
8386        self.combine_u8x32(self.unzip_low_u8x32(a0, a1), self.unzip_low_u8x32(b0, b1))
8387    }
8388    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
8389    #[inline(always)]
8390    fn unzip_high_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u8x64<Self> {
8391        let (a0, a1) = self.split_u8x64(a);
8392        let (b0, b1) = self.split_u8x64(b);
8393        self.combine_u8x32(self.unzip_high_u8x32(a0, a1), self.unzip_high_u8x32(b0, b1))
8394    }
8395    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
8396    #[inline(always)]
8397    fn interleave_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> (u8x64<Self>, u8x64<Self>) {
8398        let (a0, a1) = self.split_u8x64(a);
8399        let (b0, b1) = self.split_u8x64(b);
8400        let lo_lo = self.zip_low_u8x32(a0, b0);
8401        let lo_hi = self.zip_high_u8x32(a0, b0);
8402        let hi_lo = self.zip_low_u8x32(a1, b1);
8403        let hi_hi = self.zip_high_u8x32(a1, b1);
8404        (
8405            self.combine_u8x32(lo_lo, lo_hi),
8406            self.combine_u8x32(hi_lo, hi_hi),
8407        )
8408    }
8409    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
8410    #[inline(always)]
8411    fn deinterleave_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> (u8x64<Self>, u8x64<Self>) {
8412        let (a0, a1) = self.split_u8x64(a);
8413        let (b0, b1) = self.split_u8x64(b);
8414        let lo_even = self.unzip_low_u8x32(a0, a1);
8415        let lo_odd = self.unzip_high_u8x32(a0, a1);
8416        let hi_even = self.unzip_low_u8x32(b0, b1);
8417        let hi_odd = self.unzip_high_u8x32(b0, b1);
8418        (
8419            self.combine_u8x32(lo_even, hi_even),
8420            self.combine_u8x32(lo_odd, hi_odd),
8421        )
8422    }
8423    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
8424    #[inline(always)]
8425    fn select_u8x64(self, a: mask8x64<Self>, b: u8x64<Self>, c: u8x64<Self>) -> u8x64<Self> {
8426        let (a0, a1) = self.split_mask8x64(a);
8427        let (b0, b1) = self.split_u8x64(b);
8428        let (c0, c1) = self.split_u8x64(c);
8429        self.combine_u8x32(self.select_u8x32(a0, b0, c0), self.select_u8x32(a1, b1, c1))
8430    }
8431    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
8432    fn split_u8x64(self, a: u8x64<Self>) -> (u8x32<Self>, u8x32<Self>);
8433    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
8434    #[inline(always)]
8435    fn widen_u8x64(self, a: u8x64<Self>) -> (u16x32<Self>, u16x32<Self>) {
8436        let (a0, a1) = self.split_u8x64(a);
8437        let (a00, a01) = self.widen_u8x32(a0);
8438        let (a10, a11) = self.widen_u8x32(a1);
8439        (self.combine_u16x16(a00, a01), self.combine_u16x16(a10, a11))
8440    }
8441    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
8442    #[inline(always)]
8443    fn widening_mul_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> (u16x32<Self>, u16x32<Self>) {
8444        let (a0, a1) = self.split_u8x64(a);
8445        let (b0, b1) = self.split_u8x64(b);
8446        let (low0, low1) = self.widening_mul_u8x32(a0, b0);
8447        let (high0, high1) = self.widening_mul_u8x32(a1, b1);
8448        (
8449            self.combine_u16x16(low0, low1),
8450            self.combine_u16x16(high0, high1),
8451        )
8452    }
8453    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
8454    #[inline(always)]
8455    fn widening_add_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> (u16x32<Self>, u16x32<Self>) {
8456        let (a0, a1) = self.split_u8x64(a);
8457        let (b0, b1) = self.split_u8x64(b);
8458        let (low0, low1) = self.widening_add_u8x32(a0, b0);
8459        let (high0, high1) = self.widening_add_u8x32(a1, b1);
8460        (
8461            self.combine_u16x16(low0, low1),
8462            self.combine_u16x16(high0, high1),
8463        )
8464    }
8465    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
8466    #[inline(always)]
8467    fn pairwise_widening_add_u8x64(self, a: u8x64<Self>) -> u16x32<Self> {
8468        let (a0, a1) = self.split_u8x64(a);
8469        self.combine_u16x16(
8470            self.pairwise_widening_add_u8x32(a0),
8471            self.pairwise_widening_add_u8x32(a1),
8472        )
8473    }
8474    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
8475    #[inline(always)]
8476    fn pairwise_dot_product_u8x64(self, a: u8x64<Self>, b: u8x64<Self>) -> u16x32<Self> {
8477        let (a0, a1) = self.split_u8x64(a);
8478        let (b0, b1) = self.split_u8x64(b);
8479        self.combine_u16x16(
8480            self.pairwise_dot_product_u8x32(a0, b0),
8481            self.pairwise_dot_product_u8x32(a1, b1),
8482        )
8483    }
8484    #[doc = "Create a SIMD mask with all lanes set from the given boolean value."]
8485    #[inline(always)]
8486    fn splat_mask8x64(self, val: bool) -> mask8x64<Self> {
8487        let half = self.splat_mask8x32(val);
8488        self.combine_mask8x32(half, half)
8489    }
8490    #[doc = "Create a SIMD mask from a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are ignored."]
8491    #[inline(always)]
8492    fn from_bitmask_mask8x64(self, bits: u64) -> mask8x64<Self> {
8493        let lo = self.from_bitmask_mask8x32(bits);
8494        let hi = self.from_bitmask_mask8x32(bits >> 32usize);
8495        self.combine_mask8x32(lo, hi)
8496    }
8497    #[doc = "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared."]
8498    #[inline(always)]
8499    fn to_bitmask_mask8x64(self, a: mask8x64<Self>) -> u64 {
8500        let (lo, hi) = self.split_mask8x64(a);
8501        let lo = self.to_bitmask_mask8x32(lo);
8502        let hi = self.to_bitmask_mask8x32(hi);
8503        lo | (hi << 32usize)
8504    }
8505    #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."]
8506    fn from_vector_mask8x64(self, vector: i8x64<Self>) -> mask8x64<Self>;
8507    #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."]
8508    fn to_vector_mask8x64(self, a: mask8x64<Self>) -> i8x64<Self>;
8509    #[doc = "Set one logical lane of a SIMD mask."]
8510    fn set_mask8x64(self, a: &mut mask8x64<Self>, index: usize, value: bool) -> ();
8511    #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
8512    fn rotate_elements_left_mask8x64<const OFFSET: usize>(
8513        self,
8514        a: mask8x64<Self>,
8515    ) -> mask8x64<Self>;
8516    #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
8517    fn rotate_elements_right_mask8x64<const OFFSET: usize>(
8518        self,
8519        a: mask8x64<Self>,
8520    ) -> mask8x64<Self>;
8521    #[doc = "Compute the logical AND of two masks."]
8522    #[inline(always)]
8523    fn and_mask8x64(self, a: mask8x64<Self>, b: mask8x64<Self>) -> mask8x64<Self> {
8524        let (a0, a1) = self.split_mask8x64(a);
8525        let (b0, b1) = self.split_mask8x64(b);
8526        self.combine_mask8x32(self.and_mask8x32(a0, b0), self.and_mask8x32(a1, b1))
8527    }
8528    #[doc = "Compute the logical OR of two masks."]
8529    #[inline(always)]
8530    fn or_mask8x64(self, a: mask8x64<Self>, b: mask8x64<Self>) -> mask8x64<Self> {
8531        let (a0, a1) = self.split_mask8x64(a);
8532        let (b0, b1) = self.split_mask8x64(b);
8533        self.combine_mask8x32(self.or_mask8x32(a0, b0), self.or_mask8x32(a1, b1))
8534    }
8535    #[doc = "Compute the logical XOR of two masks."]
8536    #[inline(always)]
8537    fn xor_mask8x64(self, a: mask8x64<Self>, b: mask8x64<Self>) -> mask8x64<Self> {
8538        let (a0, a1) = self.split_mask8x64(a);
8539        let (b0, b1) = self.split_mask8x64(b);
8540        self.combine_mask8x32(self.xor_mask8x32(a0, b0), self.xor_mask8x32(a1, b1))
8541    }
8542    #[doc = "Compute the logical NOT of the mask."]
8543    #[inline(always)]
8544    fn not_mask8x64(self, a: mask8x64<Self>) -> mask8x64<Self> {
8545        let (a0, a1) = self.split_mask8x64(a);
8546        self.combine_mask8x32(self.not_mask8x32(a0), self.not_mask8x32(a1))
8547    }
8548    #[doc = "Reverse the order of the mask's logical lanes."]
8549    #[inline(always)]
8550    fn reverse_mask8x64(self, a: mask8x64<Self>) -> mask8x64<Self> {
8551        let (a0, a1) = self.split_mask8x64(a);
8552        self.combine_mask8x32(self.reverse_mask8x32(a1), self.reverse_mask8x32(a0))
8553    }
8554    #[doc = "Select elements from `b` and `c` based on the mask operand `a`.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
8555    #[inline(always)]
8556    fn select_mask8x64(
8557        self,
8558        a: mask8x64<Self>,
8559        b: mask8x64<Self>,
8560        c: mask8x64<Self>,
8561    ) -> mask8x64<Self> {
8562        let (a0, a1) = self.split_mask8x64(a);
8563        let (b0, b1) = self.split_mask8x64(b);
8564        let (c0, c1) = self.split_mask8x64(c);
8565        self.combine_mask8x32(
8566            self.select_mask8x32(a0, b0, c0),
8567            self.select_mask8x32(a1, b1, c1),
8568        )
8569    }
8570    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
8571    #[inline(always)]
8572    fn simd_eq_mask8x64(self, a: mask8x64<Self>, b: mask8x64<Self>) -> mask8x64<Self> {
8573        let (a0, a1) = self.split_mask8x64(a);
8574        let (b0, b1) = self.split_mask8x64(b);
8575        self.combine_mask8x32(self.simd_eq_mask8x32(a0, b0), self.simd_eq_mask8x32(a1, b1))
8576    }
8577    #[doc = "Compare two masks element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
8578    #[inline(always)]
8579    fn simd_ne_mask8x64(self, a: mask8x64<Self>, b: mask8x64<Self>) -> mask8x64<Self> {
8580        self.not_mask8x64(self.simd_eq_mask8x64(a, b))
8581    }
8582    #[doc = "Returns true if any logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
8583    #[inline(always)]
8584    fn any_true_mask8x64(self, a: mask8x64<Self>) -> bool {
8585        let (a0, a1) = self.split_mask8x64(a);
8586        self.any_true_mask8x32(self.or_mask8x32(a0, a1))
8587    }
8588    #[doc = "Returns true if all logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
8589    #[inline(always)]
8590    fn all_true_mask8x64(self, a: mask8x64<Self>) -> bool {
8591        let (a0, a1) = self.split_mask8x64(a);
8592        self.all_true_mask8x32(self.and_mask8x32(a0, a1))
8593    }
8594    #[doc = "Returns true if any logical lanes in this mask are false.\n\nThis is logically equivalent to `!all_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
8595    #[inline(always)]
8596    fn any_false_mask8x64(self, a: mask8x64<Self>) -> bool {
8597        let (a0, a1) = self.split_mask8x64(a);
8598        self.any_false_mask8x32(self.and_mask8x32(a0, a1))
8599    }
8600    #[doc = "Returns true if all logical lanes in this mask are false.\n\nThis is logically equivalent to `!any_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
8601    #[inline(always)]
8602    fn all_false_mask8x64(self, a: mask8x64<Self>) -> bool {
8603        let (a0, a1) = self.split_mask8x64(a);
8604        self.all_false_mask8x32(self.or_mask8x32(a0, a1))
8605    }
8606    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
8607    fn split_mask8x64(self, a: mask8x64<Self>) -> (mask8x32<Self>, mask8x32<Self>);
8608    #[doc = "Widen each boolean lane into two masks of the same logical width, preserving its value.\n\nThe first result contains the lower lanes and the second contains the upper lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
8609    #[inline(always)]
8610    fn widen_mask8x64(self, a: mask8x64<Self>) -> (mask16x32<Self>, mask16x32<Self>) {
8611        let (a0, a1) = self.split_mask8x64(a);
8612        let (a00, a01) = self.widen_mask8x32(a0);
8613        let (a10, a11) = self.widen_mask8x32(a1);
8614        (
8615            self.combine_mask16x16(a00, a01),
8616            self.combine_mask16x16(a10, a11),
8617        )
8618    }
8619    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
8620    #[inline(always)]
8621    fn abs_i16x32(self, a: i16x32<Self>) -> i16x32<Self> {
8622        let (a0, a1) = self.split_i16x32(a);
8623        self.combine_i16x16(self.abs_i16x16(a0), self.abs_i16x16(a1))
8624    }
8625    #[doc = "Create a SIMD vector with all elements set to the given value."]
8626    #[inline(always)]
8627    fn splat_i16x32(self, val: i16) -> i16x32<Self> {
8628        let half = self.splat_i16x16(val);
8629        self.combine_i16x16(half, half)
8630    }
8631    #[doc = "Reverse the order of the vector's elements."]
8632    #[inline(always)]
8633    fn reverse_i16x32(self, a: i16x32<Self>) -> i16x32<Self> {
8634        let (a0, a1) = self.split_i16x32(a);
8635        self.combine_i16x16(self.reverse_i16x16(a1), self.reverse_i16x16(a0))
8636    }
8637    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
8638    fn slide_i16x32<const SHIFT: usize>(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self>;
8639    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
8640    #[inline(always)]
8641    fn slide_within_blocks_i16x32<const SHIFT: usize>(
8642        self,
8643        a: i16x32<Self>,
8644        b: i16x32<Self>,
8645    ) -> i16x32<Self> {
8646        let (a0, a1) = self.split_i16x32(a);
8647        let (b0, b1) = self.split_i16x32(b);
8648        self.combine_i16x16(
8649            self.slide_within_blocks_i16x16::<SHIFT>(a0, b0),
8650            self.slide_within_blocks_i16x16::<SHIFT>(a1, b1),
8651        )
8652    }
8653    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
8654    #[inline(always)]
8655    fn swizzle_dyn_within_blocks_i16x32(
8656        self,
8657        a: i16x32<Self>,
8658        indices: u8x64<Self>,
8659    ) -> i16x32<Self> {
8660        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x64(Bytes::to_bytes(a), indices))
8661    }
8662    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
8663    #[inline(always)]
8664    fn swizzle_dyn_i16x32(self, a: i16x32<Self>, indices: u8x64<Self>) -> i16x32<Self> {
8665        Bytes::from_bytes(self.swizzle_dyn_u8x64(Bytes::to_bytes(a), indices))
8666    }
8667    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
8668    #[inline(always)]
8669    fn swizzle_dyn_precise_i16x32(self, a: i16x32<Self>, indices: u8x64<Self>) -> i16x32<Self> {
8670        Bytes::from_bytes(self.swizzle_dyn_precise_u8x64(Bytes::to_bytes(a), indices))
8671    }
8672    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
8673    #[inline(always)]
8674    fn concat_swizzle_dyn_i16x32(
8675        self,
8676        a: i16x32<Self>,
8677        b: i16x32<Self>,
8678        indices: u8x64<Self>,
8679    ) -> i16x32<Self> {
8680        Bytes::from_bytes(self.concat_swizzle_dyn_u8x64(
8681            Bytes::to_bytes(a),
8682            Bytes::to_bytes(b),
8683            indices,
8684        ))
8685    }
8686    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
8687    #[inline(always)]
8688    fn concat_swizzle_dyn_precise_i16x32(
8689        self,
8690        a: i16x32<Self>,
8691        b: i16x32<Self>,
8692        indices: u8x64<Self>,
8693    ) -> i16x32<Self> {
8694        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x64(
8695            Bytes::to_bytes(a),
8696            Bytes::to_bytes(b),
8697            indices,
8698        ))
8699    }
8700    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
8701    fn compress_i16x32(self, values: i16x32<Self>, mask: mask16x32<Self>) -> i16x32<Self>;
8702    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
8703    fn compress_merge_i16x32(
8704        self,
8705        values: i16x32<Self>,
8706        mask: mask16x32<Self>,
8707        merge: i16x32<Self>,
8708    ) -> i16x32<Self>;
8709    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
8710    fn expand_i16x32(self, values: i16x32<Self>, mask: mask16x32<Self>) -> i16x32<Self>;
8711    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
8712    fn expand_merge_i16x32(
8713        self,
8714        values: i16x32<Self>,
8715        mask: mask16x32<Self>,
8716        merge: i16x32<Self>,
8717    ) -> i16x32<Self>;
8718    #[doc = "Return the number of ones in the binary representation of each element."]
8719    #[inline(always)]
8720    fn count_ones_i16x32(self, a: i16x32<Self>) -> i16x32<Self> {
8721        let (a0, a1) = self.split_i16x32(a);
8722        self.combine_i16x16(self.count_ones_i16x16(a0), self.count_ones_i16x16(a1))
8723    }
8724    #[doc = "Return the number of zeros in the binary representation of each element."]
8725    #[inline(always)]
8726    fn count_zeros_i16x32(self, a: i16x32<Self>) -> i16x32<Self> {
8727        let (a0, a1) = self.split_i16x32(a);
8728        self.combine_i16x16(self.count_zeros_i16x16(a0), self.count_zeros_i16x16(a1))
8729    }
8730    #[doc = "Add two vectors element-wise, wrapping on overflow."]
8731    #[inline(always)]
8732    fn add_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
8733        let (a0, a1) = self.split_i16x32(a);
8734        let (b0, b1) = self.split_i16x32(b);
8735        self.combine_i16x16(self.add_i16x16(a0, b0), self.add_i16x16(a1, b1))
8736    }
8737    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
8738    #[inline(always)]
8739    fn saturating_add_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
8740        let (a0, a1) = self.split_i16x32(a);
8741        let (b0, b1) = self.split_i16x32(b);
8742        self.combine_i16x16(
8743            self.saturating_add_i16x16(a0, b0),
8744            self.saturating_add_i16x16(a1, b1),
8745        )
8746    }
8747    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
8748    #[inline(always)]
8749    fn sub_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
8750        let (a0, a1) = self.split_i16x32(a);
8751        let (b0, b1) = self.split_i16x32(b);
8752        self.combine_i16x16(self.sub_i16x16(a0, b0), self.sub_i16x16(a1, b1))
8753    }
8754    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
8755    #[inline(always)]
8756    fn saturating_sub_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
8757        let (a0, a1) = self.split_i16x32(a);
8758        let (b0, b1) = self.split_i16x32(b);
8759        self.combine_i16x16(
8760            self.saturating_sub_i16x16(a0, b0),
8761            self.saturating_sub_i16x16(a1, b1),
8762        )
8763    }
8764    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
8765    #[inline(always)]
8766    fn mul_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
8767        let (a0, a1) = self.split_i16x32(a);
8768        let (b0, b1) = self.split_i16x32(b);
8769        self.combine_i16x16(self.mul_i16x16(a0, b0), self.mul_i16x16(a1, b1))
8770    }
8771    #[doc = "Compute the bitwise AND of two vectors."]
8772    #[inline(always)]
8773    fn and_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
8774        let (a0, a1) = self.split_i16x32(a);
8775        let (b0, b1) = self.split_i16x32(b);
8776        self.combine_i16x16(self.and_i16x16(a0, b0), self.and_i16x16(a1, b1))
8777    }
8778    #[doc = "Compute the bitwise OR of two vectors."]
8779    #[inline(always)]
8780    fn or_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
8781        let (a0, a1) = self.split_i16x32(a);
8782        let (b0, b1) = self.split_i16x32(b);
8783        self.combine_i16x16(self.or_i16x16(a0, b0), self.or_i16x16(a1, b1))
8784    }
8785    #[doc = "Compute the bitwise XOR of two vectors."]
8786    #[inline(always)]
8787    fn xor_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
8788        let (a0, a1) = self.split_i16x32(a);
8789        let (b0, b1) = self.split_i16x32(b);
8790        self.combine_i16x16(self.xor_i16x16(a0, b0), self.xor_i16x16(a1, b1))
8791    }
8792    #[doc = "Compute the bitwise NOT of the vector."]
8793    #[inline(always)]
8794    fn not_i16x32(self, a: i16x32<Self>) -> i16x32<Self> {
8795        let (a0, a1) = self.split_i16x32(a);
8796        self.combine_i16x16(self.not_i16x16(a0), self.not_i16x16(a1))
8797    }
8798    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
8799    #[inline(always)]
8800    fn shl_i16x32(self, a: i16x32<Self>, shift: u32) -> i16x32<Self> {
8801        let (a0, a1) = self.split_i16x32(a);
8802        self.combine_i16x16(self.shl_i16x16(a0, shift), self.shl_i16x16(a1, shift))
8803    }
8804    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
8805    #[inline(always)]
8806    fn shlv_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
8807        let (a0, a1) = self.split_i16x32(a);
8808        let (b0, b1) = self.split_i16x32(b);
8809        self.combine_i16x16(self.shlv_i16x16(a0, b0), self.shlv_i16x16(a1, b1))
8810    }
8811    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
8812    #[inline(always)]
8813    fn shr_i16x32(self, a: i16x32<Self>, shift: u32) -> i16x32<Self> {
8814        let (a0, a1) = self.split_i16x32(a);
8815        self.combine_i16x16(self.shr_i16x16(a0, shift), self.shr_i16x16(a1, shift))
8816    }
8817    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
8818    #[inline(always)]
8819    fn shrv_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
8820        let (a0, a1) = self.split_i16x32(a);
8821        let (b0, b1) = self.split_i16x32(b);
8822        self.combine_i16x16(self.shrv_i16x16(a0, b0), self.shrv_i16x16(a1, b1))
8823    }
8824    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
8825    #[inline(always)]
8826    fn reduce_max_i16x32(self, a: i16x32<Self>) -> i16 {
8827        let (a0, a1) = self.split_i16x32(a);
8828        self.reduce_max_i16x16(self.max_i16x16(a0, a1))
8829    }
8830    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
8831    #[inline(always)]
8832    fn reduce_min_i16x32(self, a: i16x32<Self>) -> i16 {
8833        let (a0, a1) = self.split_i16x32(a);
8834        self.reduce_min_i16x16(self.min_i16x16(a0, a1))
8835    }
8836    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
8837    #[inline(always)]
8838    fn reduce_sum_i16x32(self, a: i16x32<Self>) -> i16 {
8839        let (a0, a1) = self.split_i16x32(a);
8840        self.reduce_sum_i16x16(self.add_i16x16(a0, a1))
8841    }
8842    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
8843    #[inline(always)]
8844    fn reduce_product_i16x32(self, a: i16x32<Self>) -> i16 {
8845        let (a0, a1) = self.split_i16x32(a);
8846        self.reduce_product_i16x16(self.mul_i16x16(a0, a1))
8847    }
8848    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
8849    #[inline(always)]
8850    fn max_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
8851        let (a0, a1) = self.split_i16x32(a);
8852        let (b0, b1) = self.split_i16x32(b);
8853        self.combine_i16x16(self.max_i16x16(a0, b0), self.max_i16x16(a1, b1))
8854    }
8855    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
8856    #[inline(always)]
8857    fn min_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
8858        let (a0, a1) = self.split_i16x32(a);
8859        let (b0, b1) = self.split_i16x32(b);
8860        self.combine_i16x16(self.min_i16x16(a0, b0), self.min_i16x16(a1, b1))
8861    }
8862    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
8863    #[inline(always)]
8864    fn clamp_i16x32(self, a: i16x32<Self>, b: i16x32<Self>, c: i16x32<Self>) -> i16x32<Self> {
8865        let (a0, a1) = self.split_i16x32(a);
8866        let (b0, b1) = self.split_i16x32(b);
8867        let (c0, c1) = self.split_i16x32(c);
8868        self.combine_i16x16(self.clamp_i16x16(a0, b0, c0), self.clamp_i16x16(a1, b1, c1))
8869    }
8870    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
8871    #[inline(always)]
8872    fn simd_eq_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> mask16x32<Self> {
8873        let (a0, a1) = self.split_i16x32(a);
8874        let (b0, b1) = self.split_i16x32(b);
8875        self.combine_mask16x16(self.simd_eq_i16x16(a0, b0), self.simd_eq_i16x16(a1, b1))
8876    }
8877    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
8878    #[inline(always)]
8879    fn simd_ne_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> mask16x32<Self> {
8880        self.not_mask16x32(self.simd_eq_i16x32(a, b))
8881    }
8882    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
8883    #[inline(always)]
8884    fn simd_lt_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> mask16x32<Self> {
8885        let (a0, a1) = self.split_i16x32(a);
8886        let (b0, b1) = self.split_i16x32(b);
8887        self.combine_mask16x16(self.simd_lt_i16x16(a0, b0), self.simd_lt_i16x16(a1, b1))
8888    }
8889    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
8890    #[inline(always)]
8891    fn simd_le_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> mask16x32<Self> {
8892        let (a0, a1) = self.split_i16x32(a);
8893        let (b0, b1) = self.split_i16x32(b);
8894        self.combine_mask16x16(self.simd_le_i16x16(a0, b0), self.simd_le_i16x16(a1, b1))
8895    }
8896    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
8897    #[inline(always)]
8898    fn simd_ge_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> mask16x32<Self> {
8899        self.simd_le_i16x32(b, a)
8900    }
8901    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
8902    #[inline(always)]
8903    fn simd_gt_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> mask16x32<Self> {
8904        self.simd_lt_i16x32(b, a)
8905    }
8906    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
8907    #[inline(always)]
8908    fn zip_low_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
8909        let (a0, _) = self.split_i16x32(a);
8910        let (b0, _) = self.split_i16x32(b);
8911        self.combine_i16x16(self.zip_low_i16x16(a0, b0), self.zip_high_i16x16(a0, b0))
8912    }
8913    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
8914    #[inline(always)]
8915    fn zip_high_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
8916        let (_, a1) = self.split_i16x32(a);
8917        let (_, b1) = self.split_i16x32(b);
8918        self.combine_i16x16(self.zip_low_i16x16(a1, b1), self.zip_high_i16x16(a1, b1))
8919    }
8920    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
8921    #[inline(always)]
8922    fn unzip_low_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
8923        let (a0, a1) = self.split_i16x32(a);
8924        let (b0, b1) = self.split_i16x32(b);
8925        self.combine_i16x16(self.unzip_low_i16x16(a0, a1), self.unzip_low_i16x16(b0, b1))
8926    }
8927    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
8928    #[inline(always)]
8929    fn unzip_high_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i16x32<Self> {
8930        let (a0, a1) = self.split_i16x32(a);
8931        let (b0, b1) = self.split_i16x32(b);
8932        self.combine_i16x16(
8933            self.unzip_high_i16x16(a0, a1),
8934            self.unzip_high_i16x16(b0, b1),
8935        )
8936    }
8937    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
8938    #[inline(always)]
8939    fn interleave_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> (i16x32<Self>, i16x32<Self>) {
8940        let (a0, a1) = self.split_i16x32(a);
8941        let (b0, b1) = self.split_i16x32(b);
8942        let lo_lo = self.zip_low_i16x16(a0, b0);
8943        let lo_hi = self.zip_high_i16x16(a0, b0);
8944        let hi_lo = self.zip_low_i16x16(a1, b1);
8945        let hi_hi = self.zip_high_i16x16(a1, b1);
8946        (
8947            self.combine_i16x16(lo_lo, lo_hi),
8948            self.combine_i16x16(hi_lo, hi_hi),
8949        )
8950    }
8951    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
8952    #[inline(always)]
8953    fn deinterleave_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> (i16x32<Self>, i16x32<Self>) {
8954        let (a0, a1) = self.split_i16x32(a);
8955        let (b0, b1) = self.split_i16x32(b);
8956        let lo_even = self.unzip_low_i16x16(a0, a1);
8957        let lo_odd = self.unzip_high_i16x16(a0, a1);
8958        let hi_even = self.unzip_low_i16x16(b0, b1);
8959        let hi_odd = self.unzip_high_i16x16(b0, b1);
8960        (
8961            self.combine_i16x16(lo_even, hi_even),
8962            self.combine_i16x16(lo_odd, hi_odd),
8963        )
8964    }
8965    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
8966    #[inline(always)]
8967    fn select_i16x32(self, a: mask16x32<Self>, b: i16x32<Self>, c: i16x32<Self>) -> i16x32<Self> {
8968        let (a0, a1) = self.split_mask16x32(a);
8969        let (b0, b1) = self.split_i16x32(b);
8970        let (c0, c1) = self.split_i16x32(c);
8971        self.combine_i16x16(
8972            self.select_i16x16(a0, b0, c0),
8973            self.select_i16x16(a1, b1, c1),
8974        )
8975    }
8976    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
8977    fn split_i16x32(self, a: i16x32<Self>) -> (i16x16<Self>, i16x16<Self>);
8978    #[doc = "Negate each element of the vector, wrapping on overflow."]
8979    #[inline(always)]
8980    fn neg_i16x32(self, a: i16x32<Self>) -> i16x32<Self> {
8981        let (a0, a1) = self.split_i16x32(a);
8982        self.combine_i16x16(self.neg_i16x16(a0), self.neg_i16x16(a1))
8983    }
8984    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
8985    #[inline(always)]
8986    fn widen_i16x32(self, a: i16x32<Self>) -> (i32x16<Self>, i32x16<Self>) {
8987        let (a0, a1) = self.split_i16x32(a);
8988        let (a00, a01) = self.widen_i16x16(a0);
8989        let (a10, a11) = self.widen_i16x16(a1);
8990        (self.combine_i32x8(a00, a01), self.combine_i32x8(a10, a11))
8991    }
8992    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
8993    #[inline(always)]
8994    fn widening_mul_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> (i32x16<Self>, i32x16<Self>) {
8995        let (a0, a1) = self.split_i16x32(a);
8996        let (b0, b1) = self.split_i16x32(b);
8997        let (low0, low1) = self.widening_mul_i16x16(a0, b0);
8998        let (high0, high1) = self.widening_mul_i16x16(a1, b1);
8999        (
9000            self.combine_i32x8(low0, low1),
9001            self.combine_i32x8(high0, high1),
9002        )
9003    }
9004    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
9005    #[inline(always)]
9006    fn widening_add_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> (i32x16<Self>, i32x16<Self>) {
9007        let (a0, a1) = self.split_i16x32(a);
9008        let (b0, b1) = self.split_i16x32(b);
9009        let (low0, low1) = self.widening_add_i16x16(a0, b0);
9010        let (high0, high1) = self.widening_add_i16x16(a1, b1);
9011        (
9012            self.combine_i32x8(low0, low1),
9013            self.combine_i32x8(high0, high1),
9014        )
9015    }
9016    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
9017    #[inline(always)]
9018    fn pairwise_widening_add_i16x32(self, a: i16x32<Self>) -> i32x16<Self> {
9019        let (a0, a1) = self.split_i16x32(a);
9020        self.combine_i32x8(
9021            self.pairwise_widening_add_i16x16(a0),
9022            self.pairwise_widening_add_i16x16(a1),
9023        )
9024    }
9025    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
9026    #[inline(always)]
9027    fn pairwise_dot_product_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i32x16<Self> {
9028        let (a0, a1) = self.split_i16x32(a);
9029        let (b0, b1) = self.split_i16x32(b);
9030        self.combine_i32x8(
9031            self.pairwise_dot_product_i16x16(a0, b0),
9032            self.pairwise_dot_product_i16x16(a1, b1),
9033        )
9034    }
9035    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
9036    #[inline(always)]
9037    fn narrow_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i8x64<Self> {
9038        let (a0, a1) = self.split_i16x32(a);
9039        let (b0, b1) = self.split_i16x32(b);
9040        self.combine_i8x32(self.narrow_i16x16(a0, a1), self.narrow_i16x16(b0, b1))
9041    }
9042    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
9043    #[inline(always)]
9044    fn saturating_narrow_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i8x64<Self> {
9045        let (a0, a1) = self.split_i16x32(a);
9046        let (b0, b1) = self.split_i16x32(b);
9047        self.combine_i8x32(
9048            self.saturating_narrow_i16x16(a0, a1),
9049            self.saturating_narrow_i16x16(b0, b1),
9050        )
9051    }
9052    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
9053    #[inline(always)]
9054    fn relaxed_narrow_i16x32(self, a: i16x32<Self>, b: i16x32<Self>) -> i8x64<Self> {
9055        let (a0, a1) = self.split_i16x32(a);
9056        let (b0, b1) = self.split_i16x32(b);
9057        self.combine_i8x32(
9058            self.relaxed_narrow_i16x16(a0, a1),
9059            self.relaxed_narrow_i16x16(b0, b1),
9060        )
9061    }
9062    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
9063    #[inline(always)]
9064    fn abs_u16x32(self, a: u16x32<Self>) -> u16x32<Self> {
9065        a
9066    }
9067    #[doc = "Create a SIMD vector with all elements set to the given value."]
9068    #[inline(always)]
9069    fn splat_u16x32(self, val: u16) -> u16x32<Self> {
9070        let half = self.splat_u16x16(val);
9071        self.combine_u16x16(half, half)
9072    }
9073    #[doc = "Reverse the order of the vector's elements."]
9074    #[inline(always)]
9075    fn reverse_u16x32(self, a: u16x32<Self>) -> u16x32<Self> {
9076        let (a0, a1) = self.split_u16x32(a);
9077        self.combine_u16x16(self.reverse_u16x16(a1), self.reverse_u16x16(a0))
9078    }
9079    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
9080    fn slide_u16x32<const SHIFT: usize>(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self>;
9081    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
9082    #[inline(always)]
9083    fn slide_within_blocks_u16x32<const SHIFT: usize>(
9084        self,
9085        a: u16x32<Self>,
9086        b: u16x32<Self>,
9087    ) -> u16x32<Self> {
9088        let (a0, a1) = self.split_u16x32(a);
9089        let (b0, b1) = self.split_u16x32(b);
9090        self.combine_u16x16(
9091            self.slide_within_blocks_u16x16::<SHIFT>(a0, b0),
9092            self.slide_within_blocks_u16x16::<SHIFT>(a1, b1),
9093        )
9094    }
9095    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
9096    #[inline(always)]
9097    fn swizzle_dyn_within_blocks_u16x32(
9098        self,
9099        a: u16x32<Self>,
9100        indices: u8x64<Self>,
9101    ) -> u16x32<Self> {
9102        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x64(Bytes::to_bytes(a), indices))
9103    }
9104    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
9105    #[inline(always)]
9106    fn swizzle_dyn_u16x32(self, a: u16x32<Self>, indices: u8x64<Self>) -> u16x32<Self> {
9107        Bytes::from_bytes(self.swizzle_dyn_u8x64(Bytes::to_bytes(a), indices))
9108    }
9109    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
9110    #[inline(always)]
9111    fn swizzle_dyn_precise_u16x32(self, a: u16x32<Self>, indices: u8x64<Self>) -> u16x32<Self> {
9112        Bytes::from_bytes(self.swizzle_dyn_precise_u8x64(Bytes::to_bytes(a), indices))
9113    }
9114    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
9115    #[inline(always)]
9116    fn concat_swizzle_dyn_u16x32(
9117        self,
9118        a: u16x32<Self>,
9119        b: u16x32<Self>,
9120        indices: u8x64<Self>,
9121    ) -> u16x32<Self> {
9122        Bytes::from_bytes(self.concat_swizzle_dyn_u8x64(
9123            Bytes::to_bytes(a),
9124            Bytes::to_bytes(b),
9125            indices,
9126        ))
9127    }
9128    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
9129    #[inline(always)]
9130    fn concat_swizzle_dyn_precise_u16x32(
9131        self,
9132        a: u16x32<Self>,
9133        b: u16x32<Self>,
9134        indices: u8x64<Self>,
9135    ) -> u16x32<Self> {
9136        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x64(
9137            Bytes::to_bytes(a),
9138            Bytes::to_bytes(b),
9139            indices,
9140        ))
9141    }
9142    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
9143    fn compress_u16x32(self, values: u16x32<Self>, mask: mask16x32<Self>) -> u16x32<Self>;
9144    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
9145    fn compress_merge_u16x32(
9146        self,
9147        values: u16x32<Self>,
9148        mask: mask16x32<Self>,
9149        merge: u16x32<Self>,
9150    ) -> u16x32<Self>;
9151    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
9152    fn expand_u16x32(self, values: u16x32<Self>, mask: mask16x32<Self>) -> u16x32<Self>;
9153    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
9154    fn expand_merge_u16x32(
9155        self,
9156        values: u16x32<Self>,
9157        mask: mask16x32<Self>,
9158        merge: u16x32<Self>,
9159    ) -> u16x32<Self>;
9160    #[doc = "Return the number of ones in the binary representation of each element."]
9161    #[inline(always)]
9162    fn count_ones_u16x32(self, a: u16x32<Self>) -> u16x32<Self> {
9163        let (a0, a1) = self.split_u16x32(a);
9164        self.combine_u16x16(self.count_ones_u16x16(a0), self.count_ones_u16x16(a1))
9165    }
9166    #[doc = "Return the number of zeros in the binary representation of each element."]
9167    #[inline(always)]
9168    fn count_zeros_u16x32(self, a: u16x32<Self>) -> u16x32<Self> {
9169        let (a0, a1) = self.split_u16x32(a);
9170        self.combine_u16x16(self.count_zeros_u16x16(a0), self.count_zeros_u16x16(a1))
9171    }
9172    #[doc = "Add two vectors element-wise, wrapping on overflow."]
9173    #[inline(always)]
9174    fn add_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9175        let (a0, a1) = self.split_u16x32(a);
9176        let (b0, b1) = self.split_u16x32(b);
9177        self.combine_u16x16(self.add_u16x16(a0, b0), self.add_u16x16(a1, b1))
9178    }
9179    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
9180    #[inline(always)]
9181    fn saturating_add_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9182        let (a0, a1) = self.split_u16x32(a);
9183        let (b0, b1) = self.split_u16x32(b);
9184        self.combine_u16x16(
9185            self.saturating_add_u16x16(a0, b0),
9186            self.saturating_add_u16x16(a1, b1),
9187        )
9188    }
9189    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
9190    #[inline(always)]
9191    fn sub_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9192        let (a0, a1) = self.split_u16x32(a);
9193        let (b0, b1) = self.split_u16x32(b);
9194        self.combine_u16x16(self.sub_u16x16(a0, b0), self.sub_u16x16(a1, b1))
9195    }
9196    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
9197    #[inline(always)]
9198    fn saturating_sub_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9199        let (a0, a1) = self.split_u16x32(a);
9200        let (b0, b1) = self.split_u16x32(b);
9201        self.combine_u16x16(
9202            self.saturating_sub_u16x16(a0, b0),
9203            self.saturating_sub_u16x16(a1, b1),
9204        )
9205    }
9206    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
9207    #[inline(always)]
9208    fn mul_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9209        let (a0, a1) = self.split_u16x32(a);
9210        let (b0, b1) = self.split_u16x32(b);
9211        self.combine_u16x16(self.mul_u16x16(a0, b0), self.mul_u16x16(a1, b1))
9212    }
9213    #[doc = "Compute the bitwise AND of two vectors."]
9214    #[inline(always)]
9215    fn and_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9216        let (a0, a1) = self.split_u16x32(a);
9217        let (b0, b1) = self.split_u16x32(b);
9218        self.combine_u16x16(self.and_u16x16(a0, b0), self.and_u16x16(a1, b1))
9219    }
9220    #[doc = "Compute the bitwise OR of two vectors."]
9221    #[inline(always)]
9222    fn or_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9223        let (a0, a1) = self.split_u16x32(a);
9224        let (b0, b1) = self.split_u16x32(b);
9225        self.combine_u16x16(self.or_u16x16(a0, b0), self.or_u16x16(a1, b1))
9226    }
9227    #[doc = "Compute the bitwise XOR of two vectors."]
9228    #[inline(always)]
9229    fn xor_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9230        let (a0, a1) = self.split_u16x32(a);
9231        let (b0, b1) = self.split_u16x32(b);
9232        self.combine_u16x16(self.xor_u16x16(a0, b0), self.xor_u16x16(a1, b1))
9233    }
9234    #[doc = "Compute the bitwise NOT of the vector."]
9235    #[inline(always)]
9236    fn not_u16x32(self, a: u16x32<Self>) -> u16x32<Self> {
9237        let (a0, a1) = self.split_u16x32(a);
9238        self.combine_u16x16(self.not_u16x16(a0), self.not_u16x16(a1))
9239    }
9240    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
9241    #[inline(always)]
9242    fn shl_u16x32(self, a: u16x32<Self>, shift: u32) -> u16x32<Self> {
9243        let (a0, a1) = self.split_u16x32(a);
9244        self.combine_u16x16(self.shl_u16x16(a0, shift), self.shl_u16x16(a1, shift))
9245    }
9246    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
9247    #[inline(always)]
9248    fn shlv_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9249        let (a0, a1) = self.split_u16x32(a);
9250        let (b0, b1) = self.split_u16x32(b);
9251        self.combine_u16x16(self.shlv_u16x16(a0, b0), self.shlv_u16x16(a1, b1))
9252    }
9253    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
9254    #[inline(always)]
9255    fn shr_u16x32(self, a: u16x32<Self>, shift: u32) -> u16x32<Self> {
9256        let (a0, a1) = self.split_u16x32(a);
9257        self.combine_u16x16(self.shr_u16x16(a0, shift), self.shr_u16x16(a1, shift))
9258    }
9259    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
9260    #[inline(always)]
9261    fn shrv_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9262        let (a0, a1) = self.split_u16x32(a);
9263        let (b0, b1) = self.split_u16x32(b);
9264        self.combine_u16x16(self.shrv_u16x16(a0, b0), self.shrv_u16x16(a1, b1))
9265    }
9266    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
9267    #[inline(always)]
9268    fn reduce_max_u16x32(self, a: u16x32<Self>) -> u16 {
9269        let (a0, a1) = self.split_u16x32(a);
9270        self.reduce_max_u16x16(self.max_u16x16(a0, a1))
9271    }
9272    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
9273    #[inline(always)]
9274    fn reduce_min_u16x32(self, a: u16x32<Self>) -> u16 {
9275        let (a0, a1) = self.split_u16x32(a);
9276        self.reduce_min_u16x16(self.min_u16x16(a0, a1))
9277    }
9278    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
9279    #[inline(always)]
9280    fn reduce_sum_u16x32(self, a: u16x32<Self>) -> u16 {
9281        let (a0, a1) = self.split_u16x32(a);
9282        self.reduce_sum_u16x16(self.add_u16x16(a0, a1))
9283    }
9284    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
9285    #[inline(always)]
9286    fn reduce_product_u16x32(self, a: u16x32<Self>) -> u16 {
9287        let (a0, a1) = self.split_u16x32(a);
9288        self.reduce_product_u16x16(self.mul_u16x16(a0, a1))
9289    }
9290    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
9291    #[inline(always)]
9292    fn max_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9293        let (a0, a1) = self.split_u16x32(a);
9294        let (b0, b1) = self.split_u16x32(b);
9295        self.combine_u16x16(self.max_u16x16(a0, b0), self.max_u16x16(a1, b1))
9296    }
9297    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
9298    #[inline(always)]
9299    fn min_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9300        let (a0, a1) = self.split_u16x32(a);
9301        let (b0, b1) = self.split_u16x32(b);
9302        self.combine_u16x16(self.min_u16x16(a0, b0), self.min_u16x16(a1, b1))
9303    }
9304    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
9305    #[inline(always)]
9306    fn clamp_u16x32(self, a: u16x32<Self>, b: u16x32<Self>, c: u16x32<Self>) -> u16x32<Self> {
9307        let (a0, a1) = self.split_u16x32(a);
9308        let (b0, b1) = self.split_u16x32(b);
9309        let (c0, c1) = self.split_u16x32(c);
9310        self.combine_u16x16(self.clamp_u16x16(a0, b0, c0), self.clamp_u16x16(a1, b1, c1))
9311    }
9312    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
9313    #[inline(always)]
9314    fn simd_eq_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> mask16x32<Self> {
9315        let (a0, a1) = self.split_u16x32(a);
9316        let (b0, b1) = self.split_u16x32(b);
9317        self.combine_mask16x16(self.simd_eq_u16x16(a0, b0), self.simd_eq_u16x16(a1, b1))
9318    }
9319    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
9320    #[inline(always)]
9321    fn simd_ne_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> mask16x32<Self> {
9322        self.not_mask16x32(self.simd_eq_u16x32(a, b))
9323    }
9324    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
9325    #[inline(always)]
9326    fn simd_lt_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> mask16x32<Self> {
9327        let (a0, a1) = self.split_u16x32(a);
9328        let (b0, b1) = self.split_u16x32(b);
9329        self.combine_mask16x16(self.simd_lt_u16x16(a0, b0), self.simd_lt_u16x16(a1, b1))
9330    }
9331    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
9332    #[inline(always)]
9333    fn simd_le_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> mask16x32<Self> {
9334        let (a0, a1) = self.split_u16x32(a);
9335        let (b0, b1) = self.split_u16x32(b);
9336        self.combine_mask16x16(self.simd_le_u16x16(a0, b0), self.simd_le_u16x16(a1, b1))
9337    }
9338    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
9339    #[inline(always)]
9340    fn simd_ge_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> mask16x32<Self> {
9341        self.simd_le_u16x32(b, a)
9342    }
9343    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
9344    #[inline(always)]
9345    fn simd_gt_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> mask16x32<Self> {
9346        self.simd_lt_u16x32(b, a)
9347    }
9348    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
9349    #[inline(always)]
9350    fn zip_low_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9351        let (a0, _) = self.split_u16x32(a);
9352        let (b0, _) = self.split_u16x32(b);
9353        self.combine_u16x16(self.zip_low_u16x16(a0, b0), self.zip_high_u16x16(a0, b0))
9354    }
9355    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
9356    #[inline(always)]
9357    fn zip_high_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9358        let (_, a1) = self.split_u16x32(a);
9359        let (_, b1) = self.split_u16x32(b);
9360        self.combine_u16x16(self.zip_low_u16x16(a1, b1), self.zip_high_u16x16(a1, b1))
9361    }
9362    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
9363    #[inline(always)]
9364    fn unzip_low_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9365        let (a0, a1) = self.split_u16x32(a);
9366        let (b0, b1) = self.split_u16x32(b);
9367        self.combine_u16x16(self.unzip_low_u16x16(a0, a1), self.unzip_low_u16x16(b0, b1))
9368    }
9369    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
9370    #[inline(always)]
9371    fn unzip_high_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u16x32<Self> {
9372        let (a0, a1) = self.split_u16x32(a);
9373        let (b0, b1) = self.split_u16x32(b);
9374        self.combine_u16x16(
9375            self.unzip_high_u16x16(a0, a1),
9376            self.unzip_high_u16x16(b0, b1),
9377        )
9378    }
9379    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
9380    #[inline(always)]
9381    fn interleave_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> (u16x32<Self>, u16x32<Self>) {
9382        let (a0, a1) = self.split_u16x32(a);
9383        let (b0, b1) = self.split_u16x32(b);
9384        let lo_lo = self.zip_low_u16x16(a0, b0);
9385        let lo_hi = self.zip_high_u16x16(a0, b0);
9386        let hi_lo = self.zip_low_u16x16(a1, b1);
9387        let hi_hi = self.zip_high_u16x16(a1, b1);
9388        (
9389            self.combine_u16x16(lo_lo, lo_hi),
9390            self.combine_u16x16(hi_lo, hi_hi),
9391        )
9392    }
9393    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
9394    #[inline(always)]
9395    fn deinterleave_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> (u16x32<Self>, u16x32<Self>) {
9396        let (a0, a1) = self.split_u16x32(a);
9397        let (b0, b1) = self.split_u16x32(b);
9398        let lo_even = self.unzip_low_u16x16(a0, a1);
9399        let lo_odd = self.unzip_high_u16x16(a0, a1);
9400        let hi_even = self.unzip_low_u16x16(b0, b1);
9401        let hi_odd = self.unzip_high_u16x16(b0, b1);
9402        (
9403            self.combine_u16x16(lo_even, hi_even),
9404            self.combine_u16x16(lo_odd, hi_odd),
9405        )
9406    }
9407    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
9408    #[inline(always)]
9409    fn select_u16x32(self, a: mask16x32<Self>, b: u16x32<Self>, c: u16x32<Self>) -> u16x32<Self> {
9410        let (a0, a1) = self.split_mask16x32(a);
9411        let (b0, b1) = self.split_u16x32(b);
9412        let (c0, c1) = self.split_u16x32(c);
9413        self.combine_u16x16(
9414            self.select_u16x16(a0, b0, c0),
9415            self.select_u16x16(a1, b1, c1),
9416        )
9417    }
9418    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
9419    fn split_u16x32(self, a: u16x32<Self>) -> (u16x16<Self>, u16x16<Self>);
9420    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
9421    #[inline(always)]
9422    fn widen_u16x32(self, a: u16x32<Self>) -> (u32x16<Self>, u32x16<Self>) {
9423        let (a0, a1) = self.split_u16x32(a);
9424        let (a00, a01) = self.widen_u16x16(a0);
9425        let (a10, a11) = self.widen_u16x16(a1);
9426        (self.combine_u32x8(a00, a01), self.combine_u32x8(a10, a11))
9427    }
9428    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
9429    #[inline(always)]
9430    fn widening_mul_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> (u32x16<Self>, u32x16<Self>) {
9431        let (a0, a1) = self.split_u16x32(a);
9432        let (b0, b1) = self.split_u16x32(b);
9433        let (low0, low1) = self.widening_mul_u16x16(a0, b0);
9434        let (high0, high1) = self.widening_mul_u16x16(a1, b1);
9435        (
9436            self.combine_u32x8(low0, low1),
9437            self.combine_u32x8(high0, high1),
9438        )
9439    }
9440    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
9441    #[inline(always)]
9442    fn widening_add_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> (u32x16<Self>, u32x16<Self>) {
9443        let (a0, a1) = self.split_u16x32(a);
9444        let (b0, b1) = self.split_u16x32(b);
9445        let (low0, low1) = self.widening_add_u16x16(a0, b0);
9446        let (high0, high1) = self.widening_add_u16x16(a1, b1);
9447        (
9448            self.combine_u32x8(low0, low1),
9449            self.combine_u32x8(high0, high1),
9450        )
9451    }
9452    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
9453    #[inline(always)]
9454    fn pairwise_widening_add_u16x32(self, a: u16x32<Self>) -> u32x16<Self> {
9455        let (a0, a1) = self.split_u16x32(a);
9456        self.combine_u32x8(
9457            self.pairwise_widening_add_u16x16(a0),
9458            self.pairwise_widening_add_u16x16(a1),
9459        )
9460    }
9461    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
9462    #[inline(always)]
9463    fn pairwise_dot_product_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u32x16<Self> {
9464        let (a0, a1) = self.split_u16x32(a);
9465        let (b0, b1) = self.split_u16x32(b);
9466        self.combine_u32x8(
9467            self.pairwise_dot_product_u16x16(a0, b0),
9468            self.pairwise_dot_product_u16x16(a1, b1),
9469        )
9470    }
9471    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
9472    #[inline(always)]
9473    fn narrow_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u8x64<Self> {
9474        let (a0, a1) = self.split_u16x32(a);
9475        let (b0, b1) = self.split_u16x32(b);
9476        self.combine_u8x32(self.narrow_u16x16(a0, a1), self.narrow_u16x16(b0, b1))
9477    }
9478    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
9479    #[inline(always)]
9480    fn saturating_narrow_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u8x64<Self> {
9481        let (a0, a1) = self.split_u16x32(a);
9482        let (b0, b1) = self.split_u16x32(b);
9483        self.combine_u8x32(
9484            self.saturating_narrow_u16x16(a0, a1),
9485            self.saturating_narrow_u16x16(b0, b1),
9486        )
9487    }
9488    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
9489    #[inline(always)]
9490    fn relaxed_narrow_u16x32(self, a: u16x32<Self>, b: u16x32<Self>) -> u8x64<Self> {
9491        let (a0, a1) = self.split_u16x32(a);
9492        let (b0, b1) = self.split_u16x32(b);
9493        self.combine_u8x32(
9494            self.relaxed_narrow_u16x16(a0, a1),
9495            self.relaxed_narrow_u16x16(b0, b1),
9496        )
9497    }
9498    #[doc = "Create a SIMD mask with all lanes set from the given boolean value."]
9499    #[inline(always)]
9500    fn splat_mask16x32(self, val: bool) -> mask16x32<Self> {
9501        let half = self.splat_mask16x16(val);
9502        self.combine_mask16x16(half, half)
9503    }
9504    #[doc = "Create a SIMD mask from a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are ignored."]
9505    #[inline(always)]
9506    fn from_bitmask_mask16x32(self, bits: u64) -> mask16x32<Self> {
9507        let lo = self.from_bitmask_mask16x16(bits);
9508        let hi = self.from_bitmask_mask16x16(bits >> 16usize);
9509        self.combine_mask16x16(lo, hi)
9510    }
9511    #[doc = "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared."]
9512    #[inline(always)]
9513    fn to_bitmask_mask16x32(self, a: mask16x32<Self>) -> u64 {
9514        let (lo, hi) = self.split_mask16x32(a);
9515        let lo = self.to_bitmask_mask16x16(lo);
9516        let hi = self.to_bitmask_mask16x16(hi);
9517        lo | (hi << 16usize)
9518    }
9519    #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."]
9520    fn from_vector_mask16x32(self, vector: i16x32<Self>) -> mask16x32<Self>;
9521    #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."]
9522    fn to_vector_mask16x32(self, a: mask16x32<Self>) -> i16x32<Self>;
9523    #[doc = "Set one logical lane of a SIMD mask."]
9524    fn set_mask16x32(self, a: &mut mask16x32<Self>, index: usize, value: bool) -> ();
9525    #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
9526    fn rotate_elements_left_mask16x32<const OFFSET: usize>(
9527        self,
9528        a: mask16x32<Self>,
9529    ) -> mask16x32<Self>;
9530    #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
9531    fn rotate_elements_right_mask16x32<const OFFSET: usize>(
9532        self,
9533        a: mask16x32<Self>,
9534    ) -> mask16x32<Self>;
9535    #[doc = "Compute the logical AND of two masks."]
9536    #[inline(always)]
9537    fn and_mask16x32(self, a: mask16x32<Self>, b: mask16x32<Self>) -> mask16x32<Self> {
9538        let (a0, a1) = self.split_mask16x32(a);
9539        let (b0, b1) = self.split_mask16x32(b);
9540        self.combine_mask16x16(self.and_mask16x16(a0, b0), self.and_mask16x16(a1, b1))
9541    }
9542    #[doc = "Compute the logical OR of two masks."]
9543    #[inline(always)]
9544    fn or_mask16x32(self, a: mask16x32<Self>, b: mask16x32<Self>) -> mask16x32<Self> {
9545        let (a0, a1) = self.split_mask16x32(a);
9546        let (b0, b1) = self.split_mask16x32(b);
9547        self.combine_mask16x16(self.or_mask16x16(a0, b0), self.or_mask16x16(a1, b1))
9548    }
9549    #[doc = "Compute the logical XOR of two masks."]
9550    #[inline(always)]
9551    fn xor_mask16x32(self, a: mask16x32<Self>, b: mask16x32<Self>) -> mask16x32<Self> {
9552        let (a0, a1) = self.split_mask16x32(a);
9553        let (b0, b1) = self.split_mask16x32(b);
9554        self.combine_mask16x16(self.xor_mask16x16(a0, b0), self.xor_mask16x16(a1, b1))
9555    }
9556    #[doc = "Compute the logical NOT of the mask."]
9557    #[inline(always)]
9558    fn not_mask16x32(self, a: mask16x32<Self>) -> mask16x32<Self> {
9559        let (a0, a1) = self.split_mask16x32(a);
9560        self.combine_mask16x16(self.not_mask16x16(a0), self.not_mask16x16(a1))
9561    }
9562    #[doc = "Reverse the order of the mask's logical lanes."]
9563    #[inline(always)]
9564    fn reverse_mask16x32(self, a: mask16x32<Self>) -> mask16x32<Self> {
9565        let (a0, a1) = self.split_mask16x32(a);
9566        self.combine_mask16x16(self.reverse_mask16x16(a1), self.reverse_mask16x16(a0))
9567    }
9568    #[doc = "Select elements from `b` and `c` based on the mask operand `a`.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
9569    #[inline(always)]
9570    fn select_mask16x32(
9571        self,
9572        a: mask16x32<Self>,
9573        b: mask16x32<Self>,
9574        c: mask16x32<Self>,
9575    ) -> mask16x32<Self> {
9576        let (a0, a1) = self.split_mask16x32(a);
9577        let (b0, b1) = self.split_mask16x32(b);
9578        let (c0, c1) = self.split_mask16x32(c);
9579        self.combine_mask16x16(
9580            self.select_mask16x16(a0, b0, c0),
9581            self.select_mask16x16(a1, b1, c1),
9582        )
9583    }
9584    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
9585    #[inline(always)]
9586    fn simd_eq_mask16x32(self, a: mask16x32<Self>, b: mask16x32<Self>) -> mask16x32<Self> {
9587        let (a0, a1) = self.split_mask16x32(a);
9588        let (b0, b1) = self.split_mask16x32(b);
9589        self.combine_mask16x16(
9590            self.simd_eq_mask16x16(a0, b0),
9591            self.simd_eq_mask16x16(a1, b1),
9592        )
9593    }
9594    #[doc = "Compare two masks element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
9595    #[inline(always)]
9596    fn simd_ne_mask16x32(self, a: mask16x32<Self>, b: mask16x32<Self>) -> mask16x32<Self> {
9597        self.not_mask16x32(self.simd_eq_mask16x32(a, b))
9598    }
9599    #[doc = "Returns true if any logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
9600    #[inline(always)]
9601    fn any_true_mask16x32(self, a: mask16x32<Self>) -> bool {
9602        let (a0, a1) = self.split_mask16x32(a);
9603        self.any_true_mask16x16(self.or_mask16x16(a0, a1))
9604    }
9605    #[doc = "Returns true if all logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
9606    #[inline(always)]
9607    fn all_true_mask16x32(self, a: mask16x32<Self>) -> bool {
9608        let (a0, a1) = self.split_mask16x32(a);
9609        self.all_true_mask16x16(self.and_mask16x16(a0, a1))
9610    }
9611    #[doc = "Returns true if any logical lanes in this mask are false.\n\nThis is logically equivalent to `!all_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
9612    #[inline(always)]
9613    fn any_false_mask16x32(self, a: mask16x32<Self>) -> bool {
9614        let (a0, a1) = self.split_mask16x32(a);
9615        self.any_false_mask16x16(self.and_mask16x16(a0, a1))
9616    }
9617    #[doc = "Returns true if all logical lanes in this mask are false.\n\nThis is logically equivalent to `!any_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
9618    #[inline(always)]
9619    fn all_false_mask16x32(self, a: mask16x32<Self>) -> bool {
9620        let (a0, a1) = self.split_mask16x32(a);
9621        self.all_false_mask16x16(self.or_mask16x16(a0, a1))
9622    }
9623    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
9624    fn split_mask16x32(self, a: mask16x32<Self>) -> (mask16x16<Self>, mask16x16<Self>);
9625    #[doc = "Widen each boolean lane into two masks of the same logical width, preserving its value.\n\nThe first result contains the lower lanes and the second contains the upper lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
9626    #[inline(always)]
9627    fn widen_mask16x32(self, a: mask16x32<Self>) -> (mask32x16<Self>, mask32x16<Self>) {
9628        let (a0, a1) = self.split_mask16x32(a);
9629        let (a00, a01) = self.widen_mask16x16(a0);
9630        let (a10, a11) = self.widen_mask16x16(a1);
9631        (
9632            self.combine_mask32x8(a00, a01),
9633            self.combine_mask32x8(a10, a11),
9634        )
9635    }
9636    #[doc = "Narrow each boolean lane of two masks and concatenate them into one mask of the same logical width, preserving each value.\n\n`a` supplies the lower result lanes and `b` supplies the upper result lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
9637    #[inline(always)]
9638    fn narrow_mask16x32(self, a: mask16x32<Self>, b: mask16x32<Self>) -> mask8x64<Self> {
9639        let (a0, a1) = self.split_mask16x32(a);
9640        let (b0, b1) = self.split_mask16x32(b);
9641        self.combine_mask8x32(self.narrow_mask16x16(a0, a1), self.narrow_mask16x16(b0, b1))
9642    }
9643    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
9644    #[inline(always)]
9645    fn abs_i32x16(self, a: i32x16<Self>) -> i32x16<Self> {
9646        let (a0, a1) = self.split_i32x16(a);
9647        self.combine_i32x8(self.abs_i32x8(a0), self.abs_i32x8(a1))
9648    }
9649    #[doc = "Create a SIMD vector with all elements set to the given value."]
9650    #[inline(always)]
9651    fn splat_i32x16(self, val: i32) -> i32x16<Self> {
9652        let half = self.splat_i32x8(val);
9653        self.combine_i32x8(half, half)
9654    }
9655    #[doc = "Reverse the order of the vector's elements."]
9656    #[inline(always)]
9657    fn reverse_i32x16(self, a: i32x16<Self>) -> i32x16<Self> {
9658        let (a0, a1) = self.split_i32x16(a);
9659        self.combine_i32x8(self.reverse_i32x8(a1), self.reverse_i32x8(a0))
9660    }
9661    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
9662    fn slide_i32x16<const SHIFT: usize>(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self>;
9663    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
9664    #[inline(always)]
9665    fn slide_within_blocks_i32x16<const SHIFT: usize>(
9666        self,
9667        a: i32x16<Self>,
9668        b: i32x16<Self>,
9669    ) -> i32x16<Self> {
9670        let (a0, a1) = self.split_i32x16(a);
9671        let (b0, b1) = self.split_i32x16(b);
9672        self.combine_i32x8(
9673            self.slide_within_blocks_i32x8::<SHIFT>(a0, b0),
9674            self.slide_within_blocks_i32x8::<SHIFT>(a1, b1),
9675        )
9676    }
9677    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
9678    #[inline(always)]
9679    fn swizzle_dyn_within_blocks_i32x16(
9680        self,
9681        a: i32x16<Self>,
9682        indices: u8x64<Self>,
9683    ) -> i32x16<Self> {
9684        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x64(Bytes::to_bytes(a), indices))
9685    }
9686    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
9687    #[inline(always)]
9688    fn swizzle_dyn_i32x16(self, a: i32x16<Self>, indices: u8x64<Self>) -> i32x16<Self> {
9689        Bytes::from_bytes(self.swizzle_dyn_u8x64(Bytes::to_bytes(a), indices))
9690    }
9691    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
9692    #[inline(always)]
9693    fn swizzle_dyn_precise_i32x16(self, a: i32x16<Self>, indices: u8x64<Self>) -> i32x16<Self> {
9694        Bytes::from_bytes(self.swizzle_dyn_precise_u8x64(Bytes::to_bytes(a), indices))
9695    }
9696    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
9697    #[inline(always)]
9698    fn concat_swizzle_dyn_i32x16(
9699        self,
9700        a: i32x16<Self>,
9701        b: i32x16<Self>,
9702        indices: u8x64<Self>,
9703    ) -> i32x16<Self> {
9704        Bytes::from_bytes(self.concat_swizzle_dyn_u8x64(
9705            Bytes::to_bytes(a),
9706            Bytes::to_bytes(b),
9707            indices,
9708        ))
9709    }
9710    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
9711    #[inline(always)]
9712    fn concat_swizzle_dyn_precise_i32x16(
9713        self,
9714        a: i32x16<Self>,
9715        b: i32x16<Self>,
9716        indices: u8x64<Self>,
9717    ) -> i32x16<Self> {
9718        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x64(
9719            Bytes::to_bytes(a),
9720            Bytes::to_bytes(b),
9721            indices,
9722        ))
9723    }
9724    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
9725    fn compress_i32x16(self, values: i32x16<Self>, mask: mask32x16<Self>) -> i32x16<Self>;
9726    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
9727    fn compress_merge_i32x16(
9728        self,
9729        values: i32x16<Self>,
9730        mask: mask32x16<Self>,
9731        merge: i32x16<Self>,
9732    ) -> i32x16<Self>;
9733    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
9734    fn expand_i32x16(self, values: i32x16<Self>, mask: mask32x16<Self>) -> i32x16<Self>;
9735    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
9736    fn expand_merge_i32x16(
9737        self,
9738        values: i32x16<Self>,
9739        mask: mask32x16<Self>,
9740        merge: i32x16<Self>,
9741    ) -> i32x16<Self>;
9742    #[doc = "Return the number of ones in the binary representation of each element."]
9743    #[inline(always)]
9744    fn count_ones_i32x16(self, a: i32x16<Self>) -> i32x16<Self> {
9745        let (a0, a1) = self.split_i32x16(a);
9746        self.combine_i32x8(self.count_ones_i32x8(a0), self.count_ones_i32x8(a1))
9747    }
9748    #[doc = "Return the number of zeros in the binary representation of each element."]
9749    #[inline(always)]
9750    fn count_zeros_i32x16(self, a: i32x16<Self>) -> i32x16<Self> {
9751        let (a0, a1) = self.split_i32x16(a);
9752        self.combine_i32x8(self.count_zeros_i32x8(a0), self.count_zeros_i32x8(a1))
9753    }
9754    #[doc = "Add two vectors element-wise, wrapping on overflow."]
9755    #[inline(always)]
9756    fn add_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9757        let (a0, a1) = self.split_i32x16(a);
9758        let (b0, b1) = self.split_i32x16(b);
9759        self.combine_i32x8(self.add_i32x8(a0, b0), self.add_i32x8(a1, b1))
9760    }
9761    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
9762    #[inline(always)]
9763    fn saturating_add_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9764        let (a0, a1) = self.split_i32x16(a);
9765        let (b0, b1) = self.split_i32x16(b);
9766        self.combine_i32x8(
9767            self.saturating_add_i32x8(a0, b0),
9768            self.saturating_add_i32x8(a1, b1),
9769        )
9770    }
9771    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
9772    #[inline(always)]
9773    fn sub_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9774        let (a0, a1) = self.split_i32x16(a);
9775        let (b0, b1) = self.split_i32x16(b);
9776        self.combine_i32x8(self.sub_i32x8(a0, b0), self.sub_i32x8(a1, b1))
9777    }
9778    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
9779    #[inline(always)]
9780    fn saturating_sub_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9781        let (a0, a1) = self.split_i32x16(a);
9782        let (b0, b1) = self.split_i32x16(b);
9783        self.combine_i32x8(
9784            self.saturating_sub_i32x8(a0, b0),
9785            self.saturating_sub_i32x8(a1, b1),
9786        )
9787    }
9788    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
9789    #[inline(always)]
9790    fn mul_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9791        let (a0, a1) = self.split_i32x16(a);
9792        let (b0, b1) = self.split_i32x16(b);
9793        self.combine_i32x8(self.mul_i32x8(a0, b0), self.mul_i32x8(a1, b1))
9794    }
9795    #[doc = "Compute the bitwise AND of two vectors."]
9796    #[inline(always)]
9797    fn and_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9798        let (a0, a1) = self.split_i32x16(a);
9799        let (b0, b1) = self.split_i32x16(b);
9800        self.combine_i32x8(self.and_i32x8(a0, b0), self.and_i32x8(a1, b1))
9801    }
9802    #[doc = "Compute the bitwise OR of two vectors."]
9803    #[inline(always)]
9804    fn or_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9805        let (a0, a1) = self.split_i32x16(a);
9806        let (b0, b1) = self.split_i32x16(b);
9807        self.combine_i32x8(self.or_i32x8(a0, b0), self.or_i32x8(a1, b1))
9808    }
9809    #[doc = "Compute the bitwise XOR of two vectors."]
9810    #[inline(always)]
9811    fn xor_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9812        let (a0, a1) = self.split_i32x16(a);
9813        let (b0, b1) = self.split_i32x16(b);
9814        self.combine_i32x8(self.xor_i32x8(a0, b0), self.xor_i32x8(a1, b1))
9815    }
9816    #[doc = "Compute the bitwise NOT of the vector."]
9817    #[inline(always)]
9818    fn not_i32x16(self, a: i32x16<Self>) -> i32x16<Self> {
9819        let (a0, a1) = self.split_i32x16(a);
9820        self.combine_i32x8(self.not_i32x8(a0), self.not_i32x8(a1))
9821    }
9822    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
9823    #[inline(always)]
9824    fn shl_i32x16(self, a: i32x16<Self>, shift: u32) -> i32x16<Self> {
9825        let (a0, a1) = self.split_i32x16(a);
9826        self.combine_i32x8(self.shl_i32x8(a0, shift), self.shl_i32x8(a1, shift))
9827    }
9828    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
9829    #[inline(always)]
9830    fn shlv_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9831        let (a0, a1) = self.split_i32x16(a);
9832        let (b0, b1) = self.split_i32x16(b);
9833        self.combine_i32x8(self.shlv_i32x8(a0, b0), self.shlv_i32x8(a1, b1))
9834    }
9835    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
9836    #[inline(always)]
9837    fn shr_i32x16(self, a: i32x16<Self>, shift: u32) -> i32x16<Self> {
9838        let (a0, a1) = self.split_i32x16(a);
9839        self.combine_i32x8(self.shr_i32x8(a0, shift), self.shr_i32x8(a1, shift))
9840    }
9841    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
9842    #[inline(always)]
9843    fn shrv_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9844        let (a0, a1) = self.split_i32x16(a);
9845        let (b0, b1) = self.split_i32x16(b);
9846        self.combine_i32x8(self.shrv_i32x8(a0, b0), self.shrv_i32x8(a1, b1))
9847    }
9848    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
9849    #[inline(always)]
9850    fn reduce_max_i32x16(self, a: i32x16<Self>) -> i32 {
9851        let (a0, a1) = self.split_i32x16(a);
9852        self.reduce_max_i32x8(self.max_i32x8(a0, a1))
9853    }
9854    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
9855    #[inline(always)]
9856    fn reduce_min_i32x16(self, a: i32x16<Self>) -> i32 {
9857        let (a0, a1) = self.split_i32x16(a);
9858        self.reduce_min_i32x8(self.min_i32x8(a0, a1))
9859    }
9860    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
9861    #[inline(always)]
9862    fn reduce_sum_i32x16(self, a: i32x16<Self>) -> i32 {
9863        let (a0, a1) = self.split_i32x16(a);
9864        self.reduce_sum_i32x8(self.add_i32x8(a0, a1))
9865    }
9866    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
9867    #[inline(always)]
9868    fn reduce_product_i32x16(self, a: i32x16<Self>) -> i32 {
9869        let (a0, a1) = self.split_i32x16(a);
9870        self.reduce_product_i32x8(self.mul_i32x8(a0, a1))
9871    }
9872    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
9873    #[inline(always)]
9874    fn max_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9875        let (a0, a1) = self.split_i32x16(a);
9876        let (b0, b1) = self.split_i32x16(b);
9877        self.combine_i32x8(self.max_i32x8(a0, b0), self.max_i32x8(a1, b1))
9878    }
9879    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
9880    #[inline(always)]
9881    fn min_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9882        let (a0, a1) = self.split_i32x16(a);
9883        let (b0, b1) = self.split_i32x16(b);
9884        self.combine_i32x8(self.min_i32x8(a0, b0), self.min_i32x8(a1, b1))
9885    }
9886    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
9887    #[inline(always)]
9888    fn clamp_i32x16(self, a: i32x16<Self>, b: i32x16<Self>, c: i32x16<Self>) -> i32x16<Self> {
9889        let (a0, a1) = self.split_i32x16(a);
9890        let (b0, b1) = self.split_i32x16(b);
9891        let (c0, c1) = self.split_i32x16(c);
9892        self.combine_i32x8(self.clamp_i32x8(a0, b0, c0), self.clamp_i32x8(a1, b1, c1))
9893    }
9894    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
9895    #[inline(always)]
9896    fn simd_eq_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> mask32x16<Self> {
9897        let (a0, a1) = self.split_i32x16(a);
9898        let (b0, b1) = self.split_i32x16(b);
9899        self.combine_mask32x8(self.simd_eq_i32x8(a0, b0), self.simd_eq_i32x8(a1, b1))
9900    }
9901    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
9902    #[inline(always)]
9903    fn simd_ne_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> mask32x16<Self> {
9904        self.not_mask32x16(self.simd_eq_i32x16(a, b))
9905    }
9906    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
9907    #[inline(always)]
9908    fn simd_lt_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> mask32x16<Self> {
9909        let (a0, a1) = self.split_i32x16(a);
9910        let (b0, b1) = self.split_i32x16(b);
9911        self.combine_mask32x8(self.simd_lt_i32x8(a0, b0), self.simd_lt_i32x8(a1, b1))
9912    }
9913    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
9914    #[inline(always)]
9915    fn simd_le_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> mask32x16<Self> {
9916        let (a0, a1) = self.split_i32x16(a);
9917        let (b0, b1) = self.split_i32x16(b);
9918        self.combine_mask32x8(self.simd_le_i32x8(a0, b0), self.simd_le_i32x8(a1, b1))
9919    }
9920    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
9921    #[inline(always)]
9922    fn simd_ge_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> mask32x16<Self> {
9923        self.simd_le_i32x16(b, a)
9924    }
9925    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
9926    #[inline(always)]
9927    fn simd_gt_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> mask32x16<Self> {
9928        self.simd_lt_i32x16(b, a)
9929    }
9930    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
9931    #[inline(always)]
9932    fn zip_low_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9933        let (a0, _) = self.split_i32x16(a);
9934        let (b0, _) = self.split_i32x16(b);
9935        self.combine_i32x8(self.zip_low_i32x8(a0, b0), self.zip_high_i32x8(a0, b0))
9936    }
9937    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
9938    #[inline(always)]
9939    fn zip_high_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9940        let (_, a1) = self.split_i32x16(a);
9941        let (_, b1) = self.split_i32x16(b);
9942        self.combine_i32x8(self.zip_low_i32x8(a1, b1), self.zip_high_i32x8(a1, b1))
9943    }
9944    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
9945    #[inline(always)]
9946    fn unzip_low_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9947        let (a0, a1) = self.split_i32x16(a);
9948        let (b0, b1) = self.split_i32x16(b);
9949        self.combine_i32x8(self.unzip_low_i32x8(a0, a1), self.unzip_low_i32x8(b0, b1))
9950    }
9951    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
9952    #[inline(always)]
9953    fn unzip_high_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i32x16<Self> {
9954        let (a0, a1) = self.split_i32x16(a);
9955        let (b0, b1) = self.split_i32x16(b);
9956        self.combine_i32x8(self.unzip_high_i32x8(a0, a1), self.unzip_high_i32x8(b0, b1))
9957    }
9958    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
9959    #[inline(always)]
9960    fn interleave_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> (i32x16<Self>, i32x16<Self>) {
9961        let (a0, a1) = self.split_i32x16(a);
9962        let (b0, b1) = self.split_i32x16(b);
9963        let lo_lo = self.zip_low_i32x8(a0, b0);
9964        let lo_hi = self.zip_high_i32x8(a0, b0);
9965        let hi_lo = self.zip_low_i32x8(a1, b1);
9966        let hi_hi = self.zip_high_i32x8(a1, b1);
9967        (
9968            self.combine_i32x8(lo_lo, lo_hi),
9969            self.combine_i32x8(hi_lo, hi_hi),
9970        )
9971    }
9972    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
9973    #[inline(always)]
9974    fn deinterleave_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> (i32x16<Self>, i32x16<Self>) {
9975        let (a0, a1) = self.split_i32x16(a);
9976        let (b0, b1) = self.split_i32x16(b);
9977        let lo_even = self.unzip_low_i32x8(a0, a1);
9978        let lo_odd = self.unzip_high_i32x8(a0, a1);
9979        let hi_even = self.unzip_low_i32x8(b0, b1);
9980        let hi_odd = self.unzip_high_i32x8(b0, b1);
9981        (
9982            self.combine_i32x8(lo_even, hi_even),
9983            self.combine_i32x8(lo_odd, hi_odd),
9984        )
9985    }
9986    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
9987    #[inline(always)]
9988    fn select_i32x16(self, a: mask32x16<Self>, b: i32x16<Self>, c: i32x16<Self>) -> i32x16<Self> {
9989        let (a0, a1) = self.split_mask32x16(a);
9990        let (b0, b1) = self.split_i32x16(b);
9991        let (c0, c1) = self.split_i32x16(c);
9992        self.combine_i32x8(self.select_i32x8(a0, b0, c0), self.select_i32x8(a1, b1, c1))
9993    }
9994    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
9995    fn split_i32x16(self, a: i32x16<Self>) -> (i32x8<Self>, i32x8<Self>);
9996    #[doc = "Negate each element of the vector, wrapping on overflow."]
9997    #[inline(always)]
9998    fn neg_i32x16(self, a: i32x16<Self>) -> i32x16<Self> {
9999        let (a0, a1) = self.split_i32x16(a);
10000        self.combine_i32x8(self.neg_i32x8(a0), self.neg_i32x8(a1))
10001    }
10002    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
10003    #[inline(always)]
10004    fn widen_i32x16(self, a: i32x16<Self>) -> (i64x8<Self>, i64x8<Self>) {
10005        let (a0, a1) = self.split_i32x16(a);
10006        let (a00, a01) = self.widen_i32x8(a0);
10007        let (a10, a11) = self.widen_i32x8(a1);
10008        (self.combine_i64x4(a00, a01), self.combine_i64x4(a10, a11))
10009    }
10010    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
10011    #[inline(always)]
10012    fn widening_mul_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> (i64x8<Self>, i64x8<Self>) {
10013        let (a0, a1) = self.split_i32x16(a);
10014        let (b0, b1) = self.split_i32x16(b);
10015        let (low0, low1) = self.widening_mul_i32x8(a0, b0);
10016        let (high0, high1) = self.widening_mul_i32x8(a1, b1);
10017        (
10018            self.combine_i64x4(low0, low1),
10019            self.combine_i64x4(high0, high1),
10020        )
10021    }
10022    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
10023    #[inline(always)]
10024    fn widening_add_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> (i64x8<Self>, i64x8<Self>) {
10025        let (a0, a1) = self.split_i32x16(a);
10026        let (b0, b1) = self.split_i32x16(b);
10027        let (low0, low1) = self.widening_add_i32x8(a0, b0);
10028        let (high0, high1) = self.widening_add_i32x8(a1, b1);
10029        (
10030            self.combine_i64x4(low0, low1),
10031            self.combine_i64x4(high0, high1),
10032        )
10033    }
10034    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
10035    #[inline(always)]
10036    fn pairwise_widening_add_i32x16(self, a: i32x16<Self>) -> i64x8<Self> {
10037        let (a0, a1) = self.split_i32x16(a);
10038        self.combine_i64x4(
10039            self.pairwise_widening_add_i32x8(a0),
10040            self.pairwise_widening_add_i32x8(a1),
10041        )
10042    }
10043    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
10044    #[inline(always)]
10045    fn pairwise_dot_product_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i64x8<Self> {
10046        let (a0, a1) = self.split_i32x16(a);
10047        let (b0, b1) = self.split_i32x16(b);
10048        self.combine_i64x4(
10049            self.pairwise_dot_product_i32x8(a0, b0),
10050            self.pairwise_dot_product_i32x8(a1, b1),
10051        )
10052    }
10053    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
10054    #[inline(always)]
10055    fn narrow_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i16x32<Self> {
10056        let (a0, a1) = self.split_i32x16(a);
10057        let (b0, b1) = self.split_i32x16(b);
10058        self.combine_i16x16(self.narrow_i32x8(a0, a1), self.narrow_i32x8(b0, b1))
10059    }
10060    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
10061    #[inline(always)]
10062    fn saturating_narrow_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i16x32<Self> {
10063        let (a0, a1) = self.split_i32x16(a);
10064        let (b0, b1) = self.split_i32x16(b);
10065        self.combine_i16x16(
10066            self.saturating_narrow_i32x8(a0, a1),
10067            self.saturating_narrow_i32x8(b0, b1),
10068        )
10069    }
10070    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
10071    #[inline(always)]
10072    fn relaxed_narrow_i32x16(self, a: i32x16<Self>, b: i32x16<Self>) -> i16x32<Self> {
10073        let (a0, a1) = self.split_i32x16(a);
10074        let (b0, b1) = self.split_i32x16(b);
10075        self.combine_i16x16(
10076            self.relaxed_narrow_i32x8(a0, a1),
10077            self.relaxed_narrow_i32x8(b0, b1),
10078        )
10079    }
10080    #[doc = "Convert each signed 32-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
10081    #[inline(always)]
10082    fn cvt_f32_i32x16(self, a: i32x16<Self>) -> f32x16<Self> {
10083        let (a0, a1) = self.split_i32x16(a);
10084        self.combine_f32x8(self.cvt_f32_i32x8(a0), self.cvt_f32_i32x8(a1))
10085    }
10086    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
10087    #[inline(always)]
10088    fn abs_u32x16(self, a: u32x16<Self>) -> u32x16<Self> {
10089        a
10090    }
10091    #[doc = "Create a SIMD vector with all elements set to the given value."]
10092    #[inline(always)]
10093    fn splat_u32x16(self, val: u32) -> u32x16<Self> {
10094        let half = self.splat_u32x8(val);
10095        self.combine_u32x8(half, half)
10096    }
10097    #[doc = "Reverse the order of the vector's elements."]
10098    #[inline(always)]
10099    fn reverse_u32x16(self, a: u32x16<Self>) -> u32x16<Self> {
10100        let (a0, a1) = self.split_u32x16(a);
10101        self.combine_u32x8(self.reverse_u32x8(a1), self.reverse_u32x8(a0))
10102    }
10103    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
10104    fn slide_u32x16<const SHIFT: usize>(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self>;
10105    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
10106    #[inline(always)]
10107    fn slide_within_blocks_u32x16<const SHIFT: usize>(
10108        self,
10109        a: u32x16<Self>,
10110        b: u32x16<Self>,
10111    ) -> u32x16<Self> {
10112        let (a0, a1) = self.split_u32x16(a);
10113        let (b0, b1) = self.split_u32x16(b);
10114        self.combine_u32x8(
10115            self.slide_within_blocks_u32x8::<SHIFT>(a0, b0),
10116            self.slide_within_blocks_u32x8::<SHIFT>(a1, b1),
10117        )
10118    }
10119    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
10120    #[inline(always)]
10121    fn swizzle_dyn_within_blocks_u32x16(
10122        self,
10123        a: u32x16<Self>,
10124        indices: u8x64<Self>,
10125    ) -> u32x16<Self> {
10126        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x64(Bytes::to_bytes(a), indices))
10127    }
10128    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
10129    #[inline(always)]
10130    fn swizzle_dyn_u32x16(self, a: u32x16<Self>, indices: u8x64<Self>) -> u32x16<Self> {
10131        Bytes::from_bytes(self.swizzle_dyn_u8x64(Bytes::to_bytes(a), indices))
10132    }
10133    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
10134    #[inline(always)]
10135    fn swizzle_dyn_precise_u32x16(self, a: u32x16<Self>, indices: u8x64<Self>) -> u32x16<Self> {
10136        Bytes::from_bytes(self.swizzle_dyn_precise_u8x64(Bytes::to_bytes(a), indices))
10137    }
10138    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
10139    #[inline(always)]
10140    fn concat_swizzle_dyn_u32x16(
10141        self,
10142        a: u32x16<Self>,
10143        b: u32x16<Self>,
10144        indices: u8x64<Self>,
10145    ) -> u32x16<Self> {
10146        Bytes::from_bytes(self.concat_swizzle_dyn_u8x64(
10147            Bytes::to_bytes(a),
10148            Bytes::to_bytes(b),
10149            indices,
10150        ))
10151    }
10152    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
10153    #[inline(always)]
10154    fn concat_swizzle_dyn_precise_u32x16(
10155        self,
10156        a: u32x16<Self>,
10157        b: u32x16<Self>,
10158        indices: u8x64<Self>,
10159    ) -> u32x16<Self> {
10160        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x64(
10161            Bytes::to_bytes(a),
10162            Bytes::to_bytes(b),
10163            indices,
10164        ))
10165    }
10166    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
10167    fn compress_u32x16(self, values: u32x16<Self>, mask: mask32x16<Self>) -> u32x16<Self>;
10168    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
10169    fn compress_merge_u32x16(
10170        self,
10171        values: u32x16<Self>,
10172        mask: mask32x16<Self>,
10173        merge: u32x16<Self>,
10174    ) -> u32x16<Self>;
10175    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
10176    fn expand_u32x16(self, values: u32x16<Self>, mask: mask32x16<Self>) -> u32x16<Self>;
10177    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
10178    fn expand_merge_u32x16(
10179        self,
10180        values: u32x16<Self>,
10181        mask: mask32x16<Self>,
10182        merge: u32x16<Self>,
10183    ) -> u32x16<Self>;
10184    #[doc = "Return the number of ones in the binary representation of each element."]
10185    #[inline(always)]
10186    fn count_ones_u32x16(self, a: u32x16<Self>) -> u32x16<Self> {
10187        let (a0, a1) = self.split_u32x16(a);
10188        self.combine_u32x8(self.count_ones_u32x8(a0), self.count_ones_u32x8(a1))
10189    }
10190    #[doc = "Return the number of zeros in the binary representation of each element."]
10191    #[inline(always)]
10192    fn count_zeros_u32x16(self, a: u32x16<Self>) -> u32x16<Self> {
10193        let (a0, a1) = self.split_u32x16(a);
10194        self.combine_u32x8(self.count_zeros_u32x8(a0), self.count_zeros_u32x8(a1))
10195    }
10196    #[doc = "Add two vectors element-wise, wrapping on overflow."]
10197    #[inline(always)]
10198    fn add_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
10199        let (a0, a1) = self.split_u32x16(a);
10200        let (b0, b1) = self.split_u32x16(b);
10201        self.combine_u32x8(self.add_u32x8(a0, b0), self.add_u32x8(a1, b1))
10202    }
10203    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
10204    #[inline(always)]
10205    fn saturating_add_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
10206        let (a0, a1) = self.split_u32x16(a);
10207        let (b0, b1) = self.split_u32x16(b);
10208        self.combine_u32x8(
10209            self.saturating_add_u32x8(a0, b0),
10210            self.saturating_add_u32x8(a1, b1),
10211        )
10212    }
10213    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
10214    #[inline(always)]
10215    fn sub_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
10216        let (a0, a1) = self.split_u32x16(a);
10217        let (b0, b1) = self.split_u32x16(b);
10218        self.combine_u32x8(self.sub_u32x8(a0, b0), self.sub_u32x8(a1, b1))
10219    }
10220    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
10221    #[inline(always)]
10222    fn saturating_sub_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
10223        let (a0, a1) = self.split_u32x16(a);
10224        let (b0, b1) = self.split_u32x16(b);
10225        self.combine_u32x8(
10226            self.saturating_sub_u32x8(a0, b0),
10227            self.saturating_sub_u32x8(a1, b1),
10228        )
10229    }
10230    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
10231    #[inline(always)]
10232    fn mul_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
10233        let (a0, a1) = self.split_u32x16(a);
10234        let (b0, b1) = self.split_u32x16(b);
10235        self.combine_u32x8(self.mul_u32x8(a0, b0), self.mul_u32x8(a1, b1))
10236    }
10237    #[doc = "Compute the bitwise AND of two vectors."]
10238    #[inline(always)]
10239    fn and_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
10240        let (a0, a1) = self.split_u32x16(a);
10241        let (b0, b1) = self.split_u32x16(b);
10242        self.combine_u32x8(self.and_u32x8(a0, b0), self.and_u32x8(a1, b1))
10243    }
10244    #[doc = "Compute the bitwise OR of two vectors."]
10245    #[inline(always)]
10246    fn or_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
10247        let (a0, a1) = self.split_u32x16(a);
10248        let (b0, b1) = self.split_u32x16(b);
10249        self.combine_u32x8(self.or_u32x8(a0, b0), self.or_u32x8(a1, b1))
10250    }
10251    #[doc = "Compute the bitwise XOR of two vectors."]
10252    #[inline(always)]
10253    fn xor_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
10254        let (a0, a1) = self.split_u32x16(a);
10255        let (b0, b1) = self.split_u32x16(b);
10256        self.combine_u32x8(self.xor_u32x8(a0, b0), self.xor_u32x8(a1, b1))
10257    }
10258    #[doc = "Compute the bitwise NOT of the vector."]
10259    #[inline(always)]
10260    fn not_u32x16(self, a: u32x16<Self>) -> u32x16<Self> {
10261        let (a0, a1) = self.split_u32x16(a);
10262        self.combine_u32x8(self.not_u32x8(a0), self.not_u32x8(a1))
10263    }
10264    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
10265    #[inline(always)]
10266    fn shl_u32x16(self, a: u32x16<Self>, shift: u32) -> u32x16<Self> {
10267        let (a0, a1) = self.split_u32x16(a);
10268        self.combine_u32x8(self.shl_u32x8(a0, shift), self.shl_u32x8(a1, shift))
10269    }
10270    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
10271    #[inline(always)]
10272    fn shlv_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
10273        let (a0, a1) = self.split_u32x16(a);
10274        let (b0, b1) = self.split_u32x16(b);
10275        self.combine_u32x8(self.shlv_u32x8(a0, b0), self.shlv_u32x8(a1, b1))
10276    }
10277    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
10278    #[inline(always)]
10279    fn shr_u32x16(self, a: u32x16<Self>, shift: u32) -> u32x16<Self> {
10280        let (a0, a1) = self.split_u32x16(a);
10281        self.combine_u32x8(self.shr_u32x8(a0, shift), self.shr_u32x8(a1, shift))
10282    }
10283    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
10284    #[inline(always)]
10285    fn shrv_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
10286        let (a0, a1) = self.split_u32x16(a);
10287        let (b0, b1) = self.split_u32x16(b);
10288        self.combine_u32x8(self.shrv_u32x8(a0, b0), self.shrv_u32x8(a1, b1))
10289    }
10290    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
10291    #[inline(always)]
10292    fn reduce_max_u32x16(self, a: u32x16<Self>) -> u32 {
10293        let (a0, a1) = self.split_u32x16(a);
10294        self.reduce_max_u32x8(self.max_u32x8(a0, a1))
10295    }
10296    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
10297    #[inline(always)]
10298    fn reduce_min_u32x16(self, a: u32x16<Self>) -> u32 {
10299        let (a0, a1) = self.split_u32x16(a);
10300        self.reduce_min_u32x8(self.min_u32x8(a0, a1))
10301    }
10302    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
10303    #[inline(always)]
10304    fn reduce_sum_u32x16(self, a: u32x16<Self>) -> u32 {
10305        let (a0, a1) = self.split_u32x16(a);
10306        self.reduce_sum_u32x8(self.add_u32x8(a0, a1))
10307    }
10308    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
10309    #[inline(always)]
10310    fn reduce_product_u32x16(self, a: u32x16<Self>) -> u32 {
10311        let (a0, a1) = self.split_u32x16(a);
10312        self.reduce_product_u32x8(self.mul_u32x8(a0, a1))
10313    }
10314    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
10315    #[inline(always)]
10316    fn max_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
10317        let (a0, a1) = self.split_u32x16(a);
10318        let (b0, b1) = self.split_u32x16(b);
10319        self.combine_u32x8(self.max_u32x8(a0, b0), self.max_u32x8(a1, b1))
10320    }
10321    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
10322    #[inline(always)]
10323    fn min_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
10324        let (a0, a1) = self.split_u32x16(a);
10325        let (b0, b1) = self.split_u32x16(b);
10326        self.combine_u32x8(self.min_u32x8(a0, b0), self.min_u32x8(a1, b1))
10327    }
10328    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
10329    #[inline(always)]
10330    fn clamp_u32x16(self, a: u32x16<Self>, b: u32x16<Self>, c: u32x16<Self>) -> u32x16<Self> {
10331        let (a0, a1) = self.split_u32x16(a);
10332        let (b0, b1) = self.split_u32x16(b);
10333        let (c0, c1) = self.split_u32x16(c);
10334        self.combine_u32x8(self.clamp_u32x8(a0, b0, c0), self.clamp_u32x8(a1, b1, c1))
10335    }
10336    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
10337    #[inline(always)]
10338    fn simd_eq_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> mask32x16<Self> {
10339        let (a0, a1) = self.split_u32x16(a);
10340        let (b0, b1) = self.split_u32x16(b);
10341        self.combine_mask32x8(self.simd_eq_u32x8(a0, b0), self.simd_eq_u32x8(a1, b1))
10342    }
10343    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
10344    #[inline(always)]
10345    fn simd_ne_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> mask32x16<Self> {
10346        self.not_mask32x16(self.simd_eq_u32x16(a, b))
10347    }
10348    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
10349    #[inline(always)]
10350    fn simd_lt_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> mask32x16<Self> {
10351        let (a0, a1) = self.split_u32x16(a);
10352        let (b0, b1) = self.split_u32x16(b);
10353        self.combine_mask32x8(self.simd_lt_u32x8(a0, b0), self.simd_lt_u32x8(a1, b1))
10354    }
10355    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
10356    #[inline(always)]
10357    fn simd_le_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> mask32x16<Self> {
10358        let (a0, a1) = self.split_u32x16(a);
10359        let (b0, b1) = self.split_u32x16(b);
10360        self.combine_mask32x8(self.simd_le_u32x8(a0, b0), self.simd_le_u32x8(a1, b1))
10361    }
10362    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
10363    #[inline(always)]
10364    fn simd_ge_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> mask32x16<Self> {
10365        self.simd_le_u32x16(b, a)
10366    }
10367    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
10368    #[inline(always)]
10369    fn simd_gt_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> mask32x16<Self> {
10370        self.simd_lt_u32x16(b, a)
10371    }
10372    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
10373    #[inline(always)]
10374    fn zip_low_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
10375        let (a0, _) = self.split_u32x16(a);
10376        let (b0, _) = self.split_u32x16(b);
10377        self.combine_u32x8(self.zip_low_u32x8(a0, b0), self.zip_high_u32x8(a0, b0))
10378    }
10379    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
10380    #[inline(always)]
10381    fn zip_high_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
10382        let (_, a1) = self.split_u32x16(a);
10383        let (_, b1) = self.split_u32x16(b);
10384        self.combine_u32x8(self.zip_low_u32x8(a1, b1), self.zip_high_u32x8(a1, b1))
10385    }
10386    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
10387    #[inline(always)]
10388    fn unzip_low_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
10389        let (a0, a1) = self.split_u32x16(a);
10390        let (b0, b1) = self.split_u32x16(b);
10391        self.combine_u32x8(self.unzip_low_u32x8(a0, a1), self.unzip_low_u32x8(b0, b1))
10392    }
10393    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
10394    #[inline(always)]
10395    fn unzip_high_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u32x16<Self> {
10396        let (a0, a1) = self.split_u32x16(a);
10397        let (b0, b1) = self.split_u32x16(b);
10398        self.combine_u32x8(self.unzip_high_u32x8(a0, a1), self.unzip_high_u32x8(b0, b1))
10399    }
10400    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
10401    #[inline(always)]
10402    fn interleave_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> (u32x16<Self>, u32x16<Self>) {
10403        let (a0, a1) = self.split_u32x16(a);
10404        let (b0, b1) = self.split_u32x16(b);
10405        let lo_lo = self.zip_low_u32x8(a0, b0);
10406        let lo_hi = self.zip_high_u32x8(a0, b0);
10407        let hi_lo = self.zip_low_u32x8(a1, b1);
10408        let hi_hi = self.zip_high_u32x8(a1, b1);
10409        (
10410            self.combine_u32x8(lo_lo, lo_hi),
10411            self.combine_u32x8(hi_lo, hi_hi),
10412        )
10413    }
10414    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
10415    #[inline(always)]
10416    fn deinterleave_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> (u32x16<Self>, u32x16<Self>) {
10417        let (a0, a1) = self.split_u32x16(a);
10418        let (b0, b1) = self.split_u32x16(b);
10419        let lo_even = self.unzip_low_u32x8(a0, a1);
10420        let lo_odd = self.unzip_high_u32x8(a0, a1);
10421        let hi_even = self.unzip_low_u32x8(b0, b1);
10422        let hi_odd = self.unzip_high_u32x8(b0, b1);
10423        (
10424            self.combine_u32x8(lo_even, hi_even),
10425            self.combine_u32x8(lo_odd, hi_odd),
10426        )
10427    }
10428    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
10429    #[inline(always)]
10430    fn select_u32x16(self, a: mask32x16<Self>, b: u32x16<Self>, c: u32x16<Self>) -> u32x16<Self> {
10431        let (a0, a1) = self.split_mask32x16(a);
10432        let (b0, b1) = self.split_u32x16(b);
10433        let (c0, c1) = self.split_u32x16(c);
10434        self.combine_u32x8(self.select_u32x8(a0, b0, c0), self.select_u32x8(a1, b1, c1))
10435    }
10436    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
10437    fn split_u32x16(self, a: u32x16<Self>) -> (u32x8<Self>, u32x8<Self>);
10438    #[doc = "Widen every lane into two same-width vectors.\n\nThe first result contains the widened lower lanes and the second contains the widened upper lanes."]
10439    #[inline(always)]
10440    fn widen_u32x16(self, a: u32x16<Self>) -> (u64x8<Self>, u64x8<Self>) {
10441        let (a0, a1) = self.split_u32x16(a);
10442        let (a00, a01) = self.widen_u32x8(a0);
10443        let (a10, a11) = self.widen_u32x8(a1);
10444        (self.combine_u64x4(a00, a01), self.combine_u64x4(a10, a11))
10445    }
10446    #[doc = "Multiply corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
10447    #[inline(always)]
10448    fn widening_mul_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> (u64x8<Self>, u64x8<Self>) {
10449        let (a0, a1) = self.split_u32x16(a);
10450        let (b0, b1) = self.split_u32x16(b);
10451        let (low0, low1) = self.widening_mul_u32x8(a0, b0);
10452        let (high0, high1) = self.widening_mul_u32x8(a1, b1);
10453        (
10454            self.combine_u64x4(low0, low1),
10455            self.combine_u64x4(high0, high1),
10456        )
10457    }
10458    #[doc = "Add corresponding integer lanes exactly into twice-wide lanes. The first result contains the lower lanes and the second contains the upper lanes."]
10459    #[inline(always)]
10460    fn widening_add_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> (u64x8<Self>, u64x8<Self>) {
10461        let (a0, a1) = self.split_u32x16(a);
10462        let (b0, b1) = self.split_u32x16(b);
10463        let (low0, low1) = self.widening_add_u32x8(a0, b0);
10464        let (high0, high1) = self.widening_add_u32x8(a1, b1);
10465        (
10466            self.combine_u64x4(low0, low1),
10467            self.combine_u64x4(high0, high1),
10468        )
10469    }
10470    #[doc = "Add adjacent integer lanes exactly into twice-wide lanes.\n\nOutput lane `i` is `widen(a[2*i]) + widen(a[2*i+1])`. The result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. The sum cannot overflow the widened type.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` produces `[3, 7, 11, 15]`. See [`SimdIntWiden::pairwise_widening_add`] for supported types and examples."]
10471    #[inline(always)]
10472    fn pairwise_widening_add_u32x16(self, a: u32x16<Self>) -> u64x8<Self> {
10473        let (a0, a1) = self.split_u32x16(a);
10474        self.combine_u64x4(
10475            self.pairwise_widening_add_u32x8(a0),
10476            self.pairwise_widening_add_u32x8(a1),
10477        )
10478    }
10479    #[doc = "Multiply corresponding integer lanes exactly in the widened type, then sum adjacent pairs of products.\n\nThe result has half as many lanes, twice the lane width, and unchanged signedness and total bit width. Lane `i` is `widen(a[2*i]) * widen(b[2*i]) + widen(a[2*i+1]) * widen(b[2*i+1])`; addition wraps in the destination type, including in debug builds.\n\nFor example, `[1, 2, 3, 4, 5, 6, 7, 8]` and `[10, 20, 30, 40, 50, 60, 70, 80]` produce `[50, 250, 610, 1130]`. See [`SimdIntWiden::pairwise_dot_product`] for examples."]
10480    #[inline(always)]
10481    fn pairwise_dot_product_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u64x8<Self> {
10482        let (a0, a1) = self.split_u32x16(a);
10483        let (b0, b1) = self.split_u32x16(b);
10484        self.combine_u64x4(
10485            self.pairwise_dot_product_u32x8(a0, b0),
10486            self.pairwise_dot_product_u32x8(a1, b1),
10487        )
10488    }
10489    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
10490    #[inline(always)]
10491    fn narrow_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u16x32<Self> {
10492        let (a0, a1) = self.split_u32x16(a);
10493        let (b0, b1) = self.split_u32x16(b);
10494        self.combine_u16x16(self.narrow_u32x8(a0, a1), self.narrow_u32x8(b0, b1))
10495    }
10496    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
10497    #[inline(always)]
10498    fn saturating_narrow_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u16x32<Self> {
10499        let (a0, a1) = self.split_u32x16(a);
10500        let (b0, b1) = self.split_u32x16(b);
10501        self.combine_u16x16(
10502            self.saturating_narrow_u32x8(a0, a1),
10503            self.saturating_narrow_u32x8(b0, b1),
10504        )
10505    }
10506    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
10507    #[inline(always)]
10508    fn relaxed_narrow_u32x16(self, a: u32x16<Self>, b: u32x16<Self>) -> u16x32<Self> {
10509        let (a0, a1) = self.split_u32x16(a);
10510        let (b0, b1) = self.split_u32x16(b);
10511        self.combine_u16x16(
10512            self.relaxed_narrow_u32x8(a0, a1),
10513            self.relaxed_narrow_u32x8(b0, b1),
10514        )
10515    }
10516    #[doc = "Convert each unsigned 32-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
10517    #[inline(always)]
10518    fn cvt_f32_u32x16(self, a: u32x16<Self>) -> f32x16<Self> {
10519        let (a0, a1) = self.split_u32x16(a);
10520        self.combine_f32x8(self.cvt_f32_u32x8(a0), self.cvt_f32_u32x8(a1))
10521    }
10522    #[doc = "Create a SIMD mask with all lanes set from the given boolean value."]
10523    #[inline(always)]
10524    fn splat_mask32x16(self, val: bool) -> mask32x16<Self> {
10525        let half = self.splat_mask32x8(val);
10526        self.combine_mask32x8(half, half)
10527    }
10528    #[doc = "Create a SIMD mask from a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are ignored."]
10529    #[inline(always)]
10530    fn from_bitmask_mask32x16(self, bits: u64) -> mask32x16<Self> {
10531        let lo = self.from_bitmask_mask32x8(bits);
10532        let hi = self.from_bitmask_mask32x8(bits >> 8usize);
10533        self.combine_mask32x8(lo, hi)
10534    }
10535    #[doc = "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared."]
10536    #[inline(always)]
10537    fn to_bitmask_mask32x16(self, a: mask32x16<Self>) -> u64 {
10538        let (lo, hi) = self.split_mask32x16(a);
10539        let lo = self.to_bitmask_mask32x8(lo);
10540        let hi = self.to_bitmask_mask32x8(hi);
10541        lo | (hi << 8usize)
10542    }
10543    #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."]
10544    fn from_vector_mask32x16(self, vector: i32x16<Self>) -> mask32x16<Self>;
10545    #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."]
10546    fn to_vector_mask32x16(self, a: mask32x16<Self>) -> i32x16<Self>;
10547    #[doc = "Set one logical lane of a SIMD mask."]
10548    fn set_mask32x16(self, a: &mut mask32x16<Self>, index: usize, value: bool) -> ();
10549    #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
10550    fn rotate_elements_left_mask32x16<const OFFSET: usize>(
10551        self,
10552        a: mask32x16<Self>,
10553    ) -> mask32x16<Self>;
10554    #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
10555    fn rotate_elements_right_mask32x16<const OFFSET: usize>(
10556        self,
10557        a: mask32x16<Self>,
10558    ) -> mask32x16<Self>;
10559    #[doc = "Compute the logical AND of two masks."]
10560    #[inline(always)]
10561    fn and_mask32x16(self, a: mask32x16<Self>, b: mask32x16<Self>) -> mask32x16<Self> {
10562        let (a0, a1) = self.split_mask32x16(a);
10563        let (b0, b1) = self.split_mask32x16(b);
10564        self.combine_mask32x8(self.and_mask32x8(a0, b0), self.and_mask32x8(a1, b1))
10565    }
10566    #[doc = "Compute the logical OR of two masks."]
10567    #[inline(always)]
10568    fn or_mask32x16(self, a: mask32x16<Self>, b: mask32x16<Self>) -> mask32x16<Self> {
10569        let (a0, a1) = self.split_mask32x16(a);
10570        let (b0, b1) = self.split_mask32x16(b);
10571        self.combine_mask32x8(self.or_mask32x8(a0, b0), self.or_mask32x8(a1, b1))
10572    }
10573    #[doc = "Compute the logical XOR of two masks."]
10574    #[inline(always)]
10575    fn xor_mask32x16(self, a: mask32x16<Self>, b: mask32x16<Self>) -> mask32x16<Self> {
10576        let (a0, a1) = self.split_mask32x16(a);
10577        let (b0, b1) = self.split_mask32x16(b);
10578        self.combine_mask32x8(self.xor_mask32x8(a0, b0), self.xor_mask32x8(a1, b1))
10579    }
10580    #[doc = "Compute the logical NOT of the mask."]
10581    #[inline(always)]
10582    fn not_mask32x16(self, a: mask32x16<Self>) -> mask32x16<Self> {
10583        let (a0, a1) = self.split_mask32x16(a);
10584        self.combine_mask32x8(self.not_mask32x8(a0), self.not_mask32x8(a1))
10585    }
10586    #[doc = "Reverse the order of the mask's logical lanes."]
10587    #[inline(always)]
10588    fn reverse_mask32x16(self, a: mask32x16<Self>) -> mask32x16<Self> {
10589        let (a0, a1) = self.split_mask32x16(a);
10590        self.combine_mask32x8(self.reverse_mask32x8(a1), self.reverse_mask32x8(a0))
10591    }
10592    #[doc = "Select elements from `b` and `c` based on the mask operand `a`.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
10593    #[inline(always)]
10594    fn select_mask32x16(
10595        self,
10596        a: mask32x16<Self>,
10597        b: mask32x16<Self>,
10598        c: mask32x16<Self>,
10599    ) -> mask32x16<Self> {
10600        let (a0, a1) = self.split_mask32x16(a);
10601        let (b0, b1) = self.split_mask32x16(b);
10602        let (c0, c1) = self.split_mask32x16(c);
10603        self.combine_mask32x8(
10604            self.select_mask32x8(a0, b0, c0),
10605            self.select_mask32x8(a1, b1, c1),
10606        )
10607    }
10608    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
10609    #[inline(always)]
10610    fn simd_eq_mask32x16(self, a: mask32x16<Self>, b: mask32x16<Self>) -> mask32x16<Self> {
10611        let (a0, a1) = self.split_mask32x16(a);
10612        let (b0, b1) = self.split_mask32x16(b);
10613        self.combine_mask32x8(self.simd_eq_mask32x8(a0, b0), self.simd_eq_mask32x8(a1, b1))
10614    }
10615    #[doc = "Compare two masks element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
10616    #[inline(always)]
10617    fn simd_ne_mask32x16(self, a: mask32x16<Self>, b: mask32x16<Self>) -> mask32x16<Self> {
10618        self.not_mask32x16(self.simd_eq_mask32x16(a, b))
10619    }
10620    #[doc = "Returns true if any logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
10621    #[inline(always)]
10622    fn any_true_mask32x16(self, a: mask32x16<Self>) -> bool {
10623        let (a0, a1) = self.split_mask32x16(a);
10624        self.any_true_mask32x8(self.or_mask32x8(a0, a1))
10625    }
10626    #[doc = "Returns true if all logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
10627    #[inline(always)]
10628    fn all_true_mask32x16(self, a: mask32x16<Self>) -> bool {
10629        let (a0, a1) = self.split_mask32x16(a);
10630        self.all_true_mask32x8(self.and_mask32x8(a0, a1))
10631    }
10632    #[doc = "Returns true if any logical lanes in this mask are false.\n\nThis is logically equivalent to `!all_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
10633    #[inline(always)]
10634    fn any_false_mask32x16(self, a: mask32x16<Self>) -> bool {
10635        let (a0, a1) = self.split_mask32x16(a);
10636        self.any_false_mask32x8(self.and_mask32x8(a0, a1))
10637    }
10638    #[doc = "Returns true if all logical lanes in this mask are false.\n\nThis is logically equivalent to `!any_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
10639    #[inline(always)]
10640    fn all_false_mask32x16(self, a: mask32x16<Self>) -> bool {
10641        let (a0, a1) = self.split_mask32x16(a);
10642        self.all_false_mask32x8(self.or_mask32x8(a0, a1))
10643    }
10644    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
10645    fn split_mask32x16(self, a: mask32x16<Self>) -> (mask32x8<Self>, mask32x8<Self>);
10646    #[doc = "Widen each boolean lane into two masks of the same logical width, preserving its value.\n\nThe first result contains the lower lanes and the second contains the upper lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
10647    #[inline(always)]
10648    fn widen_mask32x16(self, a: mask32x16<Self>) -> (mask64x8<Self>, mask64x8<Self>) {
10649        let (a0, a1) = self.split_mask32x16(a);
10650        let (a00, a01) = self.widen_mask32x8(a0);
10651        let (a10, a11) = self.widen_mask32x8(a1);
10652        (
10653            self.combine_mask64x4(a00, a01),
10654            self.combine_mask64x4(a10, a11),
10655        )
10656    }
10657    #[doc = "Narrow each boolean lane of two masks and concatenate them into one mask of the same logical width, preserving each value.\n\n`a` supplies the lower result lanes and `b` supplies the upper result lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
10658    #[inline(always)]
10659    fn narrow_mask32x16(self, a: mask32x16<Self>, b: mask32x16<Self>) -> mask16x32<Self> {
10660        let (a0, a1) = self.split_mask32x16(a);
10661        let (b0, b1) = self.split_mask32x16(b);
10662        self.combine_mask16x16(self.narrow_mask32x8(a0, a1), self.narrow_mask32x8(b0, b1))
10663    }
10664    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
10665    #[inline(always)]
10666    fn abs_f64x8(self, a: f64x8<Self>) -> f64x8<Self> {
10667        let (a0, a1) = self.split_f64x8(a);
10668        self.combine_f64x4(self.abs_f64x4(a0), self.abs_f64x4(a1))
10669    }
10670    #[doc = "Create a SIMD vector with all elements set to the given value."]
10671    #[inline(always)]
10672    fn splat_f64x8(self, val: f64) -> f64x8<Self> {
10673        let half = self.splat_f64x4(val);
10674        self.combine_f64x4(half, half)
10675    }
10676    #[doc = "Reverse the order of the vector's elements."]
10677    #[inline(always)]
10678    fn reverse_f64x8(self, a: f64x8<Self>) -> f64x8<Self> {
10679        let (a0, a1) = self.split_f64x8(a);
10680        self.combine_f64x4(self.reverse_f64x4(a1), self.reverse_f64x4(a0))
10681    }
10682    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
10683    fn slide_f64x8<const SHIFT: usize>(self, a: f64x8<Self>, b: f64x8<Self>) -> f64x8<Self>;
10684    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
10685    #[inline(always)]
10686    fn slide_within_blocks_f64x8<const SHIFT: usize>(
10687        self,
10688        a: f64x8<Self>,
10689        b: f64x8<Self>,
10690    ) -> f64x8<Self> {
10691        let (a0, a1) = self.split_f64x8(a);
10692        let (b0, b1) = self.split_f64x8(b);
10693        self.combine_f64x4(
10694            self.slide_within_blocks_f64x4::<SHIFT>(a0, b0),
10695            self.slide_within_blocks_f64x4::<SHIFT>(a1, b1),
10696        )
10697    }
10698    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
10699    #[inline(always)]
10700    fn swizzle_dyn_within_blocks_f64x8(self, a: f64x8<Self>, indices: u8x64<Self>) -> f64x8<Self> {
10701        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x64(Bytes::to_bytes(a), indices))
10702    }
10703    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
10704    #[inline(always)]
10705    fn swizzle_dyn_f64x8(self, a: f64x8<Self>, indices: u8x64<Self>) -> f64x8<Self> {
10706        Bytes::from_bytes(self.swizzle_dyn_u8x64(Bytes::to_bytes(a), indices))
10707    }
10708    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
10709    #[inline(always)]
10710    fn swizzle_dyn_precise_f64x8(self, a: f64x8<Self>, indices: u8x64<Self>) -> f64x8<Self> {
10711        Bytes::from_bytes(self.swizzle_dyn_precise_u8x64(Bytes::to_bytes(a), indices))
10712    }
10713    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
10714    #[inline(always)]
10715    fn concat_swizzle_dyn_f64x8(
10716        self,
10717        a: f64x8<Self>,
10718        b: f64x8<Self>,
10719        indices: u8x64<Self>,
10720    ) -> f64x8<Self> {
10721        Bytes::from_bytes(self.concat_swizzle_dyn_u8x64(
10722            Bytes::to_bytes(a),
10723            Bytes::to_bytes(b),
10724            indices,
10725        ))
10726    }
10727    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
10728    #[inline(always)]
10729    fn concat_swizzle_dyn_precise_f64x8(
10730        self,
10731        a: f64x8<Self>,
10732        b: f64x8<Self>,
10733        indices: u8x64<Self>,
10734    ) -> f64x8<Self> {
10735        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x64(
10736            Bytes::to_bytes(a),
10737            Bytes::to_bytes(b),
10738            indices,
10739        ))
10740    }
10741    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
10742    fn compress_f64x8(self, values: f64x8<Self>, mask: mask64x8<Self>) -> f64x8<Self>;
10743    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
10744    fn compress_merge_f64x8(
10745        self,
10746        values: f64x8<Self>,
10747        mask: mask64x8<Self>,
10748        merge: f64x8<Self>,
10749    ) -> f64x8<Self>;
10750    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
10751    fn expand_f64x8(self, values: f64x8<Self>, mask: mask64x8<Self>) -> f64x8<Self>;
10752    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
10753    fn expand_merge_f64x8(
10754        self,
10755        values: f64x8<Self>,
10756        mask: mask64x8<Self>,
10757        merge: f64x8<Self>,
10758    ) -> f64x8<Self>;
10759    #[doc = "Negate each element of the vector."]
10760    #[inline(always)]
10761    fn neg_f64x8(self, a: f64x8<Self>) -> f64x8<Self> {
10762        let (a0, a1) = self.split_f64x8(a);
10763        self.combine_f64x4(self.neg_f64x4(a0), self.neg_f64x4(a1))
10764    }
10765    #[doc = "Compute the square root of each element.\n\nNegative elements other than `-0.0` will become NaN."]
10766    #[inline(always)]
10767    fn sqrt_f64x8(self, a: f64x8<Self>) -> f64x8<Self> {
10768        let (a0, a1) = self.split_f64x8(a);
10769        self.combine_f64x4(self.sqrt_f64x4(a0), self.sqrt_f64x4(a1))
10770    }
10771    #[doc = "Compute an approximate reciprocal (`1. / x`) for each element.\n\nThis uses a fast hardware estimate where available, and falls back to exact division otherwise.\n\nOn x86 for `f32`, this has a relative error less than `1.5 × 2^-12`. On `AArch64` (`f32` and `f64`), this has a relative error less than `2^-8`. The precision of this operation may change as new platform support is added."]
10772    #[inline(always)]
10773    fn approximate_recip_f64x8(self, a: f64x8<Self>) -> f64x8<Self> {
10774        let (a0, a1) = self.split_f64x8(a);
10775        self.combine_f64x4(
10776            self.approximate_recip_f64x4(a0),
10777            self.approximate_recip_f64x4(a1),
10778        )
10779    }
10780    #[doc = "Add two vectors element-wise."]
10781    #[inline(always)]
10782    fn add_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> f64x8<Self> {
10783        let (a0, a1) = self.split_f64x8(a);
10784        let (b0, b1) = self.split_f64x8(b);
10785        self.combine_f64x4(self.add_f64x4(a0, b0), self.add_f64x4(a1, b1))
10786    }
10787    #[doc = "Subtract two vectors element-wise."]
10788    #[inline(always)]
10789    fn sub_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> f64x8<Self> {
10790        let (a0, a1) = self.split_f64x8(a);
10791        let (b0, b1) = self.split_f64x8(b);
10792        self.combine_f64x4(self.sub_f64x4(a0, b0), self.sub_f64x4(a1, b1))
10793    }
10794    #[doc = "Multiply two vectors element-wise."]
10795    #[inline(always)]
10796    fn mul_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> f64x8<Self> {
10797        let (a0, a1) = self.split_f64x8(a);
10798        let (b0, b1) = self.split_f64x8(b);
10799        self.combine_f64x4(self.mul_f64x4(a0, b0), self.mul_f64x4(a1, b1))
10800    }
10801    #[doc = "Divide two vectors element-wise."]
10802    #[inline(always)]
10803    fn div_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> f64x8<Self> {
10804        let (a0, a1) = self.split_f64x8(a);
10805        let (b0, b1) = self.split_f64x8(b);
10806        self.combine_f64x4(self.div_f64x4(a0, b0), self.div_f64x4(a1, b1))
10807    }
10808    #[doc = "Return a vector with the magnitude of `a` and the sign of `b` for each element.\n\nThis operation copies the sign bit, so if an input element is NaN, the output element will be a NaN with the same payload and a copied sign bit."]
10809    #[inline(always)]
10810    fn copysign_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> f64x8<Self> {
10811        let (a0, a1) = self.split_f64x8(a);
10812        let (b0, b1) = self.split_f64x8(b);
10813        self.combine_f64x4(self.copysign_f64x4(a0, b0), self.copysign_f64x4(a1, b1))
10814    }
10815    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
10816    #[inline(always)]
10817    fn reduce_max_f64x8(self, a: f64x8<Self>) -> f64 {
10818        let (a0, a1) = self.split_f64x8(a);
10819        self.reduce_max_f64x4(self.max_f64x4(a0, a1))
10820    }
10821    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
10822    #[inline(always)]
10823    fn reduce_min_f64x8(self, a: f64x8<Self>) -> f64 {
10824        let (a0, a1) = self.split_f64x8(a);
10825        self.reduce_min_f64x4(self.min_f64x4(a0, a1))
10826    }
10827    #[doc = "Return the maximum element in the vector, ignoring quiet NaNs.\n\nFor integer vectors, this operation is the same as `reduce_max`.\n\nFor floating-point vectors, quiet NaNs are ignored. If there is at least one numeric lane, this returns the true maximum of the numeric lanes. If all lanes are quiet NaNs, this returns NaN, with an unspecified payload and sign.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned.\n\nIf any lane is a *signaling* NaN, the result is fully non-deterministic: it may be NaN or a numeric lane and is not guaranteed to be the true maximum.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
10828    #[inline(always)]
10829    fn reduce_max_precise_f64x8(self, a: f64x8<Self>) -> f64 {
10830        let (a0, a1) = self.split_f64x8(a);
10831        self.reduce_max_precise_f64x4(self.max_precise_f64x4(a0, a1))
10832    }
10833    #[doc = "Return the minimum element in the vector, ignoring quiet NaNs.\n\nFor integer vectors, this operation is the same as `reduce_min`.\n\nFor floating-point vectors, quiet NaNs are ignored. If there is at least one numeric lane, this returns the true minimum of the numeric lanes. If all lanes are quiet NaNs, this returns NaN, with an unspecified payload and sign.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned.\n\nIf any lane is a *signaling* NaN, the result is fully non-deterministic: it may be NaN or a numeric lane and is not guaranteed to be the true minimum.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
10834    #[inline(always)]
10835    fn reduce_min_precise_f64x8(self, a: f64x8<Self>) -> f64 {
10836        let (a0, a1) = self.split_f64x8(a);
10837        self.reduce_min_precise_f64x4(self.min_precise_f64x4(a0, a1))
10838    }
10839    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
10840    #[inline(always)]
10841    fn reduce_sum_f64x8(self, a: f64x8<Self>) -> f64 {
10842        let (a0, a1) = self.split_f64x8(a);
10843        self.reduce_sum_f64x4(self.add_f64x4(a0, a1))
10844    }
10845    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
10846    #[inline(always)]
10847    fn reduce_product_f64x8(self, a: f64x8<Self>) -> f64 {
10848        let (a0, a1) = self.split_f64x8(a);
10849        self.reduce_product_f64x4(self.mul_f64x4(a0, a1))
10850    }
10851    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
10852    #[inline(always)]
10853    fn max_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> f64x8<Self> {
10854        let (a0, a1) = self.split_f64x8(a);
10855        let (b0, b1) = self.split_f64x8(b);
10856        self.combine_f64x4(self.max_f64x4(a0, b0), self.max_f64x4(a1, b1))
10857    }
10858    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
10859    #[inline(always)]
10860    fn min_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> f64x8<Self> {
10861        let (a0, a1) = self.split_f64x8(a);
10862        let (b0, b1) = self.split_f64x8(b);
10863        self.combine_f64x4(self.min_f64x4(a0, b0), self.min_f64x4(a1, b1))
10864    }
10865    #[doc = "Return the element-wise maximum of two vectors.\n\nFor integer vectors, this operation is the same as `max`.\n\nFor floating-point vectors, if one operand is a quiet NaN and the other is not, this operation will choose the non-NaN operand.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\nIf a floating-point operand is a *signaling* NaN, the result is not just implementation-defined, but fully non-deterministic: it may be either NaN or the non-NaN operand.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
10866    #[inline(always)]
10867    fn max_precise_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> f64x8<Self> {
10868        let (a0, a1) = self.split_f64x8(a);
10869        let (b0, b1) = self.split_f64x8(b);
10870        self.combine_f64x4(
10871            self.max_precise_f64x4(a0, b0),
10872            self.max_precise_f64x4(a1, b1),
10873        )
10874    }
10875    #[doc = "Return the element-wise minimum of two vectors.\n\nFor integer vectors, this operation is the same as `min`.\n\nFor floating-point vectors, if one operand is a quiet NaN and the other is not, this operation will choose the non-NaN operand.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\nIf a floating-point operand is a *signaling* NaN, the result is not just implementation-defined, but fully non-deterministic: it may be either NaN or the non-NaN operand.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
10876    #[inline(always)]
10877    fn min_precise_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> f64x8<Self> {
10878        let (a0, a1) = self.split_f64x8(a);
10879        let (b0, b1) = self.split_f64x8(b);
10880        self.combine_f64x4(
10881            self.min_precise_f64x4(a0, b0),
10882            self.min_precise_f64x4(a1, b1),
10883        )
10884    }
10885    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
10886    #[inline(always)]
10887    fn clamp_f64x8(self, a: f64x8<Self>, b: f64x8<Self>, c: f64x8<Self>) -> f64x8<Self> {
10888        let (a0, a1) = self.split_f64x8(a);
10889        let (b0, b1) = self.split_f64x8(b);
10890        let (c0, c1) = self.split_f64x8(c);
10891        self.combine_f64x4(self.clamp_f64x4(a0, b0, c0), self.clamp_f64x4(a1, b1, c1))
10892    }
10893    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
10894    #[inline(always)]
10895    fn simd_eq_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> mask64x8<Self> {
10896        let (a0, a1) = self.split_f64x8(a);
10897        let (b0, b1) = self.split_f64x8(b);
10898        self.combine_mask64x4(self.simd_eq_f64x4(a0, b0), self.simd_eq_f64x4(a1, b1))
10899    }
10900    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
10901    #[inline(always)]
10902    fn simd_ne_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> mask64x8<Self> {
10903        self.not_mask64x8(self.simd_eq_f64x8(a, b))
10904    }
10905    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
10906    #[inline(always)]
10907    fn simd_lt_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> mask64x8<Self> {
10908        let (a0, a1) = self.split_f64x8(a);
10909        let (b0, b1) = self.split_f64x8(b);
10910        self.combine_mask64x4(self.simd_lt_f64x4(a0, b0), self.simd_lt_f64x4(a1, b1))
10911    }
10912    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
10913    #[inline(always)]
10914    fn simd_le_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> mask64x8<Self> {
10915        let (a0, a1) = self.split_f64x8(a);
10916        let (b0, b1) = self.split_f64x8(b);
10917        self.combine_mask64x4(self.simd_le_f64x4(a0, b0), self.simd_le_f64x4(a1, b1))
10918    }
10919    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
10920    #[inline(always)]
10921    fn simd_ge_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> mask64x8<Self> {
10922        self.simd_le_f64x8(b, a)
10923    }
10924    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
10925    #[inline(always)]
10926    fn simd_gt_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> mask64x8<Self> {
10927        self.simd_lt_f64x8(b, a)
10928    }
10929    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
10930    #[inline(always)]
10931    fn zip_low_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> f64x8<Self> {
10932        let (a0, _) = self.split_f64x8(a);
10933        let (b0, _) = self.split_f64x8(b);
10934        self.combine_f64x4(self.zip_low_f64x4(a0, b0), self.zip_high_f64x4(a0, b0))
10935    }
10936    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
10937    #[inline(always)]
10938    fn zip_high_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> f64x8<Self> {
10939        let (_, a1) = self.split_f64x8(a);
10940        let (_, b1) = self.split_f64x8(b);
10941        self.combine_f64x4(self.zip_low_f64x4(a1, b1), self.zip_high_f64x4(a1, b1))
10942    }
10943    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
10944    #[inline(always)]
10945    fn unzip_low_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> f64x8<Self> {
10946        let (a0, a1) = self.split_f64x8(a);
10947        let (b0, b1) = self.split_f64x8(b);
10948        self.combine_f64x4(self.unzip_low_f64x4(a0, a1), self.unzip_low_f64x4(b0, b1))
10949    }
10950    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
10951    #[inline(always)]
10952    fn unzip_high_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> f64x8<Self> {
10953        let (a0, a1) = self.split_f64x8(a);
10954        let (b0, b1) = self.split_f64x8(b);
10955        self.combine_f64x4(self.unzip_high_f64x4(a0, a1), self.unzip_high_f64x4(b0, b1))
10956    }
10957    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
10958    #[inline(always)]
10959    fn interleave_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> (f64x8<Self>, f64x8<Self>) {
10960        let (a0, a1) = self.split_f64x8(a);
10961        let (b0, b1) = self.split_f64x8(b);
10962        let lo_lo = self.zip_low_f64x4(a0, b0);
10963        let lo_hi = self.zip_high_f64x4(a0, b0);
10964        let hi_lo = self.zip_low_f64x4(a1, b1);
10965        let hi_hi = self.zip_high_f64x4(a1, b1);
10966        (
10967            self.combine_f64x4(lo_lo, lo_hi),
10968            self.combine_f64x4(hi_lo, hi_hi),
10969        )
10970    }
10971    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
10972    #[inline(always)]
10973    fn deinterleave_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> (f64x8<Self>, f64x8<Self>) {
10974        let (a0, a1) = self.split_f64x8(a);
10975        let (b0, b1) = self.split_f64x8(b);
10976        let lo_even = self.unzip_low_f64x4(a0, a1);
10977        let lo_odd = self.unzip_high_f64x4(a0, a1);
10978        let hi_even = self.unzip_low_f64x4(b0, b1);
10979        let hi_odd = self.unzip_high_f64x4(b0, b1);
10980        (
10981            self.combine_f64x4(lo_even, hi_even),
10982            self.combine_f64x4(lo_odd, hi_odd),
10983        )
10984    }
10985    #[doc = "Compute `(a * b) + c` (fused multiply-add) for each element.\n\nDepending on platform support, the result may be computed with only one rounding error, or may be implemented as a regular multiply followed by an add, which will result in two rounding errors."]
10986    #[inline(always)]
10987    fn mul_add_f64x8(self, a: f64x8<Self>, b: f64x8<Self>, c: f64x8<Self>) -> f64x8<Self> {
10988        let (a0, a1) = self.split_f64x8(a);
10989        let (b0, b1) = self.split_f64x8(b);
10990        let (c0, c1) = self.split_f64x8(c);
10991        self.combine_f64x4(
10992            self.mul_add_f64x4(a0, b0, c0),
10993            self.mul_add_f64x4(a1, b1, c1),
10994        )
10995    }
10996    #[doc = "Compute `(a * b) + c` for each element, with a single rounding at the end.\n\nThe result is the infinite-precision product-plus-add rounded once to the element type. This may be substantially slower than `mul_add` on platforms without fused multiply-add instructions, including WebAssembly.\n\n# Precision guarantees\n\nThis function is **not** susceptible to [the bug](https://github.com/rust-lang/compiler-builtins/issues/1262) in Rust standard library and in musl libc that causes incorrect rounding for near-zero values on CPUs without hardware support for this operation.\n\nOn the tier-2 i586-* targets, this function is correct if and only if SSE2 is available on the CPU.\n\nThe exact `NaN` payloads as well as signaling `NaN`s are not preserved."]
10997    #[inline(always)]
10998    fn mul_add_precise_f64x8(self, a: f64x8<Self>, b: f64x8<Self>, c: f64x8<Self>) -> f64x8<Self> {
10999        let (a0, a1) = self.split_f64x8(a);
11000        let (b0, b1) = self.split_f64x8(b);
11001        let (c0, c1) = self.split_f64x8(c);
11002        self.combine_f64x4(
11003            self.mul_add_precise_f64x4(a0, b0, c0),
11004            self.mul_add_precise_f64x4(a1, b1, c1),
11005        )
11006    }
11007    #[doc = "Compute `(a * b) - c` (fused multiply-subtract) for each element.\n\nDepending on platform support, the result may be computed with only one rounding error, or may be implemented as a regular multiply followed by a subtract, which will result in two rounding errors."]
11008    #[inline(always)]
11009    fn mul_sub_f64x8(self, a: f64x8<Self>, b: f64x8<Self>, c: f64x8<Self>) -> f64x8<Self> {
11010        let (a0, a1) = self.split_f64x8(a);
11011        let (b0, b1) = self.split_f64x8(b);
11012        let (c0, c1) = self.split_f64x8(c);
11013        self.combine_f64x4(
11014            self.mul_sub_f64x4(a0, b0, c0),
11015            self.mul_sub_f64x4(a1, b1, c1),
11016        )
11017    }
11018    #[doc = "Compute `(a * b) - c` for each element, with a single rounding at the end.\n\nThe result is the infinite-precision product-minus-subtrahend rounded once to the element type. This may be substantially slower than `mul_sub` on platforms without fused multiply-add instructions, including WebAssembly.\n        # Precision guarantees\n\nThis function is **not** susceptible to [the bug](https://github.com/rust-lang/compiler-builtins/issues/1262) in Rust standard library and in musl libc that causes incorrect rounding for near-zero values on CPUs without hardware support for this operation.\n\nOn the tier-2 i586-* targets, this function is correct if and only if SSE2 is available on the CPU.\n\nThe exact `NaN` payloads as well as signaling `NaN`s are not preserved."]
11019    #[inline(always)]
11020    fn mul_sub_precise_f64x8(self, a: f64x8<Self>, b: f64x8<Self>, c: f64x8<Self>) -> f64x8<Self> {
11021        let (a0, a1) = self.split_f64x8(a);
11022        let (b0, b1) = self.split_f64x8(b);
11023        let (c0, c1) = self.split_f64x8(c);
11024        self.combine_f64x4(
11025            self.mul_sub_precise_f64x4(a0, b0, c0),
11026            self.mul_sub_precise_f64x4(a1, b1, c1),
11027        )
11028    }
11029    #[doc = "Return the largest integer less than or equal to each element, that is, round towards negative infinity."]
11030    #[inline(always)]
11031    fn floor_f64x8(self, a: f64x8<Self>) -> f64x8<Self> {
11032        let (a0, a1) = self.split_f64x8(a);
11033        self.combine_f64x4(self.floor_f64x4(a0), self.floor_f64x4(a1))
11034    }
11035    #[doc = "Return the smallest integer greater than or equal to each element, that is, round towards positive infinity."]
11036    #[inline(always)]
11037    fn ceil_f64x8(self, a: f64x8<Self>) -> f64x8<Self> {
11038        let (a0, a1) = self.split_f64x8(a);
11039        self.combine_f64x4(self.ceil_f64x4(a0), self.ceil_f64x4(a1))
11040    }
11041    #[doc = "Round each element to the nearest integer, with ties rounding to the nearest even integer."]
11042    #[inline(always)]
11043    fn round_ties_even_f64x8(self, a: f64x8<Self>) -> f64x8<Self> {
11044        let (a0, a1) = self.split_f64x8(a);
11045        self.combine_f64x4(
11046            self.round_ties_even_f64x4(a0),
11047            self.round_ties_even_f64x4(a1),
11048        )
11049    }
11050    #[doc = "Round each element to the nearest integer, with ties rounding away from zero.\n\n## Performance considerations\n\nOnly `AArch64` has native instructions for this operation. `round` has to be emulated on all other platforms which is around 2-4x slower than `round_ties_even`. Prefer using [`round_ties_even`](SimdFloat::round_ties_even) if possible."]
11051    #[inline(always)]
11052    fn round_f64x8(self, a: f64x8<Self>) -> f64x8<Self> {
11053        let (a0, a1) = self.split_f64x8(a);
11054        self.combine_f64x4(self.round_f64x4(a0), self.round_f64x4(a1))
11055    }
11056    #[doc = "Return the fractional part of each element.\n\nThis is equivalent to `a - a.trunc()`."]
11057    #[inline(always)]
11058    fn fract_f64x8(self, a: f64x8<Self>) -> f64x8<Self> {
11059        let (a0, a1) = self.split_f64x8(a);
11060        self.combine_f64x4(self.fract_f64x4(a0), self.fract_f64x4(a1))
11061    }
11062    #[doc = "Return the integer part of each element, rounding towards zero."]
11063    #[inline(always)]
11064    fn trunc_f64x8(self, a: f64x8<Self>) -> f64x8<Self> {
11065        let (a0, a1) = self.split_f64x8(a);
11066        self.combine_f64x4(self.trunc_f64x4(a0), self.trunc_f64x4(a1))
11067    }
11068    #[doc = "Converts radians to degrees.\n\nThe precision of this function is non-deterministic. This means it varies by platform, Rust version, and can even differ within the same execution from one invocation to the next."]
11069    #[inline(always)]
11070    fn to_degrees_f64x8(self, a: f64x8<Self>) -> f64x8<Self> {
11071        let (a0, a1) = self.split_f64x8(a);
11072        self.combine_f64x4(self.to_degrees_f64x4(a0), self.to_degrees_f64x4(a1))
11073    }
11074    #[doc = "Converts degrees to radians.\n\nThe precision of this function is non-deterministic. This means it varies by platform, Rust version, and can even differ within the same execution from one invocation to the next."]
11075    #[inline(always)]
11076    fn to_radians_f64x8(self, a: f64x8<Self>) -> f64x8<Self> {
11077        let (a0, a1) = self.split_f64x8(a);
11078        self.combine_f64x4(self.to_radians_f64x4(a0), self.to_radians_f64x4(a1))
11079    }
11080    #[doc = "Return a mask indicating which elements are NaN."]
11081    fn is_nan_f64x8(self, a: f64x8<Self>) -> mask64x8<Self>;
11082    #[doc = "Return a mask indicating which elements are positive or negative infinite."]
11083    fn is_infinite_f64x8(self, a: f64x8<Self>) -> mask64x8<Self>;
11084    #[doc = "Return a mask indicating which elements are neither infinite nor NaN."]
11085    fn is_finite_f64x8(self, a: f64x8<Self>) -> mask64x8<Self>;
11086    #[doc = "Return a mask indicating which elements are subnormal.\n\nThis classifies the stored bit pattern, even when floating-point operations treat subnormals as zero."]
11087    fn is_subnormal_f64x8(self, a: f64x8<Self>) -> mask64x8<Self>;
11088    #[doc = "Return a mask indicating which elements are neither zero, infinite, subnormal, or NaN."]
11089    fn is_normal_f64x8(self, a: f64x8<Self>) -> mask64x8<Self>;
11090    #[doc = "Return a mask indicating which elements have a positive sign, including `+0.0`, NaNs with positive sign bit and positive infinity.\n\nNaN inputs may produce an unexpected or non-portable result, see [`f32::is_sign_positive`] for details."]
11091    fn is_sign_positive_f64x8(self, a: f64x8<Self>) -> mask64x8<Self>;
11092    #[doc = "Return a mask indicating which elements have a negative sign, including `-0.0`, NaNs with negative sign bit and negative infinity.\n\nNaN inputs may produce an unexpected or non-portable result, see [`f32::is_sign_negative`] for details."]
11093    fn is_sign_negative_f64x8(self, a: f64x8<Self>) -> mask64x8<Self>;
11094    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
11095    #[inline(always)]
11096    fn select_f64x8(self, a: mask64x8<Self>, b: f64x8<Self>, c: f64x8<Self>) -> f64x8<Self> {
11097        let (a0, a1) = self.split_mask64x8(a);
11098        let (b0, b1) = self.split_f64x8(b);
11099        let (c0, c1) = self.split_f64x8(c);
11100        self.combine_f64x4(self.select_f64x4(a0, b0, c0), self.select_f64x4(a1, b1, c1))
11101    }
11102    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
11103    fn split_f64x8(self, a: f64x8<Self>) -> (f64x4<Self>, f64x4<Self>);
11104    #[doc = "Convert the lanes of two `f64` vectors to `f32` and concatenate them into one same-width vector.\n\nValues are rounded to the nearest representable `f32`, with ties resolved to even; overflow produces signed infinity.This is the same as the `as` operator, and follows the IEEE 754 narrowing behavior in round-to-even mode.\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
11105    #[inline(always)]
11106    fn narrow_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> f32x16<Self> {
11107        let (a0, a1) = self.split_f64x8(a);
11108        let (b0, b1) = self.split_f64x8(b);
11109        self.combine_f32x8(self.narrow_f64x4(a0, a1), self.narrow_f64x4(b0, b1))
11110    }
11111    #[doc = "Convert the lanes of two `f64` vectors to `f32` and concatenate them into one same-width vector.\n\nFor floating-point vectors this is identical to `narrow`, including its rounding and overflow behavior.\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
11112    #[inline(always)]
11113    fn saturating_narrow_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> f32x16<Self> {
11114        let (a0, a1) = self.split_f64x8(a);
11115        let (b0, b1) = self.split_f64x8(b);
11116        self.combine_f32x8(
11117            self.saturating_narrow_f64x4(a0, a1),
11118            self.saturating_narrow_f64x4(b0, b1),
11119        )
11120    }
11121    #[doc = "Convert the lanes of two `f64` vectors to `f32` and concatenate them into one same-width vector.\n\nFor floating-point vectors this is identical to `narrow`, including its rounding and overflow behavior.\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
11122    #[inline(always)]
11123    fn relaxed_narrow_f64x8(self, a: f64x8<Self>, b: f64x8<Self>) -> f32x16<Self> {
11124        let (a0, a1) = self.split_f64x8(a);
11125        let (b0, b1) = self.split_f64x8(b);
11126        self.combine_f32x8(
11127            self.relaxed_narrow_f64x4(a0, a1),
11128            self.relaxed_narrow_f64x4(b0, b1),
11129        )
11130    }
11131    #[doc = "Convert each floating-point element to an unsigned 64-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
11132    #[inline(always)]
11133    fn cvt_u64_f64x8(self, a: f64x8<Self>) -> u64x8<Self> {
11134        let (a0, a1) = self.split_f64x8(a);
11135        self.combine_u64x4(self.cvt_u64_f64x4(a0), self.cvt_u64_f64x4(a1))
11136    }
11137    #[doc = "Convert each floating-point element to an unsigned 64-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
11138    #[inline(always)]
11139    fn cvt_u64_precise_f64x8(self, a: f64x8<Self>) -> u64x8<Self> {
11140        let (a0, a1) = self.split_f64x8(a);
11141        self.combine_u64x4(
11142            self.cvt_u64_precise_f64x4(a0),
11143            self.cvt_u64_precise_f64x4(a1),
11144        )
11145    }
11146    #[doc = "Convert each floating-point element to a signed 64-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
11147    #[inline(always)]
11148    fn cvt_i64_f64x8(self, a: f64x8<Self>) -> i64x8<Self> {
11149        let (a0, a1) = self.split_f64x8(a);
11150        self.combine_i64x4(self.cvt_i64_f64x4(a0), self.cvt_i64_f64x4(a1))
11151    }
11152    #[doc = "Convert each floating-point element to a signed 64-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
11153    #[inline(always)]
11154    fn cvt_i64_precise_f64x8(self, a: f64x8<Self>) -> i64x8<Self> {
11155        let (a0, a1) = self.split_f64x8(a);
11156        self.combine_i64x4(
11157            self.cvt_i64_precise_f64x4(a0),
11158            self.cvt_i64_precise_f64x4(a1),
11159        )
11160    }
11161    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
11162    #[inline(always)]
11163    fn abs_i64x8(self, a: i64x8<Self>) -> i64x8<Self> {
11164        let (a0, a1) = self.split_i64x8(a);
11165        self.combine_i64x4(self.abs_i64x4(a0), self.abs_i64x4(a1))
11166    }
11167    #[doc = "Create a SIMD vector with all elements set to the given value."]
11168    #[inline(always)]
11169    fn splat_i64x8(self, val: i64) -> i64x8<Self> {
11170        let half = self.splat_i64x4(val);
11171        self.combine_i64x4(half, half)
11172    }
11173    #[doc = "Reverse the order of the vector's elements."]
11174    #[inline(always)]
11175    fn reverse_i64x8(self, a: i64x8<Self>) -> i64x8<Self> {
11176        let (a0, a1) = self.split_i64x8(a);
11177        self.combine_i64x4(self.reverse_i64x4(a1), self.reverse_i64x4(a0))
11178    }
11179    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
11180    fn slide_i64x8<const SHIFT: usize>(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self>;
11181    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
11182    #[inline(always)]
11183    fn slide_within_blocks_i64x8<const SHIFT: usize>(
11184        self,
11185        a: i64x8<Self>,
11186        b: i64x8<Self>,
11187    ) -> i64x8<Self> {
11188        let (a0, a1) = self.split_i64x8(a);
11189        let (b0, b1) = self.split_i64x8(b);
11190        self.combine_i64x4(
11191            self.slide_within_blocks_i64x4::<SHIFT>(a0, b0),
11192            self.slide_within_blocks_i64x4::<SHIFT>(a1, b1),
11193        )
11194    }
11195    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
11196    #[inline(always)]
11197    fn swizzle_dyn_within_blocks_i64x8(self, a: i64x8<Self>, indices: u8x64<Self>) -> i64x8<Self> {
11198        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x64(Bytes::to_bytes(a), indices))
11199    }
11200    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
11201    #[inline(always)]
11202    fn swizzle_dyn_i64x8(self, a: i64x8<Self>, indices: u8x64<Self>) -> i64x8<Self> {
11203        Bytes::from_bytes(self.swizzle_dyn_u8x64(Bytes::to_bytes(a), indices))
11204    }
11205    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
11206    #[inline(always)]
11207    fn swizzle_dyn_precise_i64x8(self, a: i64x8<Self>, indices: u8x64<Self>) -> i64x8<Self> {
11208        Bytes::from_bytes(self.swizzle_dyn_precise_u8x64(Bytes::to_bytes(a), indices))
11209    }
11210    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
11211    #[inline(always)]
11212    fn concat_swizzle_dyn_i64x8(
11213        self,
11214        a: i64x8<Self>,
11215        b: i64x8<Self>,
11216        indices: u8x64<Self>,
11217    ) -> i64x8<Self> {
11218        Bytes::from_bytes(self.concat_swizzle_dyn_u8x64(
11219            Bytes::to_bytes(a),
11220            Bytes::to_bytes(b),
11221            indices,
11222        ))
11223    }
11224    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
11225    #[inline(always)]
11226    fn concat_swizzle_dyn_precise_i64x8(
11227        self,
11228        a: i64x8<Self>,
11229        b: i64x8<Self>,
11230        indices: u8x64<Self>,
11231    ) -> i64x8<Self> {
11232        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x64(
11233            Bytes::to_bytes(a),
11234            Bytes::to_bytes(b),
11235            indices,
11236        ))
11237    }
11238    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
11239    fn compress_i64x8(self, values: i64x8<Self>, mask: mask64x8<Self>) -> i64x8<Self>;
11240    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
11241    fn compress_merge_i64x8(
11242        self,
11243        values: i64x8<Self>,
11244        mask: mask64x8<Self>,
11245        merge: i64x8<Self>,
11246    ) -> i64x8<Self>;
11247    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
11248    fn expand_i64x8(self, values: i64x8<Self>, mask: mask64x8<Self>) -> i64x8<Self>;
11249    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
11250    fn expand_merge_i64x8(
11251        self,
11252        values: i64x8<Self>,
11253        mask: mask64x8<Self>,
11254        merge: i64x8<Self>,
11255    ) -> i64x8<Self>;
11256    #[doc = "Return the number of ones in the binary representation of each element."]
11257    #[inline(always)]
11258    fn count_ones_i64x8(self, a: i64x8<Self>) -> i64x8<Self> {
11259        let (a0, a1) = self.split_i64x8(a);
11260        self.combine_i64x4(self.count_ones_i64x4(a0), self.count_ones_i64x4(a1))
11261    }
11262    #[doc = "Return the number of zeros in the binary representation of each element."]
11263    #[inline(always)]
11264    fn count_zeros_i64x8(self, a: i64x8<Self>) -> i64x8<Self> {
11265        let (a0, a1) = self.split_i64x8(a);
11266        self.combine_i64x4(self.count_zeros_i64x4(a0), self.count_zeros_i64x4(a1))
11267    }
11268    #[doc = "Add two vectors element-wise, wrapping on overflow."]
11269    #[inline(always)]
11270    fn add_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
11271        let (a0, a1) = self.split_i64x8(a);
11272        let (b0, b1) = self.split_i64x8(b);
11273        self.combine_i64x4(self.add_i64x4(a0, b0), self.add_i64x4(a1, b1))
11274    }
11275    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
11276    #[inline(always)]
11277    fn saturating_add_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
11278        let (a0, a1) = self.split_i64x8(a);
11279        let (b0, b1) = self.split_i64x8(b);
11280        self.combine_i64x4(
11281            self.saturating_add_i64x4(a0, b0),
11282            self.saturating_add_i64x4(a1, b1),
11283        )
11284    }
11285    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
11286    #[inline(always)]
11287    fn sub_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
11288        let (a0, a1) = self.split_i64x8(a);
11289        let (b0, b1) = self.split_i64x8(b);
11290        self.combine_i64x4(self.sub_i64x4(a0, b0), self.sub_i64x4(a1, b1))
11291    }
11292    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
11293    #[inline(always)]
11294    fn saturating_sub_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
11295        let (a0, a1) = self.split_i64x8(a);
11296        let (b0, b1) = self.split_i64x8(b);
11297        self.combine_i64x4(
11298            self.saturating_sub_i64x4(a0, b0),
11299            self.saturating_sub_i64x4(a1, b1),
11300        )
11301    }
11302    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
11303    #[inline(always)]
11304    fn mul_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
11305        let (a0, a1) = self.split_i64x8(a);
11306        let (b0, b1) = self.split_i64x8(b);
11307        self.combine_i64x4(self.mul_i64x4(a0, b0), self.mul_i64x4(a1, b1))
11308    }
11309    #[doc = "Compute the bitwise AND of two vectors."]
11310    #[inline(always)]
11311    fn and_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
11312        let (a0, a1) = self.split_i64x8(a);
11313        let (b0, b1) = self.split_i64x8(b);
11314        self.combine_i64x4(self.and_i64x4(a0, b0), self.and_i64x4(a1, b1))
11315    }
11316    #[doc = "Compute the bitwise OR of two vectors."]
11317    #[inline(always)]
11318    fn or_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
11319        let (a0, a1) = self.split_i64x8(a);
11320        let (b0, b1) = self.split_i64x8(b);
11321        self.combine_i64x4(self.or_i64x4(a0, b0), self.or_i64x4(a1, b1))
11322    }
11323    #[doc = "Compute the bitwise XOR of two vectors."]
11324    #[inline(always)]
11325    fn xor_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
11326        let (a0, a1) = self.split_i64x8(a);
11327        let (b0, b1) = self.split_i64x8(b);
11328        self.combine_i64x4(self.xor_i64x4(a0, b0), self.xor_i64x4(a1, b1))
11329    }
11330    #[doc = "Compute the bitwise NOT of the vector."]
11331    #[inline(always)]
11332    fn not_i64x8(self, a: i64x8<Self>) -> i64x8<Self> {
11333        let (a0, a1) = self.split_i64x8(a);
11334        self.combine_i64x4(self.not_i64x4(a0), self.not_i64x4(a1))
11335    }
11336    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
11337    #[inline(always)]
11338    fn shl_i64x8(self, a: i64x8<Self>, shift: u32) -> i64x8<Self> {
11339        let (a0, a1) = self.split_i64x8(a);
11340        self.combine_i64x4(self.shl_i64x4(a0, shift), self.shl_i64x4(a1, shift))
11341    }
11342    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
11343    #[inline(always)]
11344    fn shlv_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
11345        let (a0, a1) = self.split_i64x8(a);
11346        let (b0, b1) = self.split_i64x8(b);
11347        self.combine_i64x4(self.shlv_i64x4(a0, b0), self.shlv_i64x4(a1, b1))
11348    }
11349    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
11350    #[inline(always)]
11351    fn shr_i64x8(self, a: i64x8<Self>, shift: u32) -> i64x8<Self> {
11352        let (a0, a1) = self.split_i64x8(a);
11353        self.combine_i64x4(self.shr_i64x4(a0, shift), self.shr_i64x4(a1, shift))
11354    }
11355    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
11356    #[inline(always)]
11357    fn shrv_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
11358        let (a0, a1) = self.split_i64x8(a);
11359        let (b0, b1) = self.split_i64x8(b);
11360        self.combine_i64x4(self.shrv_i64x4(a0, b0), self.shrv_i64x4(a1, b1))
11361    }
11362    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
11363    #[inline(always)]
11364    fn reduce_max_i64x8(self, a: i64x8<Self>) -> i64 {
11365        let (a0, a1) = self.split_i64x8(a);
11366        self.reduce_max_i64x4(self.max_i64x4(a0, a1))
11367    }
11368    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
11369    #[inline(always)]
11370    fn reduce_min_i64x8(self, a: i64x8<Self>) -> i64 {
11371        let (a0, a1) = self.split_i64x8(a);
11372        self.reduce_min_i64x4(self.min_i64x4(a0, a1))
11373    }
11374    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
11375    #[inline(always)]
11376    fn reduce_sum_i64x8(self, a: i64x8<Self>) -> i64 {
11377        let (a0, a1) = self.split_i64x8(a);
11378        self.reduce_sum_i64x4(self.add_i64x4(a0, a1))
11379    }
11380    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
11381    #[inline(always)]
11382    fn reduce_product_i64x8(self, a: i64x8<Self>) -> i64 {
11383        let (a0, a1) = self.split_i64x8(a);
11384        self.reduce_product_i64x4(self.mul_i64x4(a0, a1))
11385    }
11386    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
11387    #[inline(always)]
11388    fn max_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
11389        let (a0, a1) = self.split_i64x8(a);
11390        let (b0, b1) = self.split_i64x8(b);
11391        self.combine_i64x4(self.max_i64x4(a0, b0), self.max_i64x4(a1, b1))
11392    }
11393    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
11394    #[inline(always)]
11395    fn min_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
11396        let (a0, a1) = self.split_i64x8(a);
11397        let (b0, b1) = self.split_i64x8(b);
11398        self.combine_i64x4(self.min_i64x4(a0, b0), self.min_i64x4(a1, b1))
11399    }
11400    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
11401    #[inline(always)]
11402    fn clamp_i64x8(self, a: i64x8<Self>, b: i64x8<Self>, c: i64x8<Self>) -> i64x8<Self> {
11403        let (a0, a1) = self.split_i64x8(a);
11404        let (b0, b1) = self.split_i64x8(b);
11405        let (c0, c1) = self.split_i64x8(c);
11406        self.combine_i64x4(self.clamp_i64x4(a0, b0, c0), self.clamp_i64x4(a1, b1, c1))
11407    }
11408    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
11409    #[inline(always)]
11410    fn simd_eq_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> mask64x8<Self> {
11411        let (a0, a1) = self.split_i64x8(a);
11412        let (b0, b1) = self.split_i64x8(b);
11413        self.combine_mask64x4(self.simd_eq_i64x4(a0, b0), self.simd_eq_i64x4(a1, b1))
11414    }
11415    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
11416    #[inline(always)]
11417    fn simd_ne_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> mask64x8<Self> {
11418        self.not_mask64x8(self.simd_eq_i64x8(a, b))
11419    }
11420    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
11421    #[inline(always)]
11422    fn simd_lt_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> mask64x8<Self> {
11423        let (a0, a1) = self.split_i64x8(a);
11424        let (b0, b1) = self.split_i64x8(b);
11425        self.combine_mask64x4(self.simd_lt_i64x4(a0, b0), self.simd_lt_i64x4(a1, b1))
11426    }
11427    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
11428    #[inline(always)]
11429    fn simd_le_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> mask64x8<Self> {
11430        let (a0, a1) = self.split_i64x8(a);
11431        let (b0, b1) = self.split_i64x8(b);
11432        self.combine_mask64x4(self.simd_le_i64x4(a0, b0), self.simd_le_i64x4(a1, b1))
11433    }
11434    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
11435    #[inline(always)]
11436    fn simd_ge_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> mask64x8<Self> {
11437        self.simd_le_i64x8(b, a)
11438    }
11439    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
11440    #[inline(always)]
11441    fn simd_gt_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> mask64x8<Self> {
11442        self.simd_lt_i64x8(b, a)
11443    }
11444    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
11445    #[inline(always)]
11446    fn zip_low_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
11447        let (a0, _) = self.split_i64x8(a);
11448        let (b0, _) = self.split_i64x8(b);
11449        self.combine_i64x4(self.zip_low_i64x4(a0, b0), self.zip_high_i64x4(a0, b0))
11450    }
11451    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
11452    #[inline(always)]
11453    fn zip_high_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
11454        let (_, a1) = self.split_i64x8(a);
11455        let (_, b1) = self.split_i64x8(b);
11456        self.combine_i64x4(self.zip_low_i64x4(a1, b1), self.zip_high_i64x4(a1, b1))
11457    }
11458    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
11459    #[inline(always)]
11460    fn unzip_low_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
11461        let (a0, a1) = self.split_i64x8(a);
11462        let (b0, b1) = self.split_i64x8(b);
11463        self.combine_i64x4(self.unzip_low_i64x4(a0, a1), self.unzip_low_i64x4(b0, b1))
11464    }
11465    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
11466    #[inline(always)]
11467    fn unzip_high_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i64x8<Self> {
11468        let (a0, a1) = self.split_i64x8(a);
11469        let (b0, b1) = self.split_i64x8(b);
11470        self.combine_i64x4(self.unzip_high_i64x4(a0, a1), self.unzip_high_i64x4(b0, b1))
11471    }
11472    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
11473    #[inline(always)]
11474    fn interleave_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> (i64x8<Self>, i64x8<Self>) {
11475        let (a0, a1) = self.split_i64x8(a);
11476        let (b0, b1) = self.split_i64x8(b);
11477        let lo_lo = self.zip_low_i64x4(a0, b0);
11478        let lo_hi = self.zip_high_i64x4(a0, b0);
11479        let hi_lo = self.zip_low_i64x4(a1, b1);
11480        let hi_hi = self.zip_high_i64x4(a1, b1);
11481        (
11482            self.combine_i64x4(lo_lo, lo_hi),
11483            self.combine_i64x4(hi_lo, hi_hi),
11484        )
11485    }
11486    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
11487    #[inline(always)]
11488    fn deinterleave_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> (i64x8<Self>, i64x8<Self>) {
11489        let (a0, a1) = self.split_i64x8(a);
11490        let (b0, b1) = self.split_i64x8(b);
11491        let lo_even = self.unzip_low_i64x4(a0, a1);
11492        let lo_odd = self.unzip_high_i64x4(a0, a1);
11493        let hi_even = self.unzip_low_i64x4(b0, b1);
11494        let hi_odd = self.unzip_high_i64x4(b0, b1);
11495        (
11496            self.combine_i64x4(lo_even, hi_even),
11497            self.combine_i64x4(lo_odd, hi_odd),
11498        )
11499    }
11500    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
11501    #[inline(always)]
11502    fn select_i64x8(self, a: mask64x8<Self>, b: i64x8<Self>, c: i64x8<Self>) -> i64x8<Self> {
11503        let (a0, a1) = self.split_mask64x8(a);
11504        let (b0, b1) = self.split_i64x8(b);
11505        let (c0, c1) = self.split_i64x8(c);
11506        self.combine_i64x4(self.select_i64x4(a0, b0, c0), self.select_i64x4(a1, b1, c1))
11507    }
11508    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
11509    fn split_i64x8(self, a: i64x8<Self>) -> (i64x4<Self>, i64x4<Self>);
11510    #[doc = "Negate each element of the vector, wrapping on overflow."]
11511    #[inline(always)]
11512    fn neg_i64x8(self, a: i64x8<Self>) -> i64x8<Self> {
11513        let (a0, a1) = self.split_i64x8(a);
11514        self.combine_i64x4(self.neg_i64x4(a0), self.neg_i64x4(a1))
11515    }
11516    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
11517    #[inline(always)]
11518    fn narrow_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i32x16<Self> {
11519        let (a0, a1) = self.split_i64x8(a);
11520        let (b0, b1) = self.split_i64x8(b);
11521        self.combine_i32x8(self.narrow_i64x4(a0, a1), self.narrow_i64x4(b0, b1))
11522    }
11523    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
11524    #[inline(always)]
11525    fn saturating_narrow_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i32x16<Self> {
11526        let (a0, a1) = self.split_i64x8(a);
11527        let (b0, b1) = self.split_i64x8(b);
11528        self.combine_i32x8(
11529            self.saturating_narrow_i64x4(a0, a1),
11530            self.saturating_narrow_i64x4(b0, b1),
11531        )
11532    }
11533    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
11534    #[inline(always)]
11535    fn relaxed_narrow_i64x8(self, a: i64x8<Self>, b: i64x8<Self>) -> i32x16<Self> {
11536        let (a0, a1) = self.split_i64x8(a);
11537        let (b0, b1) = self.split_i64x8(b);
11538        self.combine_i32x8(
11539            self.relaxed_narrow_i64x4(a0, a1),
11540            self.relaxed_narrow_i64x4(b0, b1),
11541        )
11542    }
11543    #[doc = "Convert each signed 64-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
11544    #[inline(always)]
11545    fn cvt_f64_i64x8(self, a: i64x8<Self>) -> f64x8<Self> {
11546        let (a0, a1) = self.split_i64x8(a);
11547        self.combine_f64x4(self.cvt_f64_i64x4(a0), self.cvt_f64_i64x4(a1))
11548    }
11549    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
11550    #[inline(always)]
11551    fn abs_u64x8(self, a: u64x8<Self>) -> u64x8<Self> {
11552        a
11553    }
11554    #[doc = "Create a SIMD vector with all elements set to the given value."]
11555    #[inline(always)]
11556    fn splat_u64x8(self, val: u64) -> u64x8<Self> {
11557        let half = self.splat_u64x4(val);
11558        self.combine_u64x4(half, half)
11559    }
11560    #[doc = "Reverse the order of the vector's elements."]
11561    #[inline(always)]
11562    fn reverse_u64x8(self, a: u64x8<Self>) -> u64x8<Self> {
11563        let (a0, a1) = self.split_u64x8(a);
11564        self.combine_u64x4(self.reverse_u64x4(a1), self.reverse_u64x4(a0))
11565    }
11566    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
11567    fn slide_u64x8<const SHIFT: usize>(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self>;
11568    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
11569    #[inline(always)]
11570    fn slide_within_blocks_u64x8<const SHIFT: usize>(
11571        self,
11572        a: u64x8<Self>,
11573        b: u64x8<Self>,
11574    ) -> u64x8<Self> {
11575        let (a0, a1) = self.split_u64x8(a);
11576        let (b0, b1) = self.split_u64x8(b);
11577        self.combine_u64x4(
11578            self.slide_within_blocks_u64x4::<SHIFT>(a0, b0),
11579            self.slide_within_blocks_u64x4::<SHIFT>(a1, b1),
11580        )
11581    }
11582    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
11583    #[inline(always)]
11584    fn swizzle_dyn_within_blocks_u64x8(self, a: u64x8<Self>, indices: u8x64<Self>) -> u64x8<Self> {
11585        Bytes::from_bytes(self.swizzle_dyn_within_blocks_u8x64(Bytes::to_bytes(a), indices))
11586    }
11587    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
11588    #[inline(always)]
11589    fn swizzle_dyn_u64x8(self, a: u64x8<Self>, indices: u8x64<Self>) -> u64x8<Self> {
11590        Bytes::from_bytes(self.swizzle_dyn_u8x64(Bytes::to_bytes(a), indices))
11591    }
11592    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
11593    #[inline(always)]
11594    fn swizzle_dyn_precise_u64x8(self, a: u64x8<Self>, indices: u8x64<Self>) -> u64x8<Self> {
11595        Bytes::from_bytes(self.swizzle_dyn_precise_u8x64(Bytes::to_bytes(a), indices))
11596    }
11597    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
11598    #[inline(always)]
11599    fn concat_swizzle_dyn_u64x8(
11600        self,
11601        a: u64x8<Self>,
11602        b: u64x8<Self>,
11603        indices: u8x64<Self>,
11604    ) -> u64x8<Self> {
11605        Bytes::from_bytes(self.concat_swizzle_dyn_u8x64(
11606            Bytes::to_bytes(a),
11607            Bytes::to_bytes(b),
11608            indices,
11609        ))
11610    }
11611    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
11612    #[inline(always)]
11613    fn concat_swizzle_dyn_precise_u64x8(
11614        self,
11615        a: u64x8<Self>,
11616        b: u64x8<Self>,
11617        indices: u8x64<Self>,
11618    ) -> u64x8<Self> {
11619        Bytes::from_bytes(self.concat_swizzle_dyn_precise_u8x64(
11620            Bytes::to_bytes(a),
11621            Bytes::to_bytes(b),
11622            indices,
11623        ))
11624    }
11625    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
11626    fn compress_u64x8(self, values: u64x8<Self>, mask: mask64x8<Self>) -> u64x8<Self>;
11627    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = values[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
11628    fn compress_merge_u64x8(
11629        self,
11630        values: u64x8<Self>,
11631        mask: mask64x8<Self>,
11632        merge: u64x8<Self>,
11633    ) -> u64x8<Self>;
11634    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
11635    fn expand_u64x8(self, values: u64x8<Self>, mask: mask64x8<Self>) -> u64x8<Self>;
11636    #[doc = "Expand consecutive low elements from `values` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = values[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
11637    fn expand_merge_u64x8(
11638        self,
11639        values: u64x8<Self>,
11640        mask: mask64x8<Self>,
11641        merge: u64x8<Self>,
11642    ) -> u64x8<Self>;
11643    #[doc = "Return the number of ones in the binary representation of each element."]
11644    #[inline(always)]
11645    fn count_ones_u64x8(self, a: u64x8<Self>) -> u64x8<Self> {
11646        let (a0, a1) = self.split_u64x8(a);
11647        self.combine_u64x4(self.count_ones_u64x4(a0), self.count_ones_u64x4(a1))
11648    }
11649    #[doc = "Return the number of zeros in the binary representation of each element."]
11650    #[inline(always)]
11651    fn count_zeros_u64x8(self, a: u64x8<Self>) -> u64x8<Self> {
11652        let (a0, a1) = self.split_u64x8(a);
11653        self.combine_u64x4(self.count_zeros_u64x4(a0), self.count_zeros_u64x4(a1))
11654    }
11655    #[doc = "Add two vectors element-wise, wrapping on overflow."]
11656    #[inline(always)]
11657    fn add_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
11658        let (a0, a1) = self.split_u64x8(a);
11659        let (b0, b1) = self.split_u64x8(b);
11660        self.combine_u64x4(self.add_u64x4(a0, b0), self.add_u64x4(a1, b1))
11661    }
11662    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
11663    #[inline(always)]
11664    fn saturating_add_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
11665        let (a0, a1) = self.split_u64x8(a);
11666        let (b0, b1) = self.split_u64x8(b);
11667        self.combine_u64x4(
11668            self.saturating_add_u64x4(a0, b0),
11669            self.saturating_add_u64x4(a1, b1),
11670        )
11671    }
11672    #[doc = "Subtract two vectors element-wise, wrapping on overflow."]
11673    #[inline(always)]
11674    fn sub_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
11675        let (a0, a1) = self.split_u64x8(a);
11676        let (b0, b1) = self.split_u64x8(b);
11677        self.combine_u64x4(self.sub_u64x4(a0, b0), self.sub_u64x4(a1, b1))
11678    }
11679    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
11680    #[inline(always)]
11681    fn saturating_sub_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
11682        let (a0, a1) = self.split_u64x8(a);
11683        let (b0, b1) = self.split_u64x8(b);
11684        self.combine_u64x4(
11685            self.saturating_sub_u64x4(a0, b0),
11686            self.saturating_sub_u64x4(a1, b1),
11687        )
11688    }
11689    #[doc = "Multiply two vectors element-wise, wrapping on overflow."]
11690    #[inline(always)]
11691    fn mul_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
11692        let (a0, a1) = self.split_u64x8(a);
11693        let (b0, b1) = self.split_u64x8(b);
11694        self.combine_u64x4(self.mul_u64x4(a0, b0), self.mul_u64x4(a1, b1))
11695    }
11696    #[doc = "Compute the bitwise AND of two vectors."]
11697    #[inline(always)]
11698    fn and_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
11699        let (a0, a1) = self.split_u64x8(a);
11700        let (b0, b1) = self.split_u64x8(b);
11701        self.combine_u64x4(self.and_u64x4(a0, b0), self.and_u64x4(a1, b1))
11702    }
11703    #[doc = "Compute the bitwise OR of two vectors."]
11704    #[inline(always)]
11705    fn or_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
11706        let (a0, a1) = self.split_u64x8(a);
11707        let (b0, b1) = self.split_u64x8(b);
11708        self.combine_u64x4(self.or_u64x4(a0, b0), self.or_u64x4(a1, b1))
11709    }
11710    #[doc = "Compute the bitwise XOR of two vectors."]
11711    #[inline(always)]
11712    fn xor_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
11713        let (a0, a1) = self.split_u64x8(a);
11714        let (b0, b1) = self.split_u64x8(b);
11715        self.combine_u64x4(self.xor_u64x4(a0, b0), self.xor_u64x4(a1, b1))
11716    }
11717    #[doc = "Compute the bitwise NOT of the vector."]
11718    #[inline(always)]
11719    fn not_u64x8(self, a: u64x8<Self>) -> u64x8<Self> {
11720        let (a0, a1) = self.split_u64x8(a);
11721        self.combine_u64x4(self.not_u64x4(a0), self.not_u64x4(a1))
11722    }
11723    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
11724    #[inline(always)]
11725    fn shl_u64x8(self, a: u64x8<Self>, shift: u32) -> u64x8<Self> {
11726        let (a0, a1) = self.split_u64x8(a);
11727        self.combine_u64x4(self.shl_u64x4(a0, shift), self.shl_u64x4(a1, shift))
11728    }
11729    #[doc = "Shift each element left by the given number of bits.\n\nBits shifted out of the left side are discarded, and zeros are shifted in on the right.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
11730    #[inline(always)]
11731    fn shlv_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
11732        let (a0, a1) = self.split_u64x8(a);
11733        let (b0, b1) = self.split_u64x8(b);
11734        self.combine_u64x4(self.shlv_u64x4(a0, b0), self.shlv_u64x4(a1, b1))
11735    }
11736    #[doc = "Shift each element right by the given number of bits.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform."]
11737    #[inline(always)]
11738    fn shr_u64x8(self, a: u64x8<Self>, shift: u32) -> u64x8<Self> {
11739        let (a0, a1) = self.split_u64x8(a);
11740        self.combine_u64x4(self.shr_u64x4(a0, shift), self.shr_u64x4(a1, shift))
11741    }
11742    #[doc = "Shift each element right by the corresponding element in another vector.\n\nFor unsigned integers, zeros are shifted in on the left. For signed integers, the sign bit is replicated.\n\nWhen shifting out of bounds (e.g. shifting a 32-bit value by 32 or more), the result is implementation-defined and may vary by platform.\n\n# Performance\nThis per-lane shift is slower than shifting the entire vector by a scalar. It is not vectorized at all on WebAssembly, SSE4.2, and for `u8` and `i8` elements on AVX2. Prefer shifting by a single scalar value instead of by a vector whenever possible."]
11743    #[inline(always)]
11744    fn shrv_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
11745        let (a0, a1) = self.split_u64x8(a);
11746        let (b0, b1) = self.split_u64x8(b);
11747        self.combine_u64x4(self.shrv_u64x4(a0, b0), self.shrv_u64x4(a1, b1))
11748    }
11749    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
11750    #[inline(always)]
11751    fn reduce_max_u64x8(self, a: u64x8<Self>) -> u64 {
11752        let (a0, a1) = self.split_u64x8(a);
11753        self.reduce_max_u64x4(self.max_u64x4(a0, a1))
11754    }
11755    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
11756    #[inline(always)]
11757    fn reduce_min_u64x8(self, a: u64x8<Self>) -> u64 {
11758        let (a0, a1) = self.split_u64x8(a);
11759        self.reduce_min_u64x4(self.min_u64x4(a0, a1))
11760    }
11761    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
11762    #[inline(always)]
11763    fn reduce_sum_u64x8(self, a: u64x8<Self>) -> u64 {
11764        let (a0, a1) = self.split_u64x8(a);
11765        self.reduce_sum_u64x4(self.add_u64x4(a0, a1))
11766    }
11767    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
11768    #[inline(always)]
11769    fn reduce_product_u64x8(self, a: u64x8<Self>) -> u64 {
11770        let (a0, a1) = self.split_u64x8(a);
11771        self.reduce_product_u64x4(self.mul_u64x4(a0, a1))
11772    }
11773    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
11774    #[inline(always)]
11775    fn max_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
11776        let (a0, a1) = self.split_u64x8(a);
11777        let (b0, b1) = self.split_u64x8(b);
11778        self.combine_u64x4(self.max_u64x4(a0, b0), self.max_u64x4(a1, b1))
11779    }
11780    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
11781    #[inline(always)]
11782    fn min_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
11783        let (a0, a1) = self.split_u64x8(a);
11784        let (b0, b1) = self.split_u64x8(b);
11785        self.combine_u64x4(self.min_u64x4(a0, b0), self.min_u64x4(a1, b1))
11786    }
11787    #[doc = "Clamp each element to the interval `[b, c]`.\n\nIf `b > c`, or `b` or `c` are NaN, the result is implementation-defined for that lane.\n\nIf `a` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `b > c` for any element or any element of `b` or `c` is NaN."]
11788    #[inline(always)]
11789    fn clamp_u64x8(self, a: u64x8<Self>, b: u64x8<Self>, c: u64x8<Self>) -> u64x8<Self> {
11790        let (a0, a1) = self.split_u64x8(a);
11791        let (b0, b1) = self.split_u64x8(b);
11792        let (c0, c1) = self.split_u64x8(c);
11793        self.combine_u64x4(self.clamp_u64x4(a0, b0, c0), self.clamp_u64x4(a1, b1, c1))
11794    }
11795    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
11796    #[inline(always)]
11797    fn simd_eq_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> mask64x8<Self> {
11798        let (a0, a1) = self.split_u64x8(a);
11799        let (b0, b1) = self.split_u64x8(b);
11800        self.combine_mask64x4(self.simd_eq_u64x4(a0, b0), self.simd_eq_u64x4(a1, b1))
11801    }
11802    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
11803    #[inline(always)]
11804    fn simd_ne_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> mask64x8<Self> {
11805        self.not_mask64x8(self.simd_eq_u64x8(a, b))
11806    }
11807    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `a` is less than `b`, and false if not."]
11808    #[inline(always)]
11809    fn simd_lt_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> mask64x8<Self> {
11810        let (a0, a1) = self.split_u64x8(a);
11811        let (b0, b1) = self.split_u64x8(b);
11812        self.combine_mask64x4(self.simd_lt_u64x4(a0, b0), self.simd_lt_u64x4(a1, b1))
11813    }
11814    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `a` is less than or equal to `b`, and false if not."]
11815    #[inline(always)]
11816    fn simd_le_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> mask64x8<Self> {
11817        let (a0, a1) = self.split_u64x8(a);
11818        let (b0, b1) = self.split_u64x8(b);
11819        self.combine_mask64x4(self.simd_le_u64x4(a0, b0), self.simd_le_u64x4(a1, b1))
11820    }
11821    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `a` is greater than or equal to `b`, and false if not."]
11822    #[inline(always)]
11823    fn simd_ge_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> mask64x8<Self> {
11824        self.simd_le_u64x8(b, a)
11825    }
11826    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `a` is greater than `b`, and false if not."]
11827    #[inline(always)]
11828    fn simd_gt_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> mask64x8<Self> {
11829        self.simd_lt_u64x8(b, a)
11830    }
11831    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
11832    #[inline(always)]
11833    fn zip_low_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
11834        let (a0, _) = self.split_u64x8(a);
11835        let (b0, _) = self.split_u64x8(b);
11836        self.combine_u64x4(self.zip_low_u64x4(a0, b0), self.zip_high_u64x4(a0, b0))
11837    }
11838    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
11839    #[inline(always)]
11840    fn zip_high_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
11841        let (_, a1) = self.split_u64x8(a);
11842        let (_, b1) = self.split_u64x8(b);
11843        self.combine_u64x4(self.zip_low_u64x4(a1, b1), self.zip_high_u64x4(a1, b1))
11844    }
11845    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
11846    #[inline(always)]
11847    fn unzip_low_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
11848        let (a0, a1) = self.split_u64x8(a);
11849        let (b0, b1) = self.split_u64x8(b);
11850        self.combine_u64x4(self.unzip_low_u64x4(a0, a1), self.unzip_low_u64x4(b0, b1))
11851    }
11852    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
11853    #[inline(always)]
11854    fn unzip_high_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u64x8<Self> {
11855        let (a0, a1) = self.split_u64x8(a);
11856        let (b0, b1) = self.split_u64x8(b);
11857        self.combine_u64x4(self.unzip_high_u64x4(a0, a1), self.unzip_high_u64x4(b0, b1))
11858    }
11859    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `a` and `b`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
11860    #[inline(always)]
11861    fn interleave_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> (u64x8<Self>, u64x8<Self>) {
11862        let (a0, a1) = self.split_u64x8(a);
11863        let (b0, b1) = self.split_u64x8(b);
11864        let lo_lo = self.zip_low_u64x4(a0, b0);
11865        let lo_hi = self.zip_high_u64x4(a0, b0);
11866        let hi_lo = self.zip_low_u64x4(a1, b1);
11867        let hi_hi = self.zip_high_u64x4(a1, b1);
11868        (
11869            self.combine_u64x4(lo_lo, lo_hi),
11870            self.combine_u64x4(hi_lo, hi_hi),
11871        )
11872    }
11873    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `a` followed by all even-indexed elements from `b`. The second result contains all odd-indexed elements from `a` followed by all odd-indexed elements from `b`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
11874    #[inline(always)]
11875    fn deinterleave_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> (u64x8<Self>, u64x8<Self>) {
11876        let (a0, a1) = self.split_u64x8(a);
11877        let (b0, b1) = self.split_u64x8(b);
11878        let lo_even = self.unzip_low_u64x4(a0, a1);
11879        let lo_odd = self.unzip_high_u64x4(a0, a1);
11880        let hi_even = self.unzip_low_u64x4(b0, b1);
11881        let hi_odd = self.unzip_high_u64x4(b0, b1);
11882        (
11883            self.combine_u64x4(lo_even, hi_even),
11884            self.combine_u64x4(lo_odd, hi_odd),
11885        )
11886    }
11887    #[doc = "Select elements from b and c based on the mask operand a.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
11888    #[inline(always)]
11889    fn select_u64x8(self, a: mask64x8<Self>, b: u64x8<Self>, c: u64x8<Self>) -> u64x8<Self> {
11890        let (a0, a1) = self.split_mask64x8(a);
11891        let (b0, b1) = self.split_u64x8(b);
11892        let (c0, c1) = self.split_u64x8(c);
11893        self.combine_u64x4(self.select_u64x4(a0, b0, c0), self.select_u64x4(a1, b1, c1))
11894    }
11895    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
11896    fn split_u64x8(self, a: u64x8<Self>) -> (u64x4<Self>, u64x4<Self>);
11897    #[doc = "Truncate the lanes of two vectors and concatenate them into one same-width vector.\n\nEach lane retains its low destination-width bits. `a` provides the lower result lanes and `b` provides the upper result lanes."]
11898    #[inline(always)]
11899    fn narrow_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u32x16<Self> {
11900        let (a0, a1) = self.split_u64x8(a);
11901        let (b0, b1) = self.split_u64x8(b);
11902        self.combine_u32x8(self.narrow_u64x4(a0, a1), self.narrow_u64x4(b0, b1))
11903    }
11904    #[doc = "Narrow the lanes of two vectors with saturation and concatenate them into one same-width vector.\n\nEach lane is clamped to the destination type's range. `a` provides the lower result lanes and `b` provides the upper result lanes."]
11905    #[inline(always)]
11906    fn saturating_narrow_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u32x16<Self> {
11907        let (a0, a1) = self.split_u64x8(a);
11908        let (b0, b1) = self.split_u64x8(b);
11909        self.combine_u32x8(
11910            self.saturating_narrow_u64x4(a0, a1),
11911            self.saturating_narrow_u64x4(b0, b1),
11912        )
11913    }
11914    #[doc = "Narrow the lanes of two vectors using the cheapest operation for the active SIMD backend and concatenate them into one same-width vector.\n\nInputs must fit in the destination type; in debug mode this function will panic if any of the inputs do not fit. Out-of-range results in release builds produce arbitrary values (but remain memory-safe).\n\n`a` provides the lower result lanes and `b` provides the upper result lanes."]
11915    #[inline(always)]
11916    fn relaxed_narrow_u64x8(self, a: u64x8<Self>, b: u64x8<Self>) -> u32x16<Self> {
11917        let (a0, a1) = self.split_u64x8(a);
11918        let (b0, b1) = self.split_u64x8(b);
11919        self.combine_u32x8(
11920            self.relaxed_narrow_u64x4(a0, a1),
11921            self.relaxed_narrow_u64x4(b0, b1),
11922        )
11923    }
11924    #[doc = "Convert each unsigned 64-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
11925    #[inline(always)]
11926    fn cvt_f64_u64x8(self, a: u64x8<Self>) -> f64x8<Self> {
11927        let (a0, a1) = self.split_u64x8(a);
11928        self.combine_f64x4(self.cvt_f64_u64x4(a0), self.cvt_f64_u64x4(a1))
11929    }
11930    #[doc = "Create a SIMD mask with all lanes set from the given boolean value."]
11931    #[inline(always)]
11932    fn splat_mask64x8(self, val: bool) -> mask64x8<Self> {
11933        let half = self.splat_mask64x4(val);
11934        self.combine_mask64x4(half, half)
11935    }
11936    #[doc = "Create a SIMD mask from a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are ignored."]
11937    #[inline(always)]
11938    fn from_bitmask_mask64x8(self, bits: u64) -> mask64x8<Self> {
11939        let lo = self.from_bitmask_mask64x4(bits);
11940        let hi = self.from_bitmask_mask64x4(bits >> 4usize);
11941        self.combine_mask64x4(lo, hi)
11942    }
11943    #[doc = "Convert a SIMD mask to a compact bitmask.\n\nBit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above the number of lanes in this mask are cleared."]
11944    #[inline(always)]
11945    fn to_bitmask_mask64x8(self, a: mask64x8<Self>) -> u64 {
11946        let (lo, hi) = self.split_mask64x8(a);
11947        let lo = self.to_bitmask_mask64x4(lo);
11948        let hi = self.to_bitmask_mask64x4(hi);
11949        lo | (hi << 4usize)
11950    }
11951    #[doc = "Create a SIMD mask from an integer vector of the same width.\n\nA lane value of -1 means \"true\", a lane value of 0 means \"false\", and all other lane values result in unspecified behavior."]
11952    fn from_vector_mask64x8(self, vector: i64x8<Self>) -> mask64x8<Self>;
11953    #[doc = "Convert a SIMD mask to an integer vector of the same width.\n\n\"True\" maps to -1 and \"false\" maps to 0."]
11954    fn to_vector_mask64x8(self, a: mask64x8<Self>) -> i64x8<Self>;
11955    #[doc = "Set one logical lane of a SIMD mask."]
11956    fn set_mask64x8(self, a: &mut mask64x8<Self>, index: usize, value: bool) -> ();
11957    #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
11958    fn rotate_elements_left_mask64x8<const OFFSET: usize>(
11959        self,
11960        a: mask64x8<Self>,
11961    ) -> mask64x8<Self>;
11962    #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
11963    fn rotate_elements_right_mask64x8<const OFFSET: usize>(
11964        self,
11965        a: mask64x8<Self>,
11966    ) -> mask64x8<Self>;
11967    #[doc = "Compute the logical AND of two masks."]
11968    #[inline(always)]
11969    fn and_mask64x8(self, a: mask64x8<Self>, b: mask64x8<Self>) -> mask64x8<Self> {
11970        let (a0, a1) = self.split_mask64x8(a);
11971        let (b0, b1) = self.split_mask64x8(b);
11972        self.combine_mask64x4(self.and_mask64x4(a0, b0), self.and_mask64x4(a1, b1))
11973    }
11974    #[doc = "Compute the logical OR of two masks."]
11975    #[inline(always)]
11976    fn or_mask64x8(self, a: mask64x8<Self>, b: mask64x8<Self>) -> mask64x8<Self> {
11977        let (a0, a1) = self.split_mask64x8(a);
11978        let (b0, b1) = self.split_mask64x8(b);
11979        self.combine_mask64x4(self.or_mask64x4(a0, b0), self.or_mask64x4(a1, b1))
11980    }
11981    #[doc = "Compute the logical XOR of two masks."]
11982    #[inline(always)]
11983    fn xor_mask64x8(self, a: mask64x8<Self>, b: mask64x8<Self>) -> mask64x8<Self> {
11984        let (a0, a1) = self.split_mask64x8(a);
11985        let (b0, b1) = self.split_mask64x8(b);
11986        self.combine_mask64x4(self.xor_mask64x4(a0, b0), self.xor_mask64x4(a1, b1))
11987    }
11988    #[doc = "Compute the logical NOT of the mask."]
11989    #[inline(always)]
11990    fn not_mask64x8(self, a: mask64x8<Self>) -> mask64x8<Self> {
11991        let (a0, a1) = self.split_mask64x8(a);
11992        self.combine_mask64x4(self.not_mask64x4(a0), self.not_mask64x4(a1))
11993    }
11994    #[doc = "Reverse the order of the mask's logical lanes."]
11995    #[inline(always)]
11996    fn reverse_mask64x8(self, a: mask64x8<Self>) -> mask64x8<Self> {
11997        let (a0, a1) = self.split_mask64x8(a);
11998        self.combine_mask64x4(self.reverse_mask64x4(a1), self.reverse_mask64x4(a0))
11999    }
12000    #[doc = "Select elements from `b` and `c` based on the mask operand `a`.\n\nThis operation's behavior is unspecified if a was constructed from signed integer lanes that are neither all-zeroes (integer value 0) nor all-ones (integer value -1). See the [`Select`] trait's documentation for more information."]
12001    #[inline(always)]
12002    fn select_mask64x8(
12003        self,
12004        a: mask64x8<Self>,
12005        b: mask64x8<Self>,
12006        c: mask64x8<Self>,
12007    ) -> mask64x8<Self> {
12008        let (a0, a1) = self.split_mask64x8(a);
12009        let (b0, b1) = self.split_mask64x8(b);
12010        let (c0, c1) = self.split_mask64x8(c);
12011        self.combine_mask64x4(
12012            self.select_mask64x4(a0, b0, c0),
12013            self.select_mask64x4(a1, b1, c1),
12014        )
12015    }
12016    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
12017    #[inline(always)]
12018    fn simd_eq_mask64x8(self, a: mask64x8<Self>, b: mask64x8<Self>) -> mask64x8<Self> {
12019        let (a0, a1) = self.split_mask64x8(a);
12020        let (b0, b1) = self.split_mask64x8(b);
12021        self.combine_mask64x4(self.simd_eq_mask64x4(a0, b0), self.simd_eq_mask64x4(a1, b1))
12022    }
12023    #[doc = "Compare two masks element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
12024    #[inline(always)]
12025    fn simd_ne_mask64x8(self, a: mask64x8<Self>, b: mask64x8<Self>) -> mask64x8<Self> {
12026        self.not_mask64x8(self.simd_eq_mask64x8(a, b))
12027    }
12028    #[doc = "Returns true if any logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
12029    #[inline(always)]
12030    fn any_true_mask64x8(self, a: mask64x8<Self>) -> bool {
12031        let (a0, a1) = self.split_mask64x8(a);
12032        self.any_true_mask64x4(self.or_mask64x4(a0, a1))
12033    }
12034    #[doc = "Returns true if all logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
12035    #[inline(always)]
12036    fn all_true_mask64x8(self, a: mask64x8<Self>) -> bool {
12037        let (a0, a1) = self.split_mask64x8(a);
12038        self.all_true_mask64x4(self.and_mask64x4(a0, a1))
12039    }
12040    #[doc = "Returns true if any logical lanes in this mask are false.\n\nThis is logically equivalent to `!all_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
12041    #[inline(always)]
12042    fn any_false_mask64x8(self, a: mask64x8<Self>) -> bool {
12043        let (a0, a1) = self.split_mask64x8(a);
12044        self.any_false_mask64x4(self.and_mask64x4(a0, a1))
12045    }
12046    #[doc = "Returns true if all logical lanes in this mask are false.\n\nThis is logically equivalent to `!any_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
12047    #[inline(always)]
12048    fn all_false_mask64x8(self, a: mask64x8<Self>) -> bool {
12049        let (a0, a1) = self.split_mask64x8(a);
12050        self.all_false_mask64x4(self.or_mask64x4(a0, a1))
12051    }
12052    #[doc = "Split a vector into two vectors of half the width.\n\nReturns a tuple of (lower half, upper half)."]
12053    fn split_mask64x8(self, a: mask64x8<Self>) -> (mask64x4<Self>, mask64x4<Self>);
12054    #[doc = "Narrow each boolean lane of two masks and concatenate them into one mask of the same logical width, preserving each value.\n\n`a` supplies the lower result lanes and `b` supplies the upper result lanes. Masks constructed from integer lanes other than 0 or -1 have unspecified behavior."]
12055    #[inline(always)]
12056    fn narrow_mask64x8(self, a: mask64x8<Self>, b: mask64x8<Self>) -> mask32x16<Self> {
12057        let (a0, a1) = self.split_mask64x8(a);
12058        let (b0, b1) = self.split_mask64x8(b);
12059        self.combine_mask32x8(self.narrow_mask64x4(a0, a1), self.narrow_mask64x4(b0, b1))
12060    }
12061}
12062pub(crate) mod arch_types {
12063    use crate::transmute::SimdPod;
12064    #[expect(
12065        unnameable_types,
12066        reason = "The native vector types that back a `Simd` implementation are an internal implementation detail, and intentionally kept private"
12067    )]
12068    pub trait ArchTypes: Sized {
12069        type f32x4: Copy + Send + Sync + SimdPod;
12070        type i8x16: Copy + Send + Sync + SimdPod;
12071        type u8x16: Copy + Send + Sync + SimdPod;
12072        type mask8x16: Copy + Send + Sync + SimdPod;
12073        type i16x8: Copy + Send + Sync + SimdPod;
12074        type u16x8: Copy + Send + Sync + SimdPod;
12075        type mask16x8: Copy + Send + Sync + SimdPod;
12076        type i32x4: Copy + Send + Sync + SimdPod;
12077        type u32x4: Copy + Send + Sync + SimdPod;
12078        type mask32x4: Copy + Send + Sync + SimdPod;
12079        type f64x2: Copy + Send + Sync + SimdPod;
12080        type i64x2: Copy + Send + Sync + SimdPod;
12081        type u64x2: Copy + Send + Sync + SimdPod;
12082        type mask64x2: Copy + Send + Sync + SimdPod;
12083        type f32x8: Copy + Send + Sync + SimdPod;
12084        type i8x32: Copy + Send + Sync + SimdPod;
12085        type u8x32: Copy + Send + Sync + SimdPod;
12086        type mask8x32: Copy + Send + Sync + SimdPod;
12087        type i16x16: Copy + Send + Sync + SimdPod;
12088        type u16x16: Copy + Send + Sync + SimdPod;
12089        type mask16x16: Copy + Send + Sync + SimdPod;
12090        type i32x8: Copy + Send + Sync + SimdPod;
12091        type u32x8: Copy + Send + Sync + SimdPod;
12092        type mask32x8: Copy + Send + Sync + SimdPod;
12093        type f64x4: Copy + Send + Sync + SimdPod;
12094        type i64x4: Copy + Send + Sync + SimdPod;
12095        type u64x4: Copy + Send + Sync + SimdPod;
12096        type mask64x4: Copy + Send + Sync + SimdPod;
12097        type f32x16: Copy + Send + Sync + SimdPod;
12098        type i8x64: Copy + Send + Sync + SimdPod;
12099        type u8x64: Copy + Send + Sync + SimdPod;
12100        type mask8x64: Copy + Send + Sync + SimdPod;
12101        type i16x32: Copy + Send + Sync + SimdPod;
12102        type u16x32: Copy + Send + Sync + SimdPod;
12103        type mask16x32: Copy + Send + Sync + SimdPod;
12104        type i32x16: Copy + Send + Sync + SimdPod;
12105        type u32x16: Copy + Send + Sync + SimdPod;
12106        type mask32x16: Copy + Send + Sync + SimdPod;
12107        type f64x8: Copy + Send + Sync + SimdPod;
12108        type i64x8: Copy + Send + Sync + SimdPod;
12109        type u64x8: Copy + Send + Sync + SimdPod;
12110        type mask64x8: Copy + Send + Sync + SimdPod;
12111        #[inline(always)]
12112        fn mask8x16_from_array(self, val: [i8; 16usize]) -> Self::mask8x16 {
12113            crate::transmute::checked_transmute_copy(&val)
12114        }
12115        #[inline(always)]
12116        fn mask8x16_to_array(self, val: Self::mask8x16) -> [i8; 16usize] {
12117            crate::transmute::checked_transmute_copy(&val)
12118        }
12119        #[inline(always)]
12120        fn mask16x8_from_array(self, val: [i16; 8usize]) -> Self::mask16x8 {
12121            crate::transmute::checked_transmute_copy(&val)
12122        }
12123        #[inline(always)]
12124        fn mask16x8_to_array(self, val: Self::mask16x8) -> [i16; 8usize] {
12125            crate::transmute::checked_transmute_copy(&val)
12126        }
12127        #[inline(always)]
12128        fn mask32x4_from_array(self, val: [i32; 4usize]) -> Self::mask32x4 {
12129            crate::transmute::checked_transmute_copy(&val)
12130        }
12131        #[inline(always)]
12132        fn mask32x4_to_array(self, val: Self::mask32x4) -> [i32; 4usize] {
12133            crate::transmute::checked_transmute_copy(&val)
12134        }
12135        #[inline(always)]
12136        fn mask64x2_from_array(self, val: [i64; 2usize]) -> Self::mask64x2 {
12137            crate::transmute::checked_transmute_copy(&val)
12138        }
12139        #[inline(always)]
12140        fn mask64x2_to_array(self, val: Self::mask64x2) -> [i64; 2usize] {
12141            crate::transmute::checked_transmute_copy(&val)
12142        }
12143        #[inline(always)]
12144        fn mask8x32_from_array(self, val: [i8; 32usize]) -> Self::mask8x32 {
12145            crate::transmute::checked_transmute_copy(&val)
12146        }
12147        #[inline(always)]
12148        fn mask8x32_to_array(self, val: Self::mask8x32) -> [i8; 32usize] {
12149            crate::transmute::checked_transmute_copy(&val)
12150        }
12151        #[inline(always)]
12152        fn mask16x16_from_array(self, val: [i16; 16usize]) -> Self::mask16x16 {
12153            crate::transmute::checked_transmute_copy(&val)
12154        }
12155        #[inline(always)]
12156        fn mask16x16_to_array(self, val: Self::mask16x16) -> [i16; 16usize] {
12157            crate::transmute::checked_transmute_copy(&val)
12158        }
12159        #[inline(always)]
12160        fn mask32x8_from_array(self, val: [i32; 8usize]) -> Self::mask32x8 {
12161            crate::transmute::checked_transmute_copy(&val)
12162        }
12163        #[inline(always)]
12164        fn mask32x8_to_array(self, val: Self::mask32x8) -> [i32; 8usize] {
12165            crate::transmute::checked_transmute_copy(&val)
12166        }
12167        #[inline(always)]
12168        fn mask64x4_from_array(self, val: [i64; 4usize]) -> Self::mask64x4 {
12169            crate::transmute::checked_transmute_copy(&val)
12170        }
12171        #[inline(always)]
12172        fn mask64x4_to_array(self, val: Self::mask64x4) -> [i64; 4usize] {
12173            crate::transmute::checked_transmute_copy(&val)
12174        }
12175        #[inline(always)]
12176        fn mask8x64_from_array(self, val: [i8; 64usize]) -> Self::mask8x64 {
12177            crate::transmute::checked_transmute_copy(&val)
12178        }
12179        #[inline(always)]
12180        fn mask8x64_to_array(self, val: Self::mask8x64) -> [i8; 64usize] {
12181            crate::transmute::checked_transmute_copy(&val)
12182        }
12183        #[inline(always)]
12184        fn mask16x32_from_array(self, val: [i16; 32usize]) -> Self::mask16x32 {
12185            crate::transmute::checked_transmute_copy(&val)
12186        }
12187        #[inline(always)]
12188        fn mask16x32_to_array(self, val: Self::mask16x32) -> [i16; 32usize] {
12189            crate::transmute::checked_transmute_copy(&val)
12190        }
12191        #[inline(always)]
12192        fn mask32x16_from_array(self, val: [i32; 16usize]) -> Self::mask32x16 {
12193            crate::transmute::checked_transmute_copy(&val)
12194        }
12195        #[inline(always)]
12196        fn mask32x16_to_array(self, val: Self::mask32x16) -> [i32; 16usize] {
12197            crate::transmute::checked_transmute_copy(&val)
12198        }
12199        #[inline(always)]
12200        fn mask64x8_from_array(self, val: [i64; 8usize]) -> Self::mask64x8 {
12201            crate::transmute::checked_transmute_copy(&val)
12202        }
12203        #[inline(always)]
12204        fn mask64x8_to_array(self, val: Self::mask64x8) -> [i64; 8usize] {
12205            crate::transmute::checked_transmute_copy(&val)
12206        }
12207    }
12208}
12209#[doc = r" Base functionality implemented by all SIMD vectors."]
12210pub trait SimdBase<S: Simd>:
12211    ExtractToken<S = S>
12212    + Copy
12213    + Sync
12214    + Send
12215    + Debug
12216    + 'static
12217    + Seal
12218    + Bytes<Bytes = Self::ByteVector>
12219    + SimdFrom<Self::Element, S>
12220    + SimdFrom<Self::Array, S>
12221    + core::ops::Index<usize, Output = Self::Element>
12222    + core::ops::IndexMut<usize, Output = Self::Element>
12223    + core::ops::Deref<Target = Self::Array>
12224    + core::ops::DerefMut<Target = Self::Array>
12225    + core::ops::Add<Output = Self>
12226    + core::ops::AddAssign
12227    + core::ops::Add<Self::Element, Output = Self>
12228    + core::ops::AddAssign<Self::Element>
12229    + core::ops::Sub<Output = Self>
12230    + core::ops::SubAssign
12231    + core::ops::Sub<Self::Element, Output = Self>
12232    + core::ops::SubAssign<Self::Element>
12233    + core::ops::Mul<Output = Self>
12234    + core::ops::MulAssign
12235    + core::ops::Mul<Self::Element, Output = Self>
12236    + core::ops::MulAssign<Self::Element>
12237{
12238    #[doc = r" The type of this vector's elements."]
12239    type Element: SimdElement;
12240    #[doc = r" The same-width SIMD vector of `u8` lanes used as the byte representation."]
12241    #[doc = r""]
12242    #[doc = r" This is the same type as [`Bytes::Bytes`]."]
12243    #[doc = r""]
12244    #[doc = r" This associated type exists because expressing the `SimdBase` bound directly on"]
12245    #[doc = r" [`Bytes::Bytes`] creates a trait-solver cycle. The `Bytes<Bytes ="]
12246    #[doc = r" Self::ByteVector>` supertrait bound ensures that the two types are identical."]
12247    #[doc = r" Generic callers should normally use [`Bytes::Bytes`], not this associated type."]
12248    type ByteVector: SimdBase<S, Element = u8, ByteVector = Self::ByteVector>;
12249    #[doc = r" This vector type's lane count. This is useful when you're"]
12250    #[doc = r" working with a native-width vector (e.g. [`Simd::f32s`]) and"]
12251    #[doc = r" want to process data in native-width chunks."]
12252    const LEN: usize;
12253    #[doc = r" A SIMD vector mask with the same number of logical lanes."]
12254    #[doc = r""]
12255    #[doc = r" Masks intentionally do not implement [`SimdBase`]. SSE, NEON, WASM, and the"]
12256    #[doc = r" fallback backend currently store masks as all-zero/all-one integer vectors, but"]
12257    #[doc = r" AVX-512/RVV/SVE-style targets use compact predicate registers instead."]
12258    type Mask: SimdMask<S, Element = <Self::Element as SimdElement>::Mask> + Select<Self>;
12259    #[doc = r" A 128-bit SIMD vector of the same scalar type."]
12260    type Block: SimdBase<S, Element = Self::Element, Block = Self::Block>;
12261    #[doc = r" The array type that this vector type corresponds to, which will"]
12262    #[doc = r" always be `[Self::Element; Self::LEN]`. It has the same layout as"]
12263    #[doc = r" this vector type, but likely has a lower alignment."]
12264    type Array: Copy
12265        + Debug
12266        + IntoIterator<Item = Self::Element>
12267        + AsRef<[Self::Element]>
12268        + AsMut<[Self::Element]>
12269        + From<Self>;
12270    fn as_slice(&self) -> &[Self::Element];
12271    fn as_mut_slice(&mut self) -> &mut [Self::Element];
12272    #[doc = r" Create a SIMD vector from a slice."]
12273    #[doc = r""]
12274    #[doc = r" The slice must be exactly the size of the SIMD vector."]
12275    fn from_slice(simd: S, slice: &[Self::Element]) -> Self;
12276    #[doc = r" Store a SIMD vector into a slice."]
12277    #[doc = r""]
12278    #[doc = r" The slice must be exactly the size of the SIMD vector."]
12279    fn store_slice(&self, slice: &mut [Self::Element]);
12280    #[doc = r" Create a SIMD vector from its corresponding lane array."]
12281    #[inline(always)]
12282    fn load_array(simd: S, val: Self::Array) -> Self {
12283        Self::simd_from(simd, val)
12284    }
12285    #[doc = r" Create a SIMD vector from a reference to its corresponding lane array."]
12286    #[inline(always)]
12287    fn load_array_ref(simd: S, val: &Self::Array) -> Self {
12288        Self::load_array(simd, *val)
12289    }
12290    #[doc = r" Convert this SIMD vector to its corresponding lane array."]
12291    #[inline(always)]
12292    fn to_array(self) -> Self::Array {
12293        *self
12294    }
12295    #[doc = r" Project this SIMD vector reference to its corresponding lane array reference."]
12296    #[inline(always)]
12297    fn as_array(&self) -> &Self::Array {
12298        self
12299    }
12300    #[doc = r" Project this mutable SIMD vector reference to its corresponding mutable lane array reference."]
12301    #[inline(always)]
12302    fn as_mut_array(&mut self) -> &mut Self::Array {
12303        self
12304    }
12305    #[doc = r" Store this SIMD vector into its corresponding lane array."]
12306    #[inline(always)]
12307    fn store_array(self, dest: &mut Self::Array) {
12308        *dest = self.to_array();
12309    }
12310    #[doc = r" Create a SIMD vector from a 128-bit vector of the same scalar"]
12311    #[doc = r" type, repeated."]
12312    fn block_splat(block: Self::Block) -> Self;
12313    #[doc = r" Create a SIMD vector where each element is produced by"]
12314    #[doc = r" calling `f` with that element's lane index (from 0 to"]
12315    #[doc = r" [`SimdBase::LEN`] - 1)."]
12316    fn from_fn(simd: S, f: impl FnMut(usize) -> Self::Element) -> Self;
12317    #[doc = r" Rotate the vector elements to the left by `OFFSET`."]
12318    #[doc = r""]
12319    #[doc = r" If `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
12320    #[inline(always)]
12321    fn rotate_elements_left<const OFFSET: usize>(self) -> Self {
12322        match OFFSET % Self::LEN {
12323            0 => self.slide::<0>(self),
12324            1 => self.slide::<1>(self),
12325            2 => self.slide::<2>(self),
12326            3 => self.slide::<3>(self),
12327            4 => self.slide::<4>(self),
12328            5 => self.slide::<5>(self),
12329            6 => self.slide::<6>(self),
12330            7 => self.slide::<7>(self),
12331            8 => self.slide::<8>(self),
12332            9 => self.slide::<9>(self),
12333            10 => self.slide::<10>(self),
12334            11 => self.slide::<11>(self),
12335            12 => self.slide::<12>(self),
12336            13 => self.slide::<13>(self),
12337            14 => self.slide::<14>(self),
12338            15 => self.slide::<15>(self),
12339            16 => self.slide::<16>(self),
12340            17 => self.slide::<17>(self),
12341            18 => self.slide::<18>(self),
12342            19 => self.slide::<19>(self),
12343            20 => self.slide::<20>(self),
12344            21 => self.slide::<21>(self),
12345            22 => self.slide::<22>(self),
12346            23 => self.slide::<23>(self),
12347            24 => self.slide::<24>(self),
12348            25 => self.slide::<25>(self),
12349            26 => self.slide::<26>(self),
12350            27 => self.slide::<27>(self),
12351            28 => self.slide::<28>(self),
12352            29 => self.slide::<29>(self),
12353            30 => self.slide::<30>(self),
12354            31 => self.slide::<31>(self),
12355            32 => self.slide::<32>(self),
12356            33 => self.slide::<33>(self),
12357            34 => self.slide::<34>(self),
12358            35 => self.slide::<35>(self),
12359            36 => self.slide::<36>(self),
12360            37 => self.slide::<37>(self),
12361            38 => self.slide::<38>(self),
12362            39 => self.slide::<39>(self),
12363            40 => self.slide::<40>(self),
12364            41 => self.slide::<41>(self),
12365            42 => self.slide::<42>(self),
12366            43 => self.slide::<43>(self),
12367            44 => self.slide::<44>(self),
12368            45 => self.slide::<45>(self),
12369            46 => self.slide::<46>(self),
12370            47 => self.slide::<47>(self),
12371            48 => self.slide::<48>(self),
12372            49 => self.slide::<49>(self),
12373            50 => self.slide::<50>(self),
12374            51 => self.slide::<51>(self),
12375            52 => self.slide::<52>(self),
12376            53 => self.slide::<53>(self),
12377            54 => self.slide::<54>(self),
12378            55 => self.slide::<55>(self),
12379            56 => self.slide::<56>(self),
12380            57 => self.slide::<57>(self),
12381            58 => self.slide::<58>(self),
12382            59 => self.slide::<59>(self),
12383            60 => self.slide::<60>(self),
12384            61 => self.slide::<61>(self),
12385            62 => self.slide::<62>(self),
12386            63 => self.slide::<63>(self),
12387            _ => unreachable!(),
12388        }
12389    }
12390    #[doc = r" Rotate the vector elements to the right by `OFFSET`."]
12391    #[doc = r""]
12392    #[doc = r" If `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
12393    #[inline(always)]
12394    fn rotate_elements_right<const OFFSET: usize>(self) -> Self {
12395        match Self::LEN - OFFSET % Self::LEN {
12396            1 => self.slide::<1>(self),
12397            2 => self.slide::<2>(self),
12398            3 => self.slide::<3>(self),
12399            4 => self.slide::<4>(self),
12400            5 => self.slide::<5>(self),
12401            6 => self.slide::<6>(self),
12402            7 => self.slide::<7>(self),
12403            8 => self.slide::<8>(self),
12404            9 => self.slide::<9>(self),
12405            10 => self.slide::<10>(self),
12406            11 => self.slide::<11>(self),
12407            12 => self.slide::<12>(self),
12408            13 => self.slide::<13>(self),
12409            14 => self.slide::<14>(self),
12410            15 => self.slide::<15>(self),
12411            16 => self.slide::<16>(self),
12412            17 => self.slide::<17>(self),
12413            18 => self.slide::<18>(self),
12414            19 => self.slide::<19>(self),
12415            20 => self.slide::<20>(self),
12416            21 => self.slide::<21>(self),
12417            22 => self.slide::<22>(self),
12418            23 => self.slide::<23>(self),
12419            24 => self.slide::<24>(self),
12420            25 => self.slide::<25>(self),
12421            26 => self.slide::<26>(self),
12422            27 => self.slide::<27>(self),
12423            28 => self.slide::<28>(self),
12424            29 => self.slide::<29>(self),
12425            30 => self.slide::<30>(self),
12426            31 => self.slide::<31>(self),
12427            32 => self.slide::<32>(self),
12428            33 => self.slide::<33>(self),
12429            34 => self.slide::<34>(self),
12430            35 => self.slide::<35>(self),
12431            36 => self.slide::<36>(self),
12432            37 => self.slide::<37>(self),
12433            38 => self.slide::<38>(self),
12434            39 => self.slide::<39>(self),
12435            40 => self.slide::<40>(self),
12436            41 => self.slide::<41>(self),
12437            42 => self.slide::<42>(self),
12438            43 => self.slide::<43>(self),
12439            44 => self.slide::<44>(self),
12440            45 => self.slide::<45>(self),
12441            46 => self.slide::<46>(self),
12442            47 => self.slide::<47>(self),
12443            48 => self.slide::<48>(self),
12444            49 => self.slide::<49>(self),
12445            50 => self.slide::<50>(self),
12446            51 => self.slide::<51>(self),
12447            52 => self.slide::<52>(self),
12448            53 => self.slide::<53>(self),
12449            54 => self.slide::<54>(self),
12450            55 => self.slide::<55>(self),
12451            56 => self.slide::<56>(self),
12452            57 => self.slide::<57>(self),
12453            58 => self.slide::<58>(self),
12454            59 => self.slide::<59>(self),
12455            60 => self.slide::<60>(self),
12456            61 => self.slide::<61>(self),
12457            62 => self.slide::<62>(self),
12458            63 => self.slide::<63>(self),
12459            64 => self.slide::<64>(self),
12460            _ => unreachable!(),
12461        }
12462    }
12463    #[doc = r" Shift the vector elements to the left by `OFFSET`, filling in with `padding` from the right."]
12464    #[doc = r""]
12465    #[doc = r" If `OFFSET` is greater than or equal to `Self::LEN`, all lanes are filled with `padding`."]
12466    #[inline(always)]
12467    fn shift_elements_left<const OFFSET: usize>(self, padding: Self::Element) -> Self {
12468        match OFFSET.min(Self::LEN) {
12469            0 => self.slide::<0>(padding),
12470            1 => self.slide::<1>(padding),
12471            2 => self.slide::<2>(padding),
12472            3 => self.slide::<3>(padding),
12473            4 => self.slide::<4>(padding),
12474            5 => self.slide::<5>(padding),
12475            6 => self.slide::<6>(padding),
12476            7 => self.slide::<7>(padding),
12477            8 => self.slide::<8>(padding),
12478            9 => self.slide::<9>(padding),
12479            10 => self.slide::<10>(padding),
12480            11 => self.slide::<11>(padding),
12481            12 => self.slide::<12>(padding),
12482            13 => self.slide::<13>(padding),
12483            14 => self.slide::<14>(padding),
12484            15 => self.slide::<15>(padding),
12485            16 => self.slide::<16>(padding),
12486            17 => self.slide::<17>(padding),
12487            18 => self.slide::<18>(padding),
12488            19 => self.slide::<19>(padding),
12489            20 => self.slide::<20>(padding),
12490            21 => self.slide::<21>(padding),
12491            22 => self.slide::<22>(padding),
12492            23 => self.slide::<23>(padding),
12493            24 => self.slide::<24>(padding),
12494            25 => self.slide::<25>(padding),
12495            26 => self.slide::<26>(padding),
12496            27 => self.slide::<27>(padding),
12497            28 => self.slide::<28>(padding),
12498            29 => self.slide::<29>(padding),
12499            30 => self.slide::<30>(padding),
12500            31 => self.slide::<31>(padding),
12501            32 => self.slide::<32>(padding),
12502            33 => self.slide::<33>(padding),
12503            34 => self.slide::<34>(padding),
12504            35 => self.slide::<35>(padding),
12505            36 => self.slide::<36>(padding),
12506            37 => self.slide::<37>(padding),
12507            38 => self.slide::<38>(padding),
12508            39 => self.slide::<39>(padding),
12509            40 => self.slide::<40>(padding),
12510            41 => self.slide::<41>(padding),
12511            42 => self.slide::<42>(padding),
12512            43 => self.slide::<43>(padding),
12513            44 => self.slide::<44>(padding),
12514            45 => self.slide::<45>(padding),
12515            46 => self.slide::<46>(padding),
12516            47 => self.slide::<47>(padding),
12517            48 => self.slide::<48>(padding),
12518            49 => self.slide::<49>(padding),
12519            50 => self.slide::<50>(padding),
12520            51 => self.slide::<51>(padding),
12521            52 => self.slide::<52>(padding),
12522            53 => self.slide::<53>(padding),
12523            54 => self.slide::<54>(padding),
12524            55 => self.slide::<55>(padding),
12525            56 => self.slide::<56>(padding),
12526            57 => self.slide::<57>(padding),
12527            58 => self.slide::<58>(padding),
12528            59 => self.slide::<59>(padding),
12529            60 => self.slide::<60>(padding),
12530            61 => self.slide::<61>(padding),
12531            62 => self.slide::<62>(padding),
12532            63 => self.slide::<63>(padding),
12533            64 => self.slide::<64>(padding),
12534            _ => unreachable!(),
12535        }
12536    }
12537    #[doc = r" Shift the vector elements to the right by `OFFSET`, filling in with `padding` from the left."]
12538    #[doc = r""]
12539    #[doc = r" If `OFFSET` is greater than or equal to `Self::LEN`, all lanes are filled with `padding`."]
12540    #[inline(always)]
12541    fn shift_elements_right<const OFFSET: usize>(self, padding: Self::Element) -> Self {
12542        let padding = Self::splat(self.token(), padding);
12543        match Self::LEN.saturating_sub(OFFSET) {
12544            0 => padding.slide::<0>(self),
12545            1 => padding.slide::<1>(self),
12546            2 => padding.slide::<2>(self),
12547            3 => padding.slide::<3>(self),
12548            4 => padding.slide::<4>(self),
12549            5 => padding.slide::<5>(self),
12550            6 => padding.slide::<6>(self),
12551            7 => padding.slide::<7>(self),
12552            8 => padding.slide::<8>(self),
12553            9 => padding.slide::<9>(self),
12554            10 => padding.slide::<10>(self),
12555            11 => padding.slide::<11>(self),
12556            12 => padding.slide::<12>(self),
12557            13 => padding.slide::<13>(self),
12558            14 => padding.slide::<14>(self),
12559            15 => padding.slide::<15>(self),
12560            16 => padding.slide::<16>(self),
12561            17 => padding.slide::<17>(self),
12562            18 => padding.slide::<18>(self),
12563            19 => padding.slide::<19>(self),
12564            20 => padding.slide::<20>(self),
12565            21 => padding.slide::<21>(self),
12566            22 => padding.slide::<22>(self),
12567            23 => padding.slide::<23>(self),
12568            24 => padding.slide::<24>(self),
12569            25 => padding.slide::<25>(self),
12570            26 => padding.slide::<26>(self),
12571            27 => padding.slide::<27>(self),
12572            28 => padding.slide::<28>(self),
12573            29 => padding.slide::<29>(self),
12574            30 => padding.slide::<30>(self),
12575            31 => padding.slide::<31>(self),
12576            32 => padding.slide::<32>(self),
12577            33 => padding.slide::<33>(self),
12578            34 => padding.slide::<34>(self),
12579            35 => padding.slide::<35>(self),
12580            36 => padding.slide::<36>(self),
12581            37 => padding.slide::<37>(self),
12582            38 => padding.slide::<38>(self),
12583            39 => padding.slide::<39>(self),
12584            40 => padding.slide::<40>(self),
12585            41 => padding.slide::<41>(self),
12586            42 => padding.slide::<42>(self),
12587            43 => padding.slide::<43>(self),
12588            44 => padding.slide::<44>(self),
12589            45 => padding.slide::<45>(self),
12590            46 => padding.slide::<46>(self),
12591            47 => padding.slide::<47>(self),
12592            48 => padding.slide::<48>(self),
12593            49 => padding.slide::<49>(self),
12594            50 => padding.slide::<50>(self),
12595            51 => padding.slide::<51>(self),
12596            52 => padding.slide::<52>(self),
12597            53 => padding.slide::<53>(self),
12598            54 => padding.slide::<54>(self),
12599            55 => padding.slide::<55>(self),
12600            56 => padding.slide::<56>(self),
12601            57 => padding.slide::<57>(self),
12602            58 => padding.slide::<58>(self),
12603            59 => padding.slide::<59>(self),
12604            60 => padding.slide::<60>(self),
12605            61 => padding.slide::<61>(self),
12606            62 => padding.slide::<62>(self),
12607            63 => padding.slide::<63>(self),
12608            64 => padding.slide::<64>(self),
12609            _ => unreachable!(),
12610        }
12611    }
12612    #[doc = "Compute the absolute value of each element.\n\nUnsigned integers are unchanged. Signed integers use wrapping absolute value: the minimum representable value remains unchanged. This matches `i32::abs()`.\n\nFor floating-point elements, clear the sign bit, preserving all other bits. For example, negative zero becomes positive zero."]
12613    fn abs(self) -> Self;
12614    #[doc = "Create a SIMD vector with all elements set to the given value."]
12615    fn splat(simd: S, val: Self::Element) -> Self;
12616    #[doc = "Reverse the order of the vector's elements."]
12617    fn reverse(self) -> Self;
12618    #[doc = "Concatenate `[self, rhs]` and extract `Self::LEN` elements starting at index `SHIFT`.\n\n`SHIFT` must be within [0, `Self::LEN`].\n\nThis can be used to implement a \"shift items\" operation by providing all zeroes as one operand. For a left shift, the right-hand side should be all zeroes. For a right shift by `M` items, the left-hand side should be all zeroes, and the shift amount will be `Self::LEN - M`.\n\nThis can also be used to rotate items within a vector by providing the same vector as both operands.\n\n```text\n\nslide::<1>([a b c d], [e f g h]) == [b c d e]\n\n```"]
12619    fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self;
12620    #[doc = "Like `slide`, but operates independently on each 128-bit block."]
12621    fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self;
12622    #[doc = "Dynamically swizzle this vector's bytes independently within each 128-bit block.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values `0..=15` select the corresponding byte from the same 128-bit input block.\n\nOut-of-range index behavior varies by platform."]
12623    fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self;
12624    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::swizzle_dyn_precise`] if out-of-range indices must produce zero."]
12625    fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self;
12626    #[doc = "Dynamically swizzle this vector's bytes across the whole vector.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the vector's byte length select the corresponding byte from the input vector. Out-of-range indices produce zero."]
12627    fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self;
12628    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices safely produce implementation-defined byte values.\n\nUse [`SimdBase::concat_swizzle_dyn_precise`] if out-of-range indices must produce zero."]
12629    fn concat_swizzle_dyn(
12630        self,
12631        rhs: impl SimdInto<Self, S>,
12632        indices: impl SimdInto<Self::Bytes, S>,
12633    ) -> Self;
12634    #[doc = "Dynamically select bytes from the concatenation of this vector and `rhs`.\n\nThe `indices` operand is a same-width byte vector. For each output byte, index values within the concatenated vectors' byte length select the corresponding byte: the first vector comes first, followed by `rhs`. Out-of-range indices produce zero."]
12635    fn concat_swizzle_dyn_precise(
12636        self,
12637        rhs: impl SimdInto<Self, S>,
12638        indices: impl SimdInto<Self::Bytes, S>,
12639    ) -> Self;
12640    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\nThis is equivalent to [`SimdBase::compress_merge`] with a zeroed merge vector."]
12641    fn compress(self, mask: Self::Mask) -> Self;
12642    #[doc = "Compact the elements selected by `mask` into consecutive low lanes, preserving their order.\n\nLanes above the number of selected elements retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[k] = self[i];\n        k += 1;\n    }\n}\nreturn result;\n```"]
12643    fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self;
12644    #[doc = "Expand consecutive low elements from `self` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes are zero (positive zero for floats).\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros..\n\nThis is equivalent to [`SimdBase::expand_merge`] with a zeroed merge vector."]
12645    fn expand(self, mask: Self::Mask) -> Self;
12646    #[doc = "Expand consecutive low elements from `self` into the lanes selected by `mask`, preserving their order.\n\nUnselected lanes retain the corresponding values from `merge`.\n\nElements are moved without changing their bits, including floating-point NaN payloads and signed zeros.\n\n## Pseudo code\n\n```ignore\nlet mut result = merge;\nlet mut k = 0;\nfor i in 0..LEN {\n    if mask[i] {\n        result[i] = self[k];\n        k += 1;\n    }\n}\nreturn result;\n```"]
12647    fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self;
12648    #[doc = "Return the maximum element in the vector. Integer vectors always return the exact maximum.\n\nFor floating-point vectors with no NaNs, this returns the true maximum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true maximum. See `reduce_max_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
12649    fn reduce_max(self) -> Self::Element;
12650    #[doc = "Return the minimum element in the vector. Integer vectors always return the exact minimum.\n\nFor floating-point vectors with no NaNs, this returns the true minimum. If any lane is NaN, the entire result is implementation-defined: it may be NaN or a numeric lane that is not the true minimum. See `reduce_min_precise` for a version that ignores quiet NaNs.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned."]
12651    fn reduce_min(self) -> Self::Element;
12652    #[doc = "Return the maximum element in the vector, ignoring quiet NaNs.\n\nFor integer vectors, this operation is the same as `reduce_max`.\n\nFor floating-point vectors, quiet NaNs are ignored. If there is at least one numeric lane, this returns the true maximum of the numeric lanes. If all lanes are quiet NaNs, this returns NaN, with an unspecified payload and sign.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned.\n\nIf any lane is a *signaling* NaN, the result is fully non-deterministic: it may be NaN or a numeric lane and is not guaranteed to be the true maximum.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
12653    fn reduce_max_precise(self) -> Self::Element;
12654    #[doc = "Return the minimum element in the vector, ignoring quiet NaNs.\n\nFor integer vectors, this operation is the same as `reduce_min`.\n\nFor floating-point vectors, quiet NaNs are ignored. If there is at least one numeric lane, this returns the true minimum of the numeric lanes. If all lanes are quiet NaNs, this returns NaN, with an unspecified payload and sign.\n\nIf the floating-point vector contains both positive zero and negative zero, either sign of zero may be returned.\n\nIf any lane is a *signaling* NaN, the result is fully non-deterministic: it may be NaN or a numeric lane and is not guaranteed to be the true minimum.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
12655    fn reduce_min_precise(self) -> Self::Element;
12656    #[doc = "Return the sum of all elements in the vector. Integer addition wraps.\n\n# Floating-point accuracy\n\nFor an input vector with N lanes, any lane's contribution may be rounded at most `log2(N)` times.\n\nFor a fixed vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nBecause floating-point addition is not associative, separately reducing smaller vectors and then adding their results can differ from reducing their combined wider vector. See [Taming Floating-Point Sums](https://orlp.net/blog/taming-float-sums/) for more information and for other summation algorithms, including exact summation without accumulated rounding error. In that article's terms, our method has the precision properties of pairwise summation, although the exact pairing of values is different."]
12657    fn reduce_sum(self) -> Self::Element;
12658    #[doc = "Return the product of all elements in the vector. Integer multiplication wraps.\n\n# Floating-point behavior\n\nFor a vector with N elements, this operation performs N-1 roundings.\n\nFor a given vector type and lane count, this operation produces the same result on all platforms and backends down to the bit pattern, except that when the result is NaN, its exact bit pattern is unspecified. This fixed-width guarantee does not make code using native-width associated types such as `S::f32s` independent of the selected SIMD level, because their lane counts can differ.\n\nThe result of this operation is **not** bit-exact to scalar product of the elements because it multiplies elements in a different (but fixed) order.\n\nIntermediate operations can overflow, underflow, or multiply infinity by zero to produce NaN even when the exact real-number product is representable.\n\nBecause floating-point multiplication is not associative, separately reducing smaller vectors and then multiplying their results can differ from reducing their combined wider vector."]
12659    fn reduce_product(self) -> Self::Element;
12660    #[doc = "Return the element-wise maximum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `max_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
12661    fn max(self, rhs: impl SimdInto<Self, S>) -> Self;
12662    #[doc = "Return the element-wise minimum of two vectors.\n\nFor floating-point vectors, if either operand is NaN, the result for that lane is implementation-defined-- it could be either the first or second operand. See `min_precise` for a version that returns the non-NaN operand if only one is NaN.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is also implementation-defined, and it could be either one."]
12663    fn min(self, rhs: impl SimdInto<Self, S>) -> Self;
12664    #[doc = "Return the element-wise maximum of two vectors.\n\nFor integer vectors, this operation is the same as `max`.\n\nFor floating-point vectors, if one operand is a quiet NaN and the other is not, this operation will choose the non-NaN operand.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\nIf a floating-point operand is a *signaling* NaN, the result is not just implementation-defined, but fully non-deterministic: it may be either NaN or the non-NaN operand.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
12665    fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self;
12666    #[doc = "Return the element-wise minimum of two vectors.\n\nFor integer vectors, this operation is the same as `min`.\n\nFor floating-point vectors, if one operand is a quiet NaN and the other is not, this operation will choose the non-NaN operand.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\nIf a floating-point operand is a *signaling* NaN, the result is not just implementation-defined, but fully non-deterministic: it may be either NaN or the non-NaN operand.\nSignaling NaN values are not produced by floating-point math operations, only from manual initialization with specific bit patterns. You probably don't need to worry about them."]
12667    fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self;
12668    #[doc = "Clamp each element to the interval `[min, max]`.\n\nIf `min > max`, or `min` or `max` are NaN, the result is implementation-defined for that lane.\n\nIf `self` is NaN, the result is an implementation-defined non-deterministic NaN value. I.e. the result of the lane will be a NaN value but its exact bit pattern is not specified.\n\nIf one floating-point operand is positive zero and the other is negative zero, the result is implementation-defined, and it could be either one.\n\n# Panics\nPanics with debug assertions if `min > max` for any element or any element of `min` or `max` is NaN."]
12669    fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self;
12670    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
12671    fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask;
12672    #[doc = "Compare two vectors element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nFor floating-point vectors, this follows Rust's `!=` semantics: a lane is true if either operand is NaN, including when both are NaN. Positive and negative zero compare equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
12673    fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask;
12674    #[doc = "Compare two vectors element-wise for less than.\n\nReturns a mask where each logical lane is true if `self` is less than `rhs`, and false if not."]
12675    fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask;
12676    #[doc = "Compare two vectors element-wise for less than or equal.\n\nReturns a mask where each logical lane is true if `self` is less than or equal to `rhs`, and false if not."]
12677    fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask;
12678    #[doc = "Compare two vectors element-wise for greater than or equal.\n\nReturns a mask where each logical lane is true if `self` is greater than or equal to `rhs`, and false if not."]
12679    fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask;
12680    #[doc = "Compare two vectors element-wise for greater than.\n\nReturns a mask where each logical lane is true if `self` is greater than `rhs`, and false if not."]
12681    fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask;
12682    #[doc = "Interleave the lower half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, b0, a1, b1]`.\n\n**Note:** This operation is only useful if you need to discard elements `a2, a3, b2, b3`.\n        For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
12683    fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self;
12684    #[doc = "Interleave the upper half elements of two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a2, b2, a3, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a1, b0, b1`.For fully interleaving two vectors prefer `interleave`,\n        which is faster than `zip_low` followed by `zip_high` on some platforms."]
12685    fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self;
12686    #[doc = "Extract even-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a0, a2, b0, b2]`.\n\n**Note:** This operation is only useful if you need to discard elements `a1, a3, b1, b3`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
12687    fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self;
12688    #[doc = "Extract odd-indexed elements from two vectors.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `[a1, a3, b1, b3]`.\n\n**Note:** This operation is only useful if you need to discard elements `a0, a2, b0, b2`.For fully deinterleaving two vectors prefer `deinterleave`,\n        which is faster than `unzip_low` followed by `unzip_high` on some platforms."]
12689    fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self;
12690    #[doc = "Interleave two vectors.\n\nThe resulting vectors contain elements taken alternately from `self` and `rhs`, first filling the first result, and then the second.\n\nThe reverse of this operation is `deinterleave`.\n\nFor vectors `[a0, a1, a2, a3]` and `[b0, b1, b2, b3]`, returns `([a0, b0, a1, b1], [a2, b2, a3, b3])`."]
12691    fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self);
12692    #[doc = "Deinterleave two vectors.\n\nThe first result contains all even-indexed elements from `self` followed by all even-indexed elements from `rhs`. The second result contains all odd-indexed elements from `self` followed by all odd-indexed elements from `rhs`.\n\nThe reverse of this operation is `interleave`.\n\nFor vectors `[a0, b0, a1, b1]` and `[a2, b2, a3, b3]`, returns `([a0, a1, a2, a3], [b0, b1, b2, b3])`."]
12693    fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self);
12694}
12695#[doc = r" Functionality implemented by floating-point SIMD vectors."]
12696pub trait SimdFloat<S: Simd>:
12697    SimdBase<S, Element: SimdFloatElement>
12698    + Seal
12699    + core::ops::Neg<Output = Self>
12700    + core::ops::Div<Output = Self>
12701    + core::ops::DivAssign
12702    + core::ops::Div<Self::Element, Output = Self>
12703    + core::ops::DivAssign<Self::Element>
12704{
12705    #[doc = r" Bit representation of this SIMD float vector type."]
12706    type Bits: SimdInt<
12707            S,
12708            Element = <Self::Element as SimdFloatElement>::Bits,
12709            ByteVector = Self::ByteVector,
12710        >;
12711    #[doc = r" Raw transmutation to an unsigned integer vector type with the same size and number of elements."]
12712    #[doc = r""]
12713    #[doc = r" This is analogous to [`f32::to_bits`] and [`f64::to_bits`]."]
12714    fn to_bits(self) -> Self::Bits {
12715        self.bitcast()
12716    }
12717    #[doc = r" Raw transmutation from an unsigned integer vector type with the same size and number of elements."]
12718    #[doc = r""]
12719    #[doc = r" This is analogous to [`f32::from_bits`] and [`f64::from_bits`]."]
12720    fn from_bits(bits: Self::Bits) -> Self {
12721        bits.bitcast()
12722    }
12723    #[doc = r" Convert this floating-point type to an integer. This is a convenience method that"]
12724    #[doc = r" delegates to [`SimdCvtTruncate::truncate_from`], and can only be called if there"]
12725    #[doc = r" actually exists a target type of the same bit width (`u32`/`i32` for `f32`, or"]
12726    #[doc = r" `u64`/`i64` for `f64`)."]
12727    #[doc = r""]
12728    #[doc = r" For more information about the semantics of this specific conversion, see the"]
12729    #[doc = r" concrete `SimdCvtTruncate` implementations for integer types."]
12730    #[inline(always)]
12731    fn to_int<T: SimdCvtTruncate<Self>>(self) -> T {
12732        T::truncate_from(self)
12733    }
12734    #[doc = r" Convert this floating-point type to an integer, saturating on overflow and returning"]
12735    #[doc = r" 0 for NaN. This is a convenience method that delegates to"]
12736    #[doc = r" [`SimdCvtTruncate::truncate_from_precise`], and can only be called if there actually"]
12737    #[doc = r" exists a target type of the same bit width (`u32`/`i32` for `f32`, or `u64`/`i64`"]
12738    #[doc = r" for `f64`)."]
12739    #[doc = r""]
12740    #[doc = r" For more information about the semantics of this specific conversion, see the"]
12741    #[doc = r" concrete `SimdCvtTruncate` implementations for integer types."]
12742    #[inline(always)]
12743    fn to_int_precise<T: SimdCvtTruncate<Self>>(self) -> T {
12744        T::truncate_from_precise(self)
12745    }
12746    #[doc = "Compute the square root of each element.\n\nNegative elements other than `-0.0` will become NaN."]
12747    fn sqrt(self) -> Self;
12748    #[doc = "Compute an approximate reciprocal (`1. / x`) for each element.\n\nThis uses a fast hardware estimate where available, and falls back to exact division otherwise.\n\nOn x86 for `f32`, this has a relative error less than `1.5 × 2^-12`. On `AArch64` (`f32` and `f64`), this has a relative error less than `2^-8`. The precision of this operation may change as new platform support is added."]
12749    fn approximate_recip(self) -> Self;
12750    #[doc = "Return a vector with the magnitude of `self` and the sign of `rhs` for each element.\n\nThis operation copies the sign bit, so if an input element is NaN, the output element will be a NaN with the same payload and a copied sign bit."]
12751    fn copysign(self, rhs: impl SimdInto<Self, S>) -> Self;
12752    #[doc = "Compute `(self * op1) + op2` (fused multiply-add) for each element.\n\nDepending on platform support, the result may be computed with only one rounding error, or may be implemented as a regular multiply followed by an add, which will result in two rounding errors."]
12753    fn mul_add(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self;
12754    #[doc = "Compute `(self * op1) + op2` for each element, with a single rounding at the end.\n\nThe result is the infinite-precision product-plus-add rounded once to the element type. This may be substantially slower than `mul_add` on platforms without fused multiply-add instructions, including WebAssembly.\n\n# Precision guarantees\n\nThis function is **not** susceptible to [the bug](https://github.com/rust-lang/compiler-builtins/issues/1262) in Rust standard library and in musl libc that causes incorrect rounding for near-zero values on CPUs without hardware support for this operation.\n\nOn the tier-2 i586-* targets, this function is correct if and only if SSE2 is available on the CPU.\n\nThe exact `NaN` payloads as well as signaling `NaN`s are not preserved."]
12755    fn mul_add_precise(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self;
12756    #[doc = "Compute `(self * op1) - op2` (fused multiply-subtract) for each element.\n\nDepending on platform support, the result may be computed with only one rounding error, or may be implemented as a regular multiply followed by a subtract, which will result in two rounding errors."]
12757    fn mul_sub(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self;
12758    #[doc = "Compute `(self * op1) - op2` for each element, with a single rounding at the end.\n\nThe result is the infinite-precision product-minus-subtrahend rounded once to the element type. This may be substantially slower than `mul_sub` on platforms without fused multiply-add instructions, including WebAssembly.\n        # Precision guarantees\n\nThis function is **not** susceptible to [the bug](https://github.com/rust-lang/compiler-builtins/issues/1262) in Rust standard library and in musl libc that causes incorrect rounding for near-zero values on CPUs without hardware support for this operation.\n\nOn the tier-2 i586-* targets, this function is correct if and only if SSE2 is available on the CPU.\n\nThe exact `NaN` payloads as well as signaling `NaN`s are not preserved."]
12759    fn mul_sub_precise(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self;
12760    #[doc = "Return the largest integer less than or equal to each element, that is, round towards negative infinity."]
12761    fn floor(self) -> Self;
12762    #[doc = "Return the smallest integer greater than or equal to each element, that is, round towards positive infinity."]
12763    fn ceil(self) -> Self;
12764    #[doc = "Round each element to the nearest integer, with ties rounding to the nearest even integer."]
12765    fn round_ties_even(self) -> Self;
12766    #[doc = "Round each element to the nearest integer, with ties rounding away from zero.\n\n## Performance considerations\n\nOnly `AArch64` has native instructions for this operation. `round` has to be emulated on all other platforms which is around 2-4x slower than `round_ties_even`. Prefer using [`round_ties_even`](SimdFloat::round_ties_even) if possible."]
12767    fn round(self) -> Self;
12768    #[doc = "Return the fractional part of each element.\n\nThis is equivalent to `self - self.trunc()`."]
12769    fn fract(self) -> Self;
12770    #[doc = "Return the integer part of each element, rounding towards zero."]
12771    fn trunc(self) -> Self;
12772    #[doc = "Converts radians to degrees.\n\nThe precision of this function is non-deterministic. This means it varies by platform, Rust version, and can even differ within the same execution from one invocation to the next."]
12773    fn to_degrees(self) -> Self;
12774    #[doc = "Converts degrees to radians.\n\nThe precision of this function is non-deterministic. This means it varies by platform, Rust version, and can even differ within the same execution from one invocation to the next."]
12775    fn to_radians(self) -> Self;
12776    #[doc = "Return a mask indicating which elements are NaN."]
12777    fn is_nan(self) -> Self::Mask;
12778    #[doc = "Return a mask indicating which elements are positive or negative infinite."]
12779    fn is_infinite(self) -> Self::Mask;
12780    #[doc = "Return a mask indicating which elements are neither infinite nor NaN."]
12781    fn is_finite(self) -> Self::Mask;
12782    #[doc = "Return a mask indicating which elements are subnormal.\n\nThis classifies the stored bit pattern, even when floating-point operations treat subnormals as zero."]
12783    fn is_subnormal(self) -> Self::Mask;
12784    #[doc = "Return a mask indicating which elements are neither zero, infinite, subnormal, or NaN."]
12785    fn is_normal(self) -> Self::Mask;
12786    #[doc = "Return a mask indicating which elements have a positive sign, including `+0.0`, NaNs with positive sign bit and positive infinity.\n\nNaN inputs may produce an unexpected or non-portable result, see [`f32::is_sign_positive`] for details."]
12787    fn is_sign_positive(self) -> Self::Mask;
12788    #[doc = "Return a mask indicating which elements have a negative sign, including `-0.0`, NaNs with negative sign bit and negative infinity.\n\nNaN inputs may produce an unexpected or non-portable result, see [`f32::is_sign_negative`] for details."]
12789    fn is_sign_negative(self) -> Self::Mask;
12790}
12791#[doc = r" Functionality implemented by (signed and unsigned) integer SIMD vectors."]
12792pub trait SimdInt<S: Simd>:
12793    SimdBase<S, Element: SimdIntElement>
12794    + Seal
12795    + core::ops::BitAnd<Output = Self>
12796    + core::ops::BitAndAssign
12797    + core::ops::BitAnd<Self::Element, Output = Self>
12798    + core::ops::BitAndAssign<Self::Element>
12799    + core::ops::BitOr<Output = Self>
12800    + core::ops::BitOrAssign
12801    + core::ops::BitOr<Self::Element, Output = Self>
12802    + core::ops::BitOrAssign<Self::Element>
12803    + core::ops::BitXor<Output = Self>
12804    + core::ops::BitXorAssign
12805    + core::ops::BitXor<Self::Element, Output = Self>
12806    + core::ops::BitXorAssign<Self::Element>
12807    + core::ops::Not<Output = Self>
12808    + core::ops::Shl<u32, Output = Self>
12809    + core::ops::ShlAssign<u32>
12810    + core::ops::Shl<Output = Self>
12811    + core::ops::ShlAssign
12812    + core::ops::Shr<u32, Output = Self>
12813    + core::ops::ShrAssign<u32>
12814    + core::ops::Shr<Output = Self>
12815    + core::ops::ShrAssign
12816{
12817    #[doc = r" Convert this integer type to a floating-point type. This is a convenience method"]
12818    #[doc = r" that delegates to [`SimdCvtFloat::float_from`], and can only be called if there"]
12819    #[doc = r" actually exists a target type of the same bit width (`f32` or `f64`)."]
12820    #[inline(always)]
12821    fn to_float<T: SimdCvtFloat<Self>>(self) -> T {
12822        T::float_from(self)
12823    }
12824    #[doc = "Return the number of ones in the binary representation of each element."]
12825    fn count_ones(self) -> Self;
12826    #[doc = "Return the number of zeros in the binary representation of each element."]
12827    fn count_zeros(self) -> Self;
12828    #[doc = "Add two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping addition on x86."]
12829    fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self;
12830    #[doc = "Subtract two vectors element-wise, saturating on overflow.\n\n\"Saturating\" means that if the result is not representable, the closest representable value (either `Element::MAX` or `Element::MIN`) is returned.\n\nOn x86 it is implemented in hardware only for 8-bit and 16-bit elements. For 32-bit and 64-bit vectors this operation is slower than wrapping subtraction on x86."]
12831    fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self;
12832}
12833#[doc = r" Functionality implemented by SIMD masks."]
12834#[doc = r""]
12835#[doc = r" A mask has one logical boolean lane per SIMD lane. Its storage is intentionally opaque:"]
12836#[doc = r" current backends may use all-zero/all-one integer vectors internally, while future"]
12837#[doc = r" predicate-register backends may use a compact representation."]
12838pub trait SimdMask<S: Simd>:
12839    ExtractToken<S = S>
12840    + Copy
12841    + Sync
12842    + Send
12843    + 'static
12844    + Seal
12845    + Select<Self>
12846    + core::ops::BitAnd<Output = Self>
12847    + core::ops::BitAndAssign
12848    + core::ops::BitOr<Output = Self>
12849    + core::ops::BitOrAssign
12850    + core::ops::BitXor<Output = Self>
12851    + core::ops::BitXorAssign
12852    + core::ops::Not<Output = Self>
12853{
12854    #[doc = r" The signed integer type used when converting this mask to and from lane values."]
12855    #[doc = r""]
12856    #[doc = r" False lanes are encoded as all zeroes (integer value 0), and true lanes are encoded as all ones"]
12857    #[doc = r" (integer value -1)."]
12858    type Element: SimdIntElement<Mask = Self::Element> + core::ops::Neg<Output = Self::Element>;
12859    #[doc = r" This mask's corresponding integer vector type."]
12860    type Ints: SimdInt<S, Element = Self::Element, Mask = Self>
12861        + core::ops::Neg<Output = Self::Ints>;
12862    #[doc = r" This mask type's lane count."]
12863    const LEN: usize;
12864    #[doc = r" Create a SIMD mask with all lanes set to the given boolean value."]
12865    fn splat(simd: S, val: bool) -> Self;
12866    #[doc = r" Create a mask from a compact bitmask."]
12867    #[doc = r""]
12868    #[doc = r" Bit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above"]
12869    #[doc = r" [`Self::LEN`] are ignored."]
12870    fn from_bitmask(simd: S, bits: u64) -> Self;
12871    #[doc = r" Convert this mask to a compact bitmask."]
12872    #[doc = r""]
12873    #[doc = r" Bit `i` maps to lane `i`, with lane 0 in the least significant bit. Bits above"]
12874    #[doc = r" [`Self::LEN`] are cleared."]
12875    fn to_bitmask(self) -> u64;
12876    #[doc = r" Create a SIMD mask from signed integer mask lanes."]
12877    fn from_vector(v: Self::Ints) -> Self;
12878    #[doc = r" Convert this SIMD mask to signed integer mask lanes."]
12879    fn to_vector(self) -> Self::Ints;
12880    #[doc = r" Test whether one logical lane is set."]
12881    #[doc = r""]
12882    #[doc = r" Panics if `index` is greater than or equal to the number of lanes in the mask."]
12883    #[inline(always)]
12884    fn test(&self, index: usize) -> bool {
12885        assert!(
12886            index < Self::LEN,
12887            "mask lane index {index} is out of bounds for {} lanes",
12888            Self::LEN
12889        );
12890        (((*self).to_bitmask() >> index) & 1) != 0
12891    }
12892    #[doc = r" Sets the value of one logical lane."]
12893    #[doc = r""]
12894    #[doc = r" Panics if `index` is greater than or equal to the number of lanes in the mask."]
12895    fn set(&mut self, index: usize, value: bool);
12896    #[doc = r" Create a SIMD mask from signed integer mask lanes."]
12897    #[doc = r""]
12898    #[doc = r" The slice must be exactly the size of the SIMD mask."]
12899    fn from_slice(simd: S, slice: &[Self::Element]) -> Self;
12900    #[doc = r" Store this SIMD mask as signed integer mask lanes."]
12901    #[doc = r""]
12902    #[doc = r" The slice must be exactly the size of the SIMD mask."]
12903    fn store_slice(&self, slice: &mut [Self::Element]);
12904    #[doc = "Rotate the mask elements to the left by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
12905    fn rotate_elements_left<const OFFSET: usize>(self) -> Self;
12906    #[doc = "Rotate the mask elements to the right by `OFFSET`.\n\nIf `OFFSET` is greater than or equal to `Self::LEN`, it wraps modulo `Self::LEN`."]
12907    fn rotate_elements_right<const OFFSET: usize>(self) -> Self;
12908    #[doc = "Reverse the order of the mask's logical lanes."]
12909    fn reverse(self) -> Self;
12910    #[doc = "Compare two vectors element-wise for equality.\n\nReturns a mask where each logical lane is true if the corresponding elements are equal, and false if not."]
12911    fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self;
12912    #[doc = "Compare two masks element-wise for inequality.\n\nReturns a mask where each logical lane is true if the corresponding elements are unequal, and false if equal.\n\nThis is equivalent to negating the mask returned by `simd_eq`."]
12913    fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self;
12914    #[doc = "Returns true if any logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
12915    fn any_true(self) -> bool;
12916    #[doc = "Returns true if all logical lanes in this mask are true.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
12917    fn all_true(self) -> bool;
12918    #[doc = "Returns true if any logical lanes in this mask are false.\n\nThis is logically equivalent to `!all_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
12919    fn any_false(self) -> bool;
12920    #[doc = "Returns true if all logical lanes in this mask are false.\n\nThis is logically equivalent to `!any_true`, but may be faster.\n\nMasks may be converted to and from signed integer lane arrays for compatibility with older APIs. For those conversions, false is encoded as all zeroes (integer value 0) and true is encoded as all ones (integer value -1).\n\nBehavior on masks constructed from any other integer bit pattern is unspecified. It may vary depending on architecture, feature level, the mask elements' width, the mask vector's width, or library version.\n\nThe behavior is also not guaranteed to be logically consistent for such non-canonical masks. `any_true` may not return the same result as `!all_false`, and `all_true` may not return the same result as `!any_false`.\n\nThe [`select`](crate::Select::select) operation also has unspecified behavior for non-canonical masks. That behavior may not match the behavior of this operation."]
12921    fn all_false(self) -> bool;
12922}