Coverage Report

Created: 2026-08-31 07:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/pulp-0.22.3/src/x86/v3.rs
Line
Count
Source
1
use super::*;
2
3
// https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels
4
simd_type!({
5
  /// AVX instruction set.
6
  ///
7
  /// Notable additions over [`V2`] include:
8
  ///  - Instructions operating on 256-bit SIMD vectors.
9
  ///  - Shift functions with a separate shift per lane, such as [`V3::shl_dyn_u32x4`].
10
  ///  - Fused multiply-accumulate instructions, such as [`V3::mul_add_f32x4`].
11
  #[allow(missing_docs)]
12
  pub struct V3 {
13
    pub sse: f!("sse"),
14
    pub sse2: f!("sse2"),
15
    pub fxsr: f!("fxsr"),
16
    pub sse3: f!("sse3"),
17
    pub ssse3: f!("ssse3"),
18
    pub sse4_1: f!("sse4.1"),
19
    pub sse4_2: f!("sse4.2"),
20
    pub popcnt: f!("popcnt"),
21
    pub avx: f!("avx"),
22
    pub avx2: f!("avx2"),
23
    pub bmi1: f!("bmi1"),
24
    pub bmi2: f!("bmi2"),
25
    pub fma: f!("fma"),
26
    pub lzcnt: f!("lzcnt"),
27
  }
28
});
29
30
// copied from the standard library
31
#[inline(always)]
32
0
fn avx2_pshufb(simd: V3, bytes: __m256i, idxs: __m256i) -> __m256i {
33
0
  let mid = simd.avx._mm256_set1_epi8(16i8);
34
0
  let high = simd.avx._mm256_set1_epi8(32i8);
35
  // This is ordering sensitive, and LLVM will order these how you put them.
36
  // Most AVX2 impls use ~5 "ports", and only 1 or 2 are capable of permutes.
37
  // But the "compose" step will lower to ops that can also use at least 1 other port.
38
  // So this tries to break up permutes so composition flows through "open" ports.
39
  // Comparative benches should be done on multiple AVX2 CPUs before reordering this
40
41
0
  let hihi = simd.avx2._mm256_permute2x128_si256::<0x11>(bytes, bytes);
42
0
  let hi_shuf = simd.avx2._mm256_shuffle_epi8(
43
0
    hihi, // duplicate the vector's top half
44
0
    idxs, // so that using only 4 bits of an index still picks bytes 16-31
45
  );
46
  // A zero-fill during the compose step gives the "all-Neon-like" OOB-is-0 semantics
47
0
  let compose = simd.avx2._mm256_blendv_epi8(
48
0
    simd.avx._mm256_set1_epi8(0),
49
0
    hi_shuf,
50
0
    simd.avx2._mm256_cmpgt_epi8(high, idxs),
51
  );
52
0
  let lolo = simd.avx2._mm256_permute2x128_si256::<0x00>(bytes, bytes);
53
0
  let lo_shuf = simd.avx2._mm256_shuffle_epi8(lolo, idxs);
54
  // Repeat, then pick indices < 16, overwriting indices 0-15 from previous compose step
55
0
  simd.avx2
56
0
    ._mm256_blendv_epi8(compose, lo_shuf, simd.avx2._mm256_cmpgt_epi8(mid, idxs))
57
0
}
58
59
static AVX2_ROTATE_IDX: [u8x32; 32] = [
60
  u8x32(
61
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
62
    25, 26, 27, 28, 29, 30, 31,
63
  ),
64
  u8x32(
65
    31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
66
    24, 25, 26, 27, 28, 29, 30,
67
  ),
68
  u8x32(
69
    30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
70
    23, 24, 25, 26, 27, 28, 29,
71
  ),
72
  u8x32(
73
    29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
74
    22, 23, 24, 25, 26, 27, 28,
75
  ),
76
  u8x32(
77
    28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
78
    21, 22, 23, 24, 25, 26, 27,
79
  ),
80
  u8x32(
81
    27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
82
    20, 21, 22, 23, 24, 25, 26,
83
  ),
84
  u8x32(
85
    26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
86
    19, 20, 21, 22, 23, 24, 25,
87
  ),
88
  u8x32(
89
    25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
90
    18, 19, 20, 21, 22, 23, 24,
91
  ),
92
  u8x32(
93
    24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
94
    17, 18, 19, 20, 21, 22, 23,
95
  ),
96
  u8x32(
97
    23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
98
    16, 17, 18, 19, 20, 21, 22,
99
  ),
100
  u8x32(
101
    22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
102
    15, 16, 17, 18, 19, 20, 21,
103
  ),
104
  u8x32(
105
    21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
106
    14, 15, 16, 17, 18, 19, 20,
107
  ),
108
  u8x32(
109
    20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
110
    13, 14, 15, 16, 17, 18, 19,
111
  ),
112
  u8x32(
113
    19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
114
    12, 13, 14, 15, 16, 17, 18,
115
  ),
116
  u8x32(
117
    18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
118
    11, 12, 13, 14, 15, 16, 17,
119
  ),
120
  u8x32(
121
    17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
122
    10, 11, 12, 13, 14, 15, 16,
123
  ),
124
  u8x32(
125
    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7, 8,
126
    9, 10, 11, 12, 13, 14, 15,
127
  ),
128
  u8x32(
129
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6, 7,
130
    8, 9, 10, 11, 12, 13, 14,
131
  ),
132
  u8x32(
133
    14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5,
134
    6, 7, 8, 9, 10, 11, 12, 13,
135
  ),
136
  u8x32(
137
    13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4,
138
    5, 6, 7, 8, 9, 10, 11, 12,
139
  ),
140
  u8x32(
141
    12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3,
142
    4, 5, 6, 7, 8, 9, 10, 11,
143
  ),
144
  u8x32(
145
    11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1,
146
    2, 3, 4, 5, 6, 7, 8, 9, 10,
147
  ),
148
  u8x32(
149
    10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0,
150
    1, 2, 3, 4, 5, 6, 7, 8, 9,
151
  ),
152
  u8x32(
153
    9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
154
    0, 1, 2, 3, 4, 5, 6, 7, 8,
155
  ),
156
  u8x32(
157
    8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
158
    31, 0, 1, 2, 3, 4, 5, 6, 7,
159
  ),
160
  u8x32(
161
    7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
162
    30, 31, 0, 1, 2, 3, 4, 5, 6,
163
  ),
164
  u8x32(
165
    6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
166
    30, 31, 0, 1, 2, 3, 4, 5,
167
  ),
168
  u8x32(
169
    5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
170
    29, 30, 31, 0, 1, 2, 3, 4,
171
  ),
172
  u8x32(
173
    4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
174
    28, 29, 30, 31, 0, 1, 2, 3,
175
  ),
176
  u8x32(
177
    3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
178
    27, 28, 29, 30, 31, 0, 1, 2,
179
  ),
180
  u8x32(
181
    2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
182
    27, 28, 29, 30, 31, 0, 1,
183
  ),
184
  u8x32(
185
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
186
    26, 27, 28, 29, 30, 31, 0,
187
  ),
188
];
189
190
static AVX2_128_ROTATE_IDX: [u8x16; 16] = [
191
  u8x16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15),
192
  u8x16(15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14),
193
  u8x16(14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13),
194
  u8x16(13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12),
195
  u8x16(12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11),
196
  u8x16(11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
197
  u8x16(10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9),
198
  u8x16(9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8),
199
  u8x16(8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7),
200
  u8x16(7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6),
201
  u8x16(6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5),
202
  u8x16(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4),
203
  u8x16(4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3),
204
  u8x16(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2),
205
  u8x16(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1),
206
  u8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0),
207
];
208
209
static V3_U32_MASKS: [u32x8; 9] = [
210
  u32x8(0, 0, 0, 0, 0, 0, 0, 0),
211
  u32x8(!0, 0, 0, 0, 0, 0, 0, 0),
212
  u32x8(!0, !0, 0, 0, 0, 0, 0, 0),
213
  u32x8(!0, !0, !0, 0, 0, 0, 0, 0),
214
  u32x8(!0, !0, !0, !0, 0, 0, 0, 0),
215
  u32x8(!0, !0, !0, !0, !0, 0, 0, 0),
216
  u32x8(!0, !0, !0, !0, !0, !0, 0, 0),
217
  u32x8(!0, !0, !0, !0, !0, !0, !0, 0),
218
  u32x8(!0, !0, !0, !0, !0, !0, !0, !0),
219
];
220
static V3_U32_LAST_MASKS: [u32x8; 9] = [
221
  u32x8(0, 0, 0, 0, 0, 0, 0, 0),
222
  u32x8(0, 0, 0, 0, 0, 0, 0, !0),
223
  u32x8(0, 0, 0, 0, 0, 0, !0, !0),
224
  u32x8(0, 0, 0, 0, 0, !0, !0, !0),
225
  u32x8(0, 0, 0, 0, !0, !0, !0, !0),
226
  u32x8(0, 0, 0, !0, !0, !0, !0, !0),
227
  u32x8(0, 0, !0, !0, !0, !0, !0, !0),
228
  u32x8(0, !0, !0, !0, !0, !0, !0, !0),
229
  u32x8(!0, !0, !0, !0, !0, !0, !0, !0),
230
];
231
232
impl Seal for V3 {}
233
impl Seal for V3_Scalar {}
234
235
#[derive(Copy, Clone, Debug)]
236
#[repr(transparent)]
237
pub struct V3_Scalar(pub V3);
238
239
#[cfg(target_arch = "x86_64")]
240
#[inline(always)]
241
0
pub(super) fn avx_load_u32s(simd: Avx2, slice: &[u32]) -> u32x8 {
242
0
  _ = simd;
243
0
  unsafe { avx_ld_u32s(slice.as_ptr(), LD_ST[2 * (16 * slice.len().min(8))]) }
244
0
}
245
246
#[cfg(target_arch = "x86_64")]
247
#[inline(always)]
248
0
pub(super) fn avx_store_u32s(simd: Avx2, slice: &mut [u32], value: u32x8) {
249
0
  _ = simd;
250
0
  unsafe {
251
0
    avx_st_u32s(
252
0
      slice.as_mut_ptr(),
253
0
      value,
254
0
      LD_ST[2 * (16 * slice.len().min(8)) + 1],
255
0
    );
256
0
  }
257
0
}
258
259
impl core::ops::Deref for V3 {
260
  type Target = V2;
261
262
  #[inline(always)]
263
0
  fn deref(&self) -> &Self::Target {
264
0
    V2 {
265
0
      sse: self.sse,
266
0
      sse2: self.sse2,
267
0
      fxsr: self.fxsr,
268
0
      sse3: self.sse3,
269
0
      ssse3: self.ssse3,
270
0
      sse4_1: self.sse4_1,
271
0
      sse4_2: self.sse4_2,
272
0
      popcnt: self.popcnt,
273
0
    }
274
0
    .to_ref()
275
0
  }
276
}
277
278
macro_rules! splat {
279
  ($ty: ty, $factor: literal) => {
280
    paste! {
281
      #[inline(always)]
282
0
      fn [<splat_ $ty s>](self, value: $ty) -> Self::[<$ty s>] {
283
0
        self.[<splat_ $ty x $factor>](value)
284
0
      }
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::splat_f32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::splat_f64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::splat_i16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::splat_i32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::splat_i64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::splat_u16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::splat_u32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::splat_u64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::splat_i8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::splat_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::splat_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::splat_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::splat_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::splat_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::splat_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::splat_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::splat_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::splat_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::splat_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::splat_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::splat_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::splat_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::splat_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::splat_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::splat_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::splat_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::splat_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::splat_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::splat_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::splat_u8s
285
    }
286
  };
287
  ($($ty: ident x $factor: literal),*) => {
288
    $(splat!($ty, $factor);)*
289
  };
290
}
291
292
macro_rules! impl_simd_binop {
293
  ($func: ident, $op: ident, $ty: ident, $out: ty, $factor: literal) => {
294
    paste! {
295
      #[inline(always)]
296
0
      fn [<$func _ $ty s>](self, a: Self::[<$ty s>], b: Self::[<$ty s>]) -> Self::[<$out s>] {
297
0
        self.[<$op _ $ty x $factor>](a, b)
298
0
      }
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::equal_f32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::equal_f64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::equal_u16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::equal_u32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::equal_u64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_i8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_u8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_f32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_f64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_i16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_i32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_i64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_u16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_u32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_u64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_i8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_u8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_f32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_f64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_i16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_i32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_i64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_u16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_u32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_u64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_or_equal_i8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_or_equal_u8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_or_equal_f32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_or_equal_f64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_or_equal_i16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_or_equal_i32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_or_equal_i64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_or_equal_u16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_or_equal_u32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::less_than_or_equal_u64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_or_equal_i8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_or_equal_u8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_or_equal_f32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_or_equal_f64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_or_equal_i16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_or_equal_i32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_or_equal_i64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_or_equal_u16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_or_equal_u32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::greater_than_or_equal_u64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::or_i8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::or_m8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::or_u8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::add_i8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::add_u8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::and_i8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::and_m8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::and_u8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::max_i8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::max_u8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::min_i8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::min_u8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::or_f32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::or_f64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::or_i16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::or_i32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::or_i64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::or_m16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::or_m32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::or_m64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::or_u16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::or_u32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::or_u64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::sub_i8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::sub_u8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::xor_i8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::xor_m8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::xor_u8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::add_f32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::add_f64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::add_i16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::add_i32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::add_i64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::add_u16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::add_u32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::add_u64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::and_f32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::and_f64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::and_i16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::and_i32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::and_i64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::and_m16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::and_m32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::and_m64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::and_u16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::and_u32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::and_u64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::div_f32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::div_f64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::max_f32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::max_f64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::max_i16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::max_i32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::max_u16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::max_u32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::min_f32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::min_f64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::min_i16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::min_i32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::min_u16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::min_u32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::mul_f32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::mul_f64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::mul_i16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::mul_i32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::mul_u16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::mul_u32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::sub_f32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::sub_f64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::sub_i16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::sub_i32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::sub_i64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::sub_u16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::sub_u32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::sub_u64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::xor_f32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::xor_f64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::xor_i16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::xor_i32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::xor_i64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::xor_m16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::xor_m32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::xor_m64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::xor_u16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::xor_u32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::xor_u64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::equal_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::equal_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::equal_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::equal_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::equal_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::equal_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_or_equal_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_or_equal_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_or_equal_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_or_equal_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_or_equal_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_or_equal_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_or_equal_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_or_equal_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_or_equal_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::less_than_or_equal_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_or_equal_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_or_equal_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_or_equal_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_or_equal_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_or_equal_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_or_equal_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_or_equal_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_or_equal_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_or_equal_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::greater_than_or_equal_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::or_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::or_m8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::or_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::add_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::add_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::and_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::and_m8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::and_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::max_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::max_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::min_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::min_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::or_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::or_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::or_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::or_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::or_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::or_m16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::or_m32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::or_m64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::or_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::or_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::or_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::sub_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::sub_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::xor_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::xor_m8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::xor_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::add_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::add_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::add_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::add_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::add_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::add_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::add_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::add_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::and_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::and_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::and_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::and_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::and_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::and_m16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::and_m32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::and_m64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::and_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::and_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::and_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::div_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::div_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::max_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::max_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::max_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::max_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::max_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::max_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::min_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::min_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::min_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::min_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::min_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::min_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::mul_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::mul_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::mul_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::mul_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::mul_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::mul_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::sub_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::sub_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::sub_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::sub_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::sub_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::sub_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::sub_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::sub_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::xor_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::xor_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::xor_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::xor_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::xor_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::xor_m16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::xor_m32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::xor_m64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::xor_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::xor_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::xor_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::equal_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::equal_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::equal_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::equal_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::equal_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::equal_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_or_equal_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_or_equal_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_or_equal_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_or_equal_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_or_equal_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_or_equal_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_or_equal_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_or_equal_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_or_equal_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::less_than_or_equal_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_or_equal_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_or_equal_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_or_equal_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_or_equal_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_or_equal_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_or_equal_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_or_equal_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_or_equal_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_or_equal_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::greater_than_or_equal_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::or_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::or_m8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::or_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::add_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::add_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::and_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::and_m8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::and_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::max_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::max_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::min_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::min_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::or_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::or_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::or_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::or_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::or_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::or_m16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::or_m32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::or_m64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::or_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::or_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::or_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::sub_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::sub_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::xor_i8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::xor_m8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::xor_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::add_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::add_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::add_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::add_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::add_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::add_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::add_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::add_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::and_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::and_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::and_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::and_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::and_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::and_m16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::and_m32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::and_m64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::and_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::and_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::and_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::div_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::div_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::max_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::max_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::max_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::max_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::max_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::max_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::min_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::min_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::min_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::min_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::min_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::min_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::mul_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::mul_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::mul_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::mul_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::mul_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::mul_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::sub_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::sub_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::sub_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::sub_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::sub_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::sub_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::sub_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::sub_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::xor_f32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::xor_f64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::xor_i16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::xor_i32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::xor_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::xor_m16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::xor_m32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::xor_m64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::xor_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::xor_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::xor_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::equal_u8s
299
    }
300
  };
301
  ($func: ident, $op: ident, $($ty: ident x $factor: literal => $out: ty),*) => {
302
    $(impl_simd_binop!($func, $op, $ty, $out, $factor);)*
303
  };
304
  ($func: ident, $op: ident, $($ty: ident x $factor: literal),*) => {
305
    $(impl_simd_binop!($func, $op, $ty, $ty, $factor);)*
306
  };
307
  ($func: ident, $($ty: ident x $factor: literal => $out: ty),*) => {
308
    $(impl_simd_binop!($func, $func, $ty, $out, $factor);)*
309
  };
310
  ($func: ident, $($ty: ident x $factor: literal),*) => {
311
    $(impl_simd_binop!($func, $func, $ty, $ty, $factor);)*
312
  };
313
}
314
315
macro_rules! impl_simd_unop {
316
  ($func: ident, $op: ident, $ty: ident, $out: ty, $factor: literal) => {
317
    paste! {
318
      #[inline(always)]
319
0
      fn [<$func _ $ty s>](self, a: Self::[<$ty s>]) -> Self::[<$out s>] {
320
0
        self.[<$op _ $ty x $factor>](a)
321
0
      }
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::not_m8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::not_u8s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::not_m16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::not_m32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::not_m64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::not_u16s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::not_u32s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::not_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::not_m8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::not_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::not_m16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::not_m32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::not_m64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::not_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::not_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::not_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::not_m8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::not_u8s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::not_m16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::not_m32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::not_m64s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::not_u16s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::not_u32s
Unexecuted instantiation: <pulp::x86::v3::V3_256b as pulp::Simd>::not_u64s
322
    }
323
  };
324
  ($func: ident, $($ty: ident x $factor: literal),*) => {
325
    $(impl_simd_unop!($func, $func, $ty, $ty, $factor);)*
326
  };
327
}
328
329
macro_rules! impl_scalar_binop {
330
  ($func: ident, $ty: ident, $out: ty, impl) => {
331
    paste! {
332
      #[inline(always)]
333
0
      fn [<$func _ $ty s>](self, a: Self::[<$ty s>], b: Self::[<$ty s>]) -> Self::[<$out s>] {
334
0
        Scalar256b.[<$func _ $ty s>](a, b)
335
0
      }
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::max_i64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::max_u64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::min_i64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::min_u64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::mul_i64s
Unexecuted instantiation: <pulp::x86::v3::V3 as pulp::Simd>::mul_u64s
336
    }
337
  };
338
  ($func: ident, $($ty: ident => $out: ty),*) => {
339
    $(impl_scalar_binop!($func, $ty, $out, impl);)*
340
  };
341
  ($func: ident, $($ty: ident),*) => {
342
    $(impl_scalar_binop!($func, $ty, $ty, impl);)*
343
  };
344
}
345
346
impl Simd for V3 {
347
  type c32s = f32x8;
348
  type c64s = f64x4;
349
  type f32s = f32x8;
350
  type f64s = f64x4;
351
  type i16s = i16x16;
352
  type i32s = i32x8;
353
  type i64s = i64x4;
354
  type i8s = i8x32;
355
  type m16s = m16x16;
356
  type m32s = m32x8;
357
  type m64s = m64x4;
358
  type m8s = m8x32;
359
  type u16s = u16x16;
360
  type u32s = u32x8;
361
  type u64s = u64x4;
362
  type u8s = u8x32;
363
364
  const REGISTER_COUNT: usize = 16;
365
366
  impl_simd_binop!(add, f32 x 8, f64 x 4);
367
368
  impl_simd_binop!(add, wrapping_add, u8 x 32, i8 x 32, u16 x 16, i16 x 16, u32 x 8, i32 x 8, u64 x 4, i64 x 4);
369
370
  impl_simd_binop!(sub, f32 x 8, f64 x 4);
371
372
  impl_simd_binop!(sub, wrapping_sub, u8 x 32, i8 x 32, u16 x 16, i16 x 16, u32 x 8, i32 x 8, u64 x 4, i64 x 4);
373
374
  impl_simd_binop!(mul, f32 x 8, f64 x 4);
375
376
  impl_simd_binop!(mul, wrapping_mul, u16 x 16, i16 x 16, u32 x 8, i32 x 8);
377
378
  impl_scalar_binop!(mul, u64, i64);
379
380
  impl_simd_binop!(and, m8 x 32, u8 x 32, i8 x 32, m16 x 16, u16 x 16, i16 x 16, m32 x 8, u32 x 8, i32 x 8, m64 x 4, u64 x 4, i64 x 4, f32 x 8, f64 x 4);
381
382
  impl_simd_binop!(or, m8 x 32, u8 x 32, i8 x 32, m16 x 16, u16 x 16, i16 x 16, m32 x 8, u32 x 8, i32 x 8, m64 x 4, u64 x 4, i64 x 4, f32 x 8, f64 x 4);
383
384
  impl_simd_binop!(xor, m8 x 32, u8 x 32, i8 x 32, m16 x 16, u16 x 16, i16 x 16, m32 x 8, u32 x 8, i32 x 8, m64 x 4, u64 x 4, i64 x 4, f32 x 8, f64 x 4);
385
386
  impl_simd_binop!(div, f32 x 8, f64 x 4);
387
388
  impl_simd_binop!(equal, cmp_eq, u8 x 32 => m8, u16 x 16 => m16, u32 x 8 => m32, u64 x 4 => m64, f32 x 8 => m32, f64 x 4 => m64);
389
390
  impl_simd_binop!(greater_than, cmp_gt, u8 x 32 => m8, i8 x 32 => m8, u16 x 16 => m16, i16 x 16 => m16, u32 x 8 => m32, i32 x 8 => m32, u64 x 4 => m64, i64 x 4 => m64, f32 x 8 => m32, f64 x 4 => m64);
391
392
  impl_simd_binop!(greater_than_or_equal, cmp_ge, u8 x 32 => m8, i8 x 32 => m8, u16 x 16 => m16, i16 x 16 => m16, u32 x 8 => m32, i32 x 8 => m32, u64 x 4 => m64, i64 x 4 => m64, f32 x 8 => m32, f64 x 4 => m64);
393
394
  impl_simd_binop!(less_than, cmp_lt, u8 x 32 => m8, i8 x 32 => m8, u16 x 16 => m16, i16 x 16 => m16, u32 x 8 => m32, i32 x 8 => m32, u64 x 4 => m64, i64 x 4 => m64, f32 x 8 => m32, f64 x 4 => m64);
395
396
  impl_simd_binop!(less_than_or_equal, cmp_le, u8 x 32 => m8, i8 x 32 => m8, u16 x 16 => m16, i16 x 16 => m16, u32 x 8 => m32, i32 x 8 => m32, u64 x 4 => m64, i64 x 4 => m64, f32 x 8 => m32, f64 x 4 => m64);
397
398
  splat!(u8 x 32, i8 x 32, u16 x 16, i16 x 16, u32 x 8, i32 x 8, u64 x 4, i64 x 4, f32 x 8, f64 x 4);
399
400
  impl_simd_binop!(max, u8 x 32, i8 x 32, u16 x 16, i16 x 16, u32 x 8, i32 x 8, f32 x 8, f64 x 4);
401
402
  impl_scalar_binop!(max, u64, i64);
403
404
  impl_simd_binop!(min, u8 x 32, i8 x 32, u16 x 16, i16 x 16, u32 x 8, i32 x 8, f32 x 8, f64 x 4);
405
406
  impl_scalar_binop!(min, u64, i64);
407
408
  impl_simd_unop!(not, m8 x 32, u8 x 32, m16 x 16, u16 x 16, m32 x 8, u32 x 8, m64 x 4, u64 x 4);
409
410
  #[inline(always)]
411
0
  fn abs2_c32s(self, a: Self::c32s) -> Self::c32s {
412
0
    let sqr = self.mul_f32s(a, a);
413
0
    let sqr_rev = self
414
0
      .avx
415
0
      ._mm256_shuffle_ps::<0b10_11_00_01>(cast!(sqr), cast!(sqr));
416
0
    self.add_f32s(sqr, cast!(sqr_rev))
417
0
  }
418
419
  #[inline(always)]
420
0
  fn abs2_c64s(self, a: Self::c64s) -> Self::c64s {
421
0
    let sqr = self.mul_f64s(a, a);
422
0
    let sqr_rev = self.avx._mm256_shuffle_pd::<0b0101>(cast!(sqr), cast!(sqr));
423
0
    self.add_f64s(sqr, cast!(sqr_rev))
424
0
  }
425
426
  #[inline(always)]
427
0
  fn abs_max_c32s(self, a: Self::c32s) -> Self::c32s {
428
0
    let max = self.abs_f32s(a);
429
0
    let max_rev = self
430
0
      .avx
431
0
      ._mm256_shuffle_ps::<0b10_11_00_01>(cast!(a), cast!(a));
432
0
    self.max_f32s(max, cast!(max_rev))
433
0
  }
434
435
  #[inline(always)]
436
0
  fn abs_max_c64s(self, a: Self::c64s) -> Self::c64s {
437
0
    let max = self.abs_f64s(a);
438
0
    let max_rev = self.avx._mm256_shuffle_pd::<0b0101>(cast!(max), cast!(max));
439
0
    self.max_f64s(max, cast!(max_rev))
440
0
  }
441
442
  #[inline(always)]
443
0
  fn add_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::c32s {
444
0
    self.add_f32s(a, b)
445
0
  }
446
447
  #[inline(always)]
448
0
  fn add_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::c64s {
449
0
    self.add_f64s(a, b)
450
0
  }
451
452
  #[inline(always)]
453
0
  fn equal_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::m32s {
454
0
    self.equal_f32s(a, b)
455
0
  }
456
457
  #[inline(always)]
458
0
  fn equal_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::m64s {
459
0
    self.equal_f64s(a, b)
460
0
  }
461
462
  #[inline(always)]
463
0
  fn conj_c32s(self, a: Self::c32s) -> Self::c32s {
464
0
    self.xor_f32s(a, self.splat_c32s(c32 { re: 0.0, im: -0.0 }))
465
0
  }
466
467
  #[inline(always)]
468
0
  fn conj_c64s(self, a: Self::c64s) -> Self::c64s {
469
0
    self.xor_f64s(a, self.splat_c64s(c64 { re: 0.0, im: -0.0 }))
470
0
  }
471
472
  #[inline(always)]
473
0
  fn conj_mul_add_c32s(self, a: Self::c32s, b: Self::c32s, c: Self::c32s) -> Self::c32s {
474
0
    let ab = cast!(a);
475
0
    let xy = cast!(b);
476
477
0
    let yx = self.avx._mm256_permute_ps::<0b10_11_00_01>(xy);
478
0
    let aa = self.avx._mm256_moveldup_ps(ab);
479
0
    let bb = self.avx._mm256_movehdup_ps(ab);
480
481
0
    cast!(
482
0
      self.fma
483
0
        ._mm256_fmsubadd_ps(aa, xy, self.fma._mm256_fmsubadd_ps(bb, yx, cast!(c)))
484
    )
485
0
  }
486
487
  #[inline(always)]
488
0
  fn conj_mul_add_c64s(self, a: Self::c64s, b: Self::c64s, c: Self::c64s) -> Self::c64s {
489
0
    let ab = cast!(a);
490
0
    let xy = cast!(b);
491
492
0
    let yx = self.avx._mm256_permute_pd::<0b0101>(xy);
493
0
    let aa = self.avx._mm256_unpacklo_pd(ab, ab);
494
0
    let bb = self.avx._mm256_unpackhi_pd(ab, ab);
495
496
0
    cast!(
497
0
      self.fma
498
0
        ._mm256_fmsubadd_pd(aa, xy, self.fma._mm256_fmsubadd_pd(bb, yx, cast!(c)))
499
    )
500
0
  }
501
502
  #[inline(always)]
503
0
  fn conj_mul_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::c32s {
504
0
    let ab = cast!(a);
505
0
    let xy = cast!(b);
506
507
0
    let yx = self.avx._mm256_permute_ps::<0b10_11_00_01>(xy);
508
0
    let aa = self.avx._mm256_moveldup_ps(ab);
509
0
    let bb = self.avx._mm256_movehdup_ps(ab);
510
511
0
    cast!(
512
0
      self.fma
513
0
        ._mm256_fmsubadd_ps(aa, xy, self.avx._mm256_mul_ps(bb, yx))
514
    )
515
0
  }
516
517
  #[inline(always)]
518
0
  fn conj_mul_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::c64s {
519
0
    let ab = cast!(a);
520
0
    let xy = cast!(b);
521
522
0
    let yx = self.avx._mm256_permute_pd::<0b0101>(xy);
523
0
    let aa = self.avx._mm256_unpacklo_pd(ab, ab);
524
0
    let bb = self.avx._mm256_unpackhi_pd(ab, ab);
525
526
0
    cast!(
527
0
      self.fma
528
0
        ._mm256_fmsubadd_pd(aa, xy, self.avx._mm256_mul_pd(bb, yx))
529
    )
530
0
  }
531
532
  #[inline(always)]
533
0
  fn deinterleave_shfl_f32s<T: Interleave>(self, values: T) -> T {
534
0
    let avx = self.avx;
535
536
    if const { core::mem::size_of::<T>() == 2 * core::mem::size_of::<Self::f32s>() } {
537
0
      let values: [__m256d; 2] = unsafe { core::mem::transmute_copy(&values) };
538
      // a0 b0 a1 b1 a2 b2 a3 b3
539
      // a4 b4 a5 b5 a6 b6 a7 b7
540
541
      // a0 a4 b0 b4 a2 a6 b2 b6
542
      // a1 a5 b1 b5 a3 a7 b3 b7
543
0
      let values = [
544
0
        cast!(avx._mm256_unpacklo_ps(cast!(values[0]), cast!(values[1]))),
545
0
        cast!(avx._mm256_unpackhi_ps(cast!(values[0]), cast!(values[1]))),
546
      ];
547
548
      // a0 a4 a1 a5 a2 a6 a3 a7
549
      // b0 b4 b1 b5 b2 b6 b3 b7
550
0
      let values = [
551
0
        avx._mm256_unpacklo_pd(values[0], values[1]),
552
0
        avx._mm256_unpackhi_pd(values[0], values[1]),
553
0
      ];
554
555
0
      unsafe { core::mem::transmute_copy(&values) }
556
    } else if const { core::mem::size_of::<T>() == 4 * core::mem::size_of::<Self::f32s>() } {
557
      // a0 b0 c0 d0 a1 b1 c1 d1
558
      // a2 b2 c2 d2 a3 b3 c3 d3
559
      // a4 b4 c4 d4 a5 b5 c5 d5
560
      // a6 b6 c6 d6 a7 b7 c7 d7
561
0
      let values: [__m256d; 4] = unsafe { core::mem::transmute_copy(&values) };
562
563
      // a0 a2 c0 c2 a1 a3 c1 c3
564
      // b0 b2 d0 d2 b1 b3 d1 d3
565
      // a4 a6 c4 c6 a5 a7 c5 c7
566
      // b4 b6 d4 d6 b5 b7 d5 d7
567
0
      let values = [
568
0
        cast!(avx._mm256_unpacklo_ps(cast!(values[0]), cast!(values[1]))),
569
0
        cast!(avx._mm256_unpackhi_ps(cast!(values[0]), cast!(values[1]))),
570
0
        cast!(avx._mm256_unpacklo_ps(cast!(values[2]), cast!(values[3]))),
571
0
        cast!(avx._mm256_unpackhi_ps(cast!(values[2]), cast!(values[3]))),
572
      ];
573
574
0
      let values = [
575
0
        avx._mm256_unpacklo_pd(values[0], values[1]),
576
0
        avx._mm256_unpackhi_pd(values[0], values[1]),
577
0
        avx._mm256_unpacklo_pd(values[2], values[3]),
578
0
        avx._mm256_unpackhi_pd(values[2], values[3]),
579
0
      ];
580
581
      // a0 a2 a4 a6 a1 a3 a5 a7
582
      // b0 b2 b4 b6 b1 b3 b5 b7
583
      // c0 c2 c4 c6 c1 c3 c5 c7
584
      // d0 d2 d4 d6 d1 d3 d5 d7
585
0
      let values = [
586
0
        avx._mm256_unpacklo_pd(values[0], values[2]),
587
0
        avx._mm256_unpacklo_pd(values[1], values[3]),
588
0
        avx._mm256_unpackhi_pd(values[0], values[2]),
589
0
        avx._mm256_unpackhi_pd(values[1], values[3]),
590
0
      ];
591
592
0
      unsafe { core::mem::transmute_copy(&values) }
593
    } else {
594
0
      unsafe { deinterleave_fallback::<f32, Self::f32s, T>(values) }
595
    }
596
0
  }
597
598
  #[inline(always)]
599
0
  fn deinterleave_shfl_f64s<T: Interleave>(self, values: T) -> T {
600
0
    let avx = self.avx;
601
602
    if const { core::mem::size_of::<T>() == 2 * core::mem::size_of::<Self::f64s>() } {
603
0
      let values: [__m256d; 2] = unsafe { core::mem::transmute_copy(&values) };
604
0
      let values = [
605
0
        avx._mm256_unpacklo_pd(values[0], values[1]),
606
0
        avx._mm256_unpackhi_pd(values[0], values[1]),
607
0
      ];
608
0
      unsafe { core::mem::transmute_copy(&values) }
609
    } else if const { core::mem::size_of::<T>() == 4 * core::mem::size_of::<Self::f64s>() } {
610
0
      let values: [__m256d; 4] = unsafe { core::mem::transmute_copy(&values) };
611
612
      // a0 b0 c0 d0
613
      // a1 b1 c1 d1
614
      // a2 b2 c2 d2
615
      // a3 b3 c3 d3
616
617
      // a0 a1 c0 c1
618
      // b0 b1 d0 d1
619
      // a2 a3 c2 c3
620
      // b2 b3 d2 d3
621
0
      let values: [__m256d; 4] = [
622
0
        avx._mm256_unpacklo_pd(values[0], values[1]),
623
0
        avx._mm256_unpackhi_pd(values[0], values[1]),
624
0
        avx._mm256_unpacklo_pd(values[2], values[3]),
625
0
        avx._mm256_unpackhi_pd(values[2], values[3]),
626
0
      ];
627
628
      // a0 a1 a2 a3
629
      // b0 b1 b2 b3
630
      // c0 c1 c2 c3
631
      // d0 d1 d2 d3
632
0
      let values = [
633
0
        avx._mm256_permute2f128_pd::<0b0010_0000>(values[0], values[2]),
634
0
        avx._mm256_permute2f128_pd::<0b0010_0000>(values[1], values[3]),
635
0
        avx._mm256_permute2f128_pd::<0b0011_0001>(values[0], values[2]),
636
0
        avx._mm256_permute2f128_pd::<0b0011_0001>(values[1], values[3]),
637
0
      ];
638
639
0
      unsafe { core::mem::transmute_copy(&values) }
640
    } else {
641
0
      unsafe { deinterleave_fallback::<f64, Self::f64s, T>(values) }
642
    }
643
0
  }
644
645
  #[inline(always)]
646
0
  fn interleave_shfl_f32s<T: Interleave>(self, values: T) -> T {
647
    if const {
648
      (core::mem::size_of::<T>() == 2 * core::mem::size_of::<Self::f32s>())
649
        || (core::mem::size_of::<T>() == 4 * core::mem::size_of::<Self::f32s>())
650
    } {
651
      // permutation is inverse of itself in this case
652
0
      self.deinterleave_shfl_f32s(values)
653
    } else {
654
0
      unsafe { interleave_fallback::<f32, Self::f32s, T>(values) }
655
    }
656
0
  }
657
658
  #[inline(always)]
659
0
  fn interleave_shfl_f64s<T: Interleave>(self, values: T) -> T {
660
    if const {
661
      (core::mem::size_of::<T>() == 2 * core::mem::size_of::<Self::f64s>())
662
        || (core::mem::size_of::<T>() == 4 * core::mem::size_of::<Self::f64s>())
663
    } {
664
      // permutation is inverse of itself in this case
665
0
      self.deinterleave_shfl_f64s(values)
666
    } else {
667
0
      unsafe { interleave_fallback::<f64, Self::f64s, T>(values) }
668
    }
669
0
  }
670
671
  #[inline(always)]
672
0
  fn mask_between_m32s(self, start: u32, end: u32) -> MemMask<Self::m32s> {
673
0
    let start = start.min(8) as usize;
674
0
    let end = end.min(8) as usize;
675
    MemMask {
676
0
      mask: self.and_m32s(
677
0
        cast!(V3_U32_LAST_MASKS[8 - start]),
678
0
        cast!(V3_U32_MASKS[end]),
679
      ),
680
      #[cfg(target_arch = "x86_64")]
681
0
      load: Some(LD_ST[2 * (16 * end + start) + 0]),
682
      #[cfg(target_arch = "x86_64")]
683
0
      store: Some(LD_ST[2 * (16 * end + start) + 1]),
684
    }
685
0
  }
686
687
  #[inline(always)]
688
0
  fn mask_between_m64s(self, start: u64, end: u64) -> MemMask<Self::m64s> {
689
0
    let start = (2 * start.min(4)) as usize;
690
0
    let end = (2 * end.min(4)) as usize;
691
    MemMask {
692
0
      mask: self.and_m64s(
693
0
        cast!(V3_U32_LAST_MASKS[8 - start]),
694
0
        cast!(V3_U32_MASKS[end]),
695
      ),
696
      #[cfg(target_arch = "x86_64")]
697
0
      load: Some(LD_ST[2 * (16 * end + start) + 0]),
698
      #[cfg(target_arch = "x86_64")]
699
0
      store: Some(LD_ST[2 * (16 * end + start) + 1]),
700
    }
701
0
  }
702
703
  /// # Safety
704
  ///
705
  /// See the trait-level safety documentation.
706
  #[inline(always)]
707
0
  unsafe fn mask_load_ptr_c32s(self, mask: MemMask<Self::m32s>, ptr: *const c32) -> Self::c32s {
708
0
    cast!(self.mask_load_ptr_u32s(mask, ptr as _))
709
0
  }
710
711
  /// # Safety
712
  ///
713
  /// See the trait-level safety documentation.
714
  #[inline(always)]
715
0
  unsafe fn mask_load_ptr_c64s(self, mask: MemMask<Self::m64s>, ptr: *const c64) -> Self::c64s {
716
0
    cast!(self.mask_load_ptr_u64s(mask, ptr as _))
717
0
  }
718
719
  /// # Safety
720
  ///
721
  /// See the trait-level safety documentation.
722
  #[inline(always)]
723
0
  unsafe fn mask_load_ptr_u8s(self, mask: MemMask<Self::m8s>, ptr: *const u8) -> Self::u8s {
724
0
    Scalar256b.mask_load_ptr_u8s(mask, ptr)
725
0
  }
726
727
  /// # Safety
728
  ///
729
  /// See the trait-level safety documentation.
730
  #[inline(always)]
731
0
  unsafe fn mask_load_ptr_u16s(self, mask: MemMask<Self::m16s>, ptr: *const u16) -> Self::u16s {
732
0
    Scalar256b.mask_load_ptr_u16s(mask, ptr)
733
0
  }
734
735
  /// # Safety
736
  ///
737
  /// See the trait-level safety documentation.
738
  #[inline(always)]
739
0
  unsafe fn mask_load_ptr_u32s(self, mask: MemMask<Self::m32s>, ptr: *const u32) -> Self::u32s {
740
    #[cfg(target_arch = "x86_64")]
741
0
    if let Some(load) = mask.load {
742
0
      return avx_ld_u32s(ptr, load);
743
0
    }
744
0
    cast!(self.avx2._mm256_maskload_epi32(ptr as _, cast!(mask.mask)))
745
0
  }
746
747
  /// # Safety
748
  ///
749
  /// See the trait-level safety documentation.
750
  #[inline(always)]
751
0
  unsafe fn mask_load_ptr_u64s(self, mask: MemMask<Self::m64s>, ptr: *const u64) -> Self::u64s {
752
    #[cfg(target_arch = "x86_64")]
753
0
    if let Some(load) = mask.load {
754
0
      return cast!(avx_ld_u32s(ptr as _, load));
755
0
    }
756
0
    cast!(self.avx2._mm256_maskload_epi64(ptr as _, cast!(mask.mask)))
757
0
  }
758
759
  /// # Safety
760
  ///
761
  /// See the trait-level safety documentation.
762
  #[inline(always)]
763
0
  unsafe fn mask_store_ptr_c32s(
764
0
    self,
765
0
    mask: MemMask<Self::m32s>,
766
0
    ptr: *mut c32,
767
0
    values: Self::c32s,
768
0
  ) {
769
0
    self.mask_store_ptr_u32s(mask, ptr as _, cast!(values))
770
0
  }
771
772
  /// # Safety
773
  ///
774
  /// See the trait-level safety documentation.
775
  #[inline(always)]
776
0
  unsafe fn mask_store_ptr_c64s(
777
0
    self,
778
0
    mask: MemMask<Self::m64s>,
779
0
    ptr: *mut c64,
780
0
    values: Self::c64s,
781
0
  ) {
782
0
    self.mask_store_ptr_u64s(mask, ptr as _, cast!(values))
783
0
  }
784
785
  /// # Safety
786
  ///
787
  /// See the trait-level safety documentation.
788
  #[inline(always)]
789
0
  unsafe fn mask_store_ptr_u8s(self, mask: MemMask<Self::m8s>, ptr: *mut u8, values: Self::u8s) {
790
0
    Scalar256b.mask_store_ptr_u8s(mask, ptr, values);
791
0
  }
792
793
  /// # Safety
794
  ///
795
  /// See the trait-level safety documentation.
796
  #[inline(always)]
797
0
  unsafe fn mask_store_ptr_u16s(
798
0
    self,
799
0
    mask: MemMask<Self::m16s>,
800
0
    ptr: *mut u16,
801
0
    values: Self::u16s,
802
0
  ) {
803
0
    Scalar256b.mask_store_ptr_u16s(mask, ptr, values);
804
0
  }
805
806
  /// # Safety
807
  ///
808
  /// See the trait-level safety documentation.
809
  #[inline(always)]
810
0
  unsafe fn mask_store_ptr_u32s(
811
0
    self,
812
0
    mask: MemMask<Self::m32s>,
813
0
    ptr: *mut u32,
814
0
    values: Self::u32s,
815
0
  ) {
816
    #[cfg(target_arch = "x86_64")]
817
0
    if let Some(store) = mask.store {
818
0
      return avx_st_u32s(ptr, values, store);
819
0
    }
820
0
    _mm256_maskstore_epi32(ptr as *mut i32, cast!(mask.mask), cast!(values))
821
0
  }
822
823
  /// # Safety
824
  ///
825
  /// See the trait-level safety documentation.
826
  #[inline(always)]
827
0
  unsafe fn mask_store_ptr_u64s(
828
0
    self,
829
0
    mask: MemMask<Self::m64s>,
830
0
    ptr: *mut u64,
831
0
    values: Self::u64s,
832
0
  ) {
833
0
    self.mask_store_ptr_u32s(
834
      MemMask {
835
0
        mask: cast!(mask.mask),
836
        #[cfg(target_arch = "x86_64")]
837
0
        load: mask.load,
838
        #[cfg(target_arch = "x86_64")]
839
0
        store: mask.store,
840
      },
841
0
      ptr as _,
842
0
      cast!(values),
843
    )
844
0
  }
845
846
  #[inline(always)]
847
0
  fn mul_add_c32s(self, a: Self::c32s, b: Self::c32s, c: Self::c32s) -> Self::c32s {
848
0
    let ab = cast!(a);
849
0
    let xy = cast!(b);
850
851
0
    let yx = self.avx._mm256_permute_ps::<0b10_11_00_01>(xy);
852
0
    let aa = self.avx._mm256_moveldup_ps(ab);
853
0
    let bb = self.avx._mm256_movehdup_ps(ab);
854
855
0
    cast!(
856
0
      self.fma
857
0
        ._mm256_fmaddsub_ps(aa, xy, self.fma._mm256_fmaddsub_ps(bb, yx, cast!(c)))
858
    )
859
0
  }
860
861
  #[inline(always)]
862
0
  fn mul_add_c64s(self, a: Self::c64s, b: Self::c64s, c: Self::c64s) -> Self::c64s {
863
0
    let ab = cast!(a);
864
0
    let xy = cast!(b);
865
866
0
    let yx = self.avx._mm256_permute_pd::<0b0101>(xy);
867
0
    let aa = self.avx._mm256_unpacklo_pd(ab, ab);
868
0
    let bb = self.avx._mm256_unpackhi_pd(ab, ab);
869
870
0
    cast!(
871
0
      self.fma
872
0
        ._mm256_fmaddsub_pd(aa, xy, self.fma._mm256_fmaddsub_pd(bb, yx, cast!(c)))
873
    )
874
0
  }
875
876
  #[inline(always)]
877
0
  fn mul_add_e_f32s(self, a: Self::f32s, b: Self::f32s, c: Self::f32s) -> Self::f32s {
878
0
    self.mul_add_f32s(a, b, c)
879
0
  }
880
881
  #[inline(always)]
882
0
  fn mul_add_e_f64s(self, a: Self::f64s, b: Self::f64s, c: Self::f64s) -> Self::f64s {
883
0
    self.mul_add_f64s(a, b, c)
884
0
  }
885
886
  #[inline(always)]
887
0
  fn mul_add_f32s(self, a: Self::f32s, b: Self::f32s, c: Self::f32s) -> Self::f32s {
888
0
    cast!(self.fma._mm256_fmadd_ps(cast!(a), cast!(b), cast!(c)))
889
0
  }
890
891
  #[inline(always)]
892
0
  fn mul_add_f64s(self, a: Self::f64s, b: Self::f64s, c: Self::f64s) -> Self::f64s {
893
0
    cast!(self.fma._mm256_fmadd_pd(cast!(a), cast!(b), cast!(c)))
894
0
  }
895
896
  #[inline(always)]
897
0
  fn negate_mul_add_e_f32s(self, a: Self::f32s, b: Self::f32s, c: Self::f32s) -> Self::f32s {
898
0
    self.negate_mul_add_f32s(a, b, c)
899
0
  }
900
901
  #[inline(always)]
902
0
  fn negate_mul_add_e_f64s(self, a: Self::f64s, b: Self::f64s, c: Self::f64s) -> Self::f64s {
903
0
    self.negate_mul_add_f64s(a, b, c)
904
0
  }
905
906
  #[inline(always)]
907
0
  fn negate_mul_add_f32s(self, a: Self::f32s, b: Self::f32s, c: Self::f32s) -> Self::f32s {
908
0
    cast!(self.fma._mm256_fnmadd_ps(cast!(a), cast!(b), cast!(c)))
909
0
  }
910
911
  #[inline(always)]
912
0
  fn negate_mul_add_f64s(self, a: Self::f64s, b: Self::f64s, c: Self::f64s) -> Self::f64s {
913
0
    cast!(self.fma._mm256_fnmadd_pd(cast!(a), cast!(b), cast!(c)))
914
0
  }
915
916
  #[inline(always)]
917
0
  fn mul_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::c32s {
918
0
    let ab = cast!(a);
919
0
    let xy = cast!(b);
920
921
0
    let yx = self.avx._mm256_permute_ps::<0b10_11_00_01>(xy);
922
0
    let aa = self.avx._mm256_moveldup_ps(ab);
923
0
    let bb = self.avx._mm256_movehdup_ps(ab);
924
925
0
    cast!(
926
0
      self.fma
927
0
        ._mm256_fmaddsub_ps(aa, xy, self.avx._mm256_mul_ps(bb, yx))
928
    )
929
0
  }
930
931
  #[inline(always)]
932
0
  fn mul_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::c64s {
933
0
    let ab = cast!(a);
934
0
    let xy = cast!(b);
935
936
0
    let yx = self.avx._mm256_permute_pd::<0b0101>(xy);
937
0
    let aa = self.avx._mm256_unpacklo_pd(ab, ab);
938
0
    let bb = self.avx._mm256_unpackhi_pd(ab, ab);
939
940
0
    cast!(
941
0
      self.fma
942
0
        ._mm256_fmaddsub_pd(aa, xy, self.avx._mm256_mul_pd(bb, yx))
943
    )
944
0
  }
945
946
  #[inline(always)]
947
0
  fn neg_c32s(self, a: Self::c32s) -> Self::c32s {
948
0
    self.xor_f32s(a, self.splat_f32s(-0.0))
949
0
  }
950
951
  #[inline(always)]
952
0
  fn neg_c64s(self, a: Self::c64s) -> Self::c64s {
953
0
    self.xor_f64s(a, self.splat_f64s(-0.0))
954
0
  }
955
956
  #[cfg(target_arch = "x86_64")]
957
  #[inline(always)]
958
0
  fn partial_load_u32s(self, slice: &[u32]) -> Self::u32s {
959
0
    avx_load_u32s(self.avx2, slice)
960
0
  }
961
962
  #[cfg(target_arch = "x86_64")]
963
  #[inline(always)]
964
0
  fn partial_load_u64s(self, slice: &[u64]) -> Self::u64s {
965
0
    cast!(self.partial_load_u32s(bytemuck::cast_slice(slice)))
966
0
  }
967
968
  #[cfg(target_arch = "x86_64")]
969
  #[inline(always)]
970
0
  fn partial_store_u32s(self, slice: &mut [u32], values: Self::u32s) {
971
0
    avx_store_u32s(self.avx2, slice, values)
972
0
  }
973
974
  #[cfg(target_arch = "x86_64")]
975
  #[inline(always)]
976
0
  fn partial_store_u64s(self, slice: &mut [u64], values: Self::u64s) {
977
0
    self.partial_store_u32s(bytemuck::cast_slice_mut(slice), cast!(values))
978
0
  }
979
980
  #[inline(always)]
981
0
  fn reduce_max_c32s(self, a: Self::c32s) -> c32 {
982
0
    let a: __m256 = cast!(a);
983
0
    let r = self.sse._mm_max_ps(
984
0
      self.avx._mm256_castps256_ps128(a),
985
0
      self.avx._mm256_extractf128_ps::<1>(a),
986
    );
987
0
    (*self).reduce_max_c32x2(cast!(r))
988
0
  }
989
990
  #[inline(always)]
991
0
  fn reduce_max_c64s(self, a: Self::c64s) -> c64 {
992
0
    let a: __m256d = cast!(a);
993
0
    let r = self.sse2._mm_max_pd(
994
0
      self.avx._mm256_castpd256_pd128(a),
995
0
      self.avx._mm256_extractf128_pd::<1>(a),
996
    );
997
0
    (*self).reduce_max_c64x1(cast!(r))
998
0
  }
999
1000
  #[inline(always)]
1001
0
  fn reduce_max_f32s(self, a: Self::f32s) -> f32 {
1002
0
    let a: __m256 = cast!(a);
1003
0
    let r = self.sse._mm_max_ps(
1004
0
      self.avx._mm256_castps256_ps128(a),
1005
0
      self.avx._mm256_extractf128_ps::<1>(a),
1006
    );
1007
0
    (*self).reduce_max_f32x4(cast!(r))
1008
0
  }
1009
1010
  #[inline(always)]
1011
0
  fn reduce_max_f64s(self, a: Self::f64s) -> f64 {
1012
0
    let a: __m256d = cast!(a);
1013
0
    let r = self.sse2._mm_max_pd(
1014
0
      self.avx._mm256_castpd256_pd128(a),
1015
0
      self.avx._mm256_extractf128_pd::<1>(a),
1016
    );
1017
0
    (*self).reduce_max_f64x2(cast!(r))
1018
0
  }
1019
1020
  #[inline(always)]
1021
0
  fn reduce_min_c32s(self, a: Self::c32s) -> c32 {
1022
0
    let a: __m256 = cast!(a);
1023
0
    let r = self.sse._mm_min_ps(
1024
0
      self.avx._mm256_castps256_ps128(a),
1025
0
      self.avx._mm256_extractf128_ps::<1>(a),
1026
    );
1027
0
    (*self).reduce_min_c32x2(cast!(r))
1028
0
  }
1029
1030
  #[inline(always)]
1031
0
  fn reduce_min_c64s(self, a: Self::c64s) -> c64 {
1032
0
    let a: __m256d = cast!(a);
1033
0
    let r = self.sse2._mm_min_pd(
1034
0
      self.avx._mm256_castpd256_pd128(a),
1035
0
      self.avx._mm256_extractf128_pd::<1>(a),
1036
    );
1037
0
    (*self).reduce_min_c64x1(cast!(r))
1038
0
  }
1039
1040
  #[inline(always)]
1041
0
  fn reduce_min_f32s(self, a: Self::f32s) -> f32 {
1042
0
    let a: __m256 = cast!(a);
1043
0
    let r = self.sse._mm_min_ps(
1044
0
      self.avx._mm256_castps256_ps128(a),
1045
0
      self.avx._mm256_extractf128_ps::<1>(a),
1046
    );
1047
0
    (*self).reduce_min_f32x4(cast!(r))
1048
0
  }
1049
1050
  #[inline(always)]
1051
0
  fn reduce_min_f64s(self, a: Self::f64s) -> f64 {
1052
0
    let a: __m256d = cast!(a);
1053
0
    let r = self.sse2._mm_min_pd(
1054
0
      self.avx._mm256_castpd256_pd128(a),
1055
0
      self.avx._mm256_extractf128_pd::<1>(a),
1056
    );
1057
0
    (*self).reduce_min_f64x2(cast!(r))
1058
0
  }
1059
1060
  #[inline(always)]
1061
0
  fn reduce_product_f32s(self, a: Self::f32s) -> f32 {
1062
0
    let a: __m256 = cast!(a);
1063
0
    let r = self.sse._mm_mul_ps(
1064
0
      self.avx._mm256_castps256_ps128(a),
1065
0
      self.avx._mm256_extractf128_ps::<1>(a),
1066
    );
1067
0
    (*self).reduce_product_f32x4(cast!(r))
1068
0
  }
1069
1070
  #[inline(always)]
1071
0
  fn reduce_product_f64s(self, a: Self::f64s) -> f64 {
1072
0
    let a: __m256d = cast!(a);
1073
0
    let r = self.sse2._mm_mul_pd(
1074
0
      self.avx._mm256_castpd256_pd128(a),
1075
0
      self.avx._mm256_extractf128_pd::<1>(a),
1076
    );
1077
0
    (*self).reduce_product_f64x2(cast!(r))
1078
0
  }
1079
1080
  #[inline(always)]
1081
0
  fn reduce_sum_c32s(self, a: Self::c32s) -> c32 {
1082
0
    let a: __m256 = cast!(a);
1083
0
    let r = self.sse._mm_add_ps(
1084
0
      self.avx._mm256_castps256_ps128(a),
1085
0
      self.avx._mm256_extractf128_ps::<1>(a),
1086
    );
1087
0
    (*self).reduce_sum_c32x2(cast!(r))
1088
0
  }
1089
1090
  #[inline(always)]
1091
0
  fn reduce_sum_c64s(self, a: Self::c64s) -> c64 {
1092
0
    let a: __m256d = cast!(a);
1093
0
    let r = self.sse2._mm_add_pd(
1094
0
      self.avx._mm256_castpd256_pd128(a),
1095
0
      self.avx._mm256_extractf128_pd::<1>(a),
1096
    );
1097
0
    (*self).reduce_sum_c64x1(cast!(r))
1098
0
  }
1099
1100
  #[inline(always)]
1101
0
  fn reduce_sum_f32s(self, a: Self::f32s) -> f32 {
1102
0
    let a: __m256 = cast!(a);
1103
0
    let r = self.sse._mm_add_ps(
1104
0
      self.avx._mm256_castps256_ps128(a),
1105
0
      self.avx._mm256_extractf128_ps::<1>(a),
1106
    );
1107
0
    (*self).reduce_sum_f32x4(cast!(r))
1108
0
  }
1109
1110
  #[inline(always)]
1111
0
  fn reduce_sum_f64s(self, a: Self::f64s) -> f64 {
1112
0
    let a: __m256d = cast!(a);
1113
0
    let r = self.sse2._mm_add_pd(
1114
0
      self.avx._mm256_castpd256_pd128(a),
1115
0
      self.avx._mm256_extractf128_pd::<1>(a),
1116
    );
1117
0
    (*self).reduce_sum_f64x2(cast!(r))
1118
0
  }
1119
1120
  #[inline(always)]
1121
0
  fn rotate_right_c32s(self, a: Self::c32s, amount: usize) -> Self::c32s {
1122
0
    cast!(avx2_pshufb(
1123
0
      self,
1124
0
      cast!(a),
1125
0
      cast!(AVX2_ROTATE_IDX[8 * (amount % 4)]),
1126
    ))
1127
0
  }
1128
1129
  #[inline(always)]
1130
0
  fn rotate_right_c64s(self, a: Self::c64s, amount: usize) -> Self::c64s {
1131
0
    cast!(avx2_pshufb(
1132
0
      self,
1133
0
      cast!(a),
1134
0
      cast!(AVX2_ROTATE_IDX[16 * (amount % 2)]),
1135
    ))
1136
0
  }
1137
1138
  #[inline(always)]
1139
0
  fn rotate_right_u32s(self, a: Self::u32s, amount: usize) -> Self::u32s {
1140
0
    cast!(avx2_pshufb(
1141
0
      self,
1142
0
      cast!(a),
1143
0
      cast!(AVX2_ROTATE_IDX[4 * (amount % 8)]),
1144
    ))
1145
0
  }
1146
1147
  #[inline(always)]
1148
0
  fn rotate_right_u64s(self, a: Self::u64s, amount: usize) -> Self::u64s {
1149
0
    cast!(avx2_pshufb(
1150
0
      self,
1151
0
      cast!(a),
1152
0
      cast!(AVX2_ROTATE_IDX[8 * (amount % 4)]),
1153
    ))
1154
0
  }
1155
1156
  #[inline(always)]
1157
0
  fn select_u32s(
1158
0
    self,
1159
0
    mask: Self::m32s,
1160
0
    if_true: Self::u32s,
1161
0
    if_false: Self::u32s,
1162
0
  ) -> Self::u32s {
1163
0
    let mask: __m256 = cast!(mask);
1164
0
    let if_true: __m256 = cast!(if_true);
1165
0
    let if_false: __m256 = cast!(if_false);
1166
1167
0
    cast!(self.avx._mm256_blendv_ps(if_false, if_true, mask))
1168
0
  }
1169
1170
  #[inline(always)]
1171
0
  fn select_u64s(
1172
0
    self,
1173
0
    mask: Self::m64s,
1174
0
    if_true: Self::u64s,
1175
0
    if_false: Self::u64s,
1176
0
  ) -> Self::u64s {
1177
0
    let mask: __m256d = cast!(mask);
1178
0
    let if_true: __m256d = cast!(if_true);
1179
0
    let if_false: __m256d = cast!(if_false);
1180
1181
0
    cast!(self.avx._mm256_blendv_pd(if_false, if_true, mask))
1182
0
  }
1183
1184
  #[inline(always)]
1185
0
  fn splat_c32s(self, value: c32) -> Self::c32s {
1186
0
    cast!(self.splat_f64s(cast!(value)))
1187
0
  }
1188
1189
  #[inline(always)]
1190
0
  fn splat_c64s(self, value: c64) -> Self::c64s {
1191
0
    cast!(self.avx._mm256_broadcast_pd(&cast!(value)))
1192
0
  }
1193
1194
  #[inline(always)]
1195
0
  fn sub_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::c32s {
1196
0
    self.sub_f32s(a, b)
1197
0
  }
1198
1199
  #[inline(always)]
1200
0
  fn sub_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::c64s {
1201
0
    self.sub_f64s(a, b)
1202
0
  }
1203
1204
  #[inline(always)]
1205
0
  fn swap_re_im_c32s(self, a: Self::c32s) -> Self::c32s {
1206
0
    cast!(self.avx._mm256_permute_ps::<0b10_11_00_01>(cast!(a)))
1207
0
  }
1208
1209
  #[inline(always)]
1210
0
  fn swap_re_im_c64s(self, a: Self::c64s) -> Self::c64s {
1211
0
    cast!(self.avx._mm256_permute_pd::<0b0101>(cast!(a)))
1212
0
  }
1213
1214
  #[inline(always)]
1215
0
  fn vectorize<Op: WithSimd>(self, op: Op) -> Op::Output {
1216
    struct Impl<Op> {
1217
      this: V3,
1218
      op: Op,
1219
    }
1220
    impl<Op: WithSimd> crate::NullaryFnOnce for Impl<Op> {
1221
      type Output = Op::Output;
1222
1223
      #[inline(always)]
1224
0
      fn call(self) -> Self::Output {
1225
0
        self.op.with_simd(self.this)
1226
0
      }
1227
    }
1228
0
    self.vectorize(Impl { this: self, op })
1229
0
  }
1230
1231
  #[inline(always)]
1232
0
  fn widening_mul_u32s(self, a: Self::u32s, b: Self::u32s) -> (Self::u32s, Self::u32s) {
1233
0
    self.widening_mul_u32x8(a, b)
1234
0
  }
1235
1236
  #[inline(always)]
1237
0
  fn wrapping_dyn_shl_u32s(self, a: Self::u32s, amount: Self::u32s) -> Self::u32s {
1238
0
    self.shl_dyn_u32x8(a, self.and_u32x8(amount, self.splat_u32x8(32 - 1)))
1239
0
  }
1240
1241
  #[inline(always)]
1242
0
  fn wrapping_dyn_shr_u32s(self, a: Self::u32s, amount: Self::u32s) -> Self::u32s {
1243
0
    self.shr_dyn_u32x8(a, self.and_u32x8(amount, self.splat_u32x8(32 - 1)))
1244
0
  }
1245
1246
  #[inline(always)]
1247
0
  fn sqrt_f32s(self, a: Self::f32s) -> Self::f32s {
1248
0
    self.sqrt_f32x8(a)
1249
0
  }
1250
1251
  #[inline(always)]
1252
0
  fn sqrt_f64s(self, a: Self::f64s) -> Self::f64s {
1253
0
    self.sqrt_f64x4(a)
1254
0
  }
1255
}
1256
1257
#[derive(Copy, Clone, Debug)]
1258
#[repr(transparent)]
1259
pub struct V3_128b(pub V3);
1260
1261
#[derive(Copy, Clone, Debug)]
1262
#[repr(transparent)]
1263
pub struct V3_256b(pub V3);
1264
1265
#[derive(Copy, Clone, Debug)]
1266
#[repr(transparent)]
1267
pub struct V3_512b(pub V3);
1268
1269
impl core::ops::Deref for V3_128b {
1270
  type Target = V3;
1271
1272
  #[inline]
1273
0
  fn deref(&self) -> &Self::Target {
1274
0
    &self.0
1275
0
  }
1276
}
1277
1278
impl core::ops::Deref for V3_256b {
1279
  type Target = V3;
1280
1281
  #[inline]
1282
0
  fn deref(&self) -> &Self::Target {
1283
0
    &self.0
1284
0
  }
1285
}
1286
1287
impl core::ops::Deref for V3_512b {
1288
  type Target = V3;
1289
1290
  #[inline]
1291
0
  fn deref(&self) -> &Self::Target {
1292
0
    &self.0
1293
0
  }
1294
}
1295
1296
impl Seal for V3_128b {}
1297
impl Seal for V3_256b {}
1298
impl Seal for V3_512b {}
1299
1300
macro_rules! impl_scalar_binop {
1301
  ($func: ident, $ty: ident, $out: ty, impl) => {
1302
    paste! {
1303
      #[inline(always)]
1304
0
      fn [<$func _ $ty s>](self, a: Self::[<$ty s>], b: Self::[<$ty s>]) -> Self::[<$out s>] {
1305
0
        Scalar128b.[<$func _ $ty s>](a, b)
1306
0
      }
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::conj_mul_c32s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::conj_mul_c64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::max_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::max_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::min_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::min_u64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::mul_i64s
Unexecuted instantiation: <pulp::x86::v3::V3_128b as pulp::Simd>::mul_u64s
1307
    }
1308
  };
1309
  ($func: ident, $($ty: ident => $out: ty),*) => {
1310
    $(impl_scalar_binop!($func, $ty, $out, impl);)*
1311
  };
1312
  ($func: ident, $($ty: ident),*) => {
1313
    $(impl_scalar_binop!($func, $ty, $ty, impl);)*
1314
  };
1315
}
1316
1317
impl Simd for V3_128b {
1318
  type c32s = f32x4;
1319
  type c64s = f64x2;
1320
  type f32s = f32x4;
1321
  type f64s = f64x2;
1322
  type i16s = i16x8;
1323
  type i32s = i32x4;
1324
  type i64s = i64x2;
1325
  type i8s = i8x16;
1326
  type m16s = m16x8;
1327
  type m32s = m32x4;
1328
  type m64s = m64x2;
1329
  type m8s = m8x16;
1330
  type u16s = u16x8;
1331
  type u32s = u32x4;
1332
  type u64s = u64x2;
1333
  type u8s = u8x16;
1334
1335
  const REGISTER_COUNT: usize = 16;
1336
1337
  impl_simd_binop!(add, f32 x 4, f64 x 2);
1338
1339
  impl_simd_binop!(add, wrapping_add, u8 x 16, i8 x 16, u16 x 8, i16 x 8, u32 x 4, i32 x 4, u64 x 2, i64 x 2);
1340
1341
  impl_simd_binop!(sub, f32 x 4, f64 x 2);
1342
1343
  impl_simd_binop!(sub, wrapping_sub, u8 x 16, i8 x 16, u16 x 8, i16 x 8, u32 x 4, i32 x 4, u64 x 2, i64 x 2);
1344
1345
  impl_simd_binop!(mul, f32 x 4, f64 x 2);
1346
1347
  impl_simd_binop!(mul, wrapping_mul, u16 x 8, i16 x 8, u32 x 4, i32 x 4);
1348
1349
  impl_scalar_binop!(mul, u64, i64);
1350
1351
  impl_simd_binop!(and, m8 x 16, u8 x 16, i8 x 16, m16 x 8, u16 x 8, i16 x 8, m32 x 4, u32 x 4, i32 x 4, m64 x 2, u64 x 2, i64 x 2, f32 x 4, f64 x 2);
1352
1353
  impl_simd_binop!(or, m8 x 16, u8 x 16, i8 x 16, m16 x 8, u16 x 8, i16 x 8, m32 x 4, u32 x 4, i32 x 4, m64 x 2, u64 x 2, i64 x 2, f32 x 4, f64 x 2);
1354
1355
  impl_simd_binop!(xor, m8 x 16, u8 x 16, i8 x 16, m16 x 8, u16 x 8, i16 x 8, m32 x 4, u32 x 4, i32 x 4, m64 x 2, u64 x 2, i64 x 2, f32 x 4, f64 x 2);
1356
1357
  impl_simd_binop!(div, f32 x 4, f64 x 2);
1358
1359
  impl_simd_binop!(equal, cmp_eq, u8 x 16 => m8, u16 x 8 => m16, u32 x 4 => m32, u64 x 2 => m64, f32 x 4 => m32, f64 x 2 => m64);
1360
1361
  impl_simd_binop!(greater_than, cmp_gt, u8 x 16 => m8, i8 x 16 => m8, u16 x 8 => m16, i16 x 8 => m16, u32 x 4 => m32, i32 x 4 => m32, u64 x 2 => m64, i64 x 2 => m64, f32 x 4 => m32, f64 x 2 => m64);
1362
1363
  impl_simd_binop!(greater_than_or_equal, cmp_ge, u8 x 16 => m8, i8 x 16 => m8, u16 x 8 => m16, i16 x 8 => m16, u32 x 4 => m32, i32 x 4 => m32, u64 x 2 => m64, i64 x 2 => m64, f32 x 4 => m32, f64 x 2 => m64);
1364
1365
  impl_simd_binop!(less_than, cmp_lt, u8 x 16 => m8, i8 x 16 => m8, u16 x 8 => m16, i16 x 8 => m16, u32 x 4 => m32, i32 x 4 => m32, u64 x 2 => m64, i64 x 2 => m64, f32 x 4 => m32, f64 x 2 => m64);
1366
1367
  impl_simd_binop!(less_than_or_equal, cmp_le, u8 x 16 => m8, i8 x 16 => m8, u16 x 8 => m16, i16 x 8 => m16, u32 x 4 => m32, i32 x 4 => m32, u64 x 2 => m64, i64 x 2 => m64, f32 x 4 => m32, f64 x 2 => m64);
1368
1369
  impl_scalar_binop!(conj_mul, c32, c64);
1370
1371
  splat!(u8 x 16, i8 x 16, u16 x 8, i16 x 8, u32 x 4, i32 x 4, u64 x 2, i64 x 2, f32 x 4, f64 x 2);
1372
1373
  impl_simd_binop!(max, u8 x 16, i8 x 16, u16 x 8, i16 x 8, u32 x 4, i32 x 4, f32 x 4, f64 x 2);
1374
1375
  impl_scalar_binop!(max, u64, i64);
1376
1377
  impl_simd_binop!(min, u8 x 16, i8 x 16, u16 x 8, i16 x 8, u32 x 4, i32 x 4, f32 x 4, f64 x 2);
1378
1379
  impl_scalar_binop!(min, u64, i64);
1380
1381
  impl_simd_unop!(not, m8 x 16, u8 x 16, m16 x 8, u16 x 8, m32 x 4, u32 x 4, m64 x 2, u64 x 2);
1382
1383
  #[inline(always)]
1384
0
  fn abs2_c32s(self, a: Self::c32s) -> Self::c32s {
1385
0
    let sqr = self.mul_f32s(a, a);
1386
0
    let sqr_rev = self
1387
0
      .sse
1388
0
      ._mm_shuffle_ps::<0b10_11_00_01>(cast!(sqr), cast!(sqr));
1389
0
    self.add_f32s(sqr, cast!(sqr_rev))
1390
0
  }
1391
1392
  #[inline(always)]
1393
0
  fn abs2_c64s(self, a: Self::c64s) -> Self::c64s {
1394
0
    let sqr = self.mul_f64s(a, a);
1395
0
    let sqr_rev = self.sse2._mm_shuffle_pd::<0b01>(cast!(sqr), cast!(sqr));
1396
0
    self.add_f64s(sqr, cast!(sqr_rev))
1397
0
  }
1398
1399
  #[inline(always)]
1400
0
  fn abs_max_c32s(self, a: Self::c32s) -> Self::c32s {
1401
0
    let sqr = self.abs_f32s(a);
1402
0
    let sqr_rev = self
1403
0
      .sse
1404
0
      ._mm_shuffle_ps::<0b10_11_00_01>(cast!(sqr), cast!(sqr));
1405
0
    self.max_f32s(sqr, cast!(sqr_rev))
1406
0
  }
1407
1408
  #[inline(always)]
1409
0
  fn abs_max_c64s(self, a: Self::c64s) -> Self::c64s {
1410
0
    let sqr = self.abs_f64s(a);
1411
0
    let sqr_rev = self.sse2._mm_shuffle_pd::<0b01>(cast!(sqr), cast!(sqr));
1412
0
    self.max_f64s(sqr, cast!(sqr_rev))
1413
0
  }
1414
1415
  #[inline(always)]
1416
0
  fn add_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::c32s {
1417
0
    self.add_f32s(a, b)
1418
0
  }
1419
1420
  #[inline(always)]
1421
0
  fn add_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::c64s {
1422
0
    self.add_f64s(a, b)
1423
0
  }
1424
1425
  #[inline(always)]
1426
0
  fn equal_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::m32s {
1427
0
    self.equal_f32s(a, b)
1428
0
  }
1429
1430
  #[inline(always)]
1431
0
  fn equal_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::m64s {
1432
0
    self.equal_f64s(a, b)
1433
0
  }
1434
1435
  #[inline(always)]
1436
0
  fn conj_c32s(self, a: Self::c32s) -> Self::c32s {
1437
0
    self.xor_f32s(a, self.splat_c32s(c32 { re: 0.0, im: -0.0 }))
1438
0
  }
1439
1440
  #[inline(always)]
1441
0
  fn conj_c64s(self, a: Self::c64s) -> Self::c64s {
1442
0
    self.xor_f64s(a, self.splat_c64s(c64 { re: 0.0, im: -0.0 }))
1443
0
  }
1444
1445
  #[inline(always)]
1446
0
  fn conj_mul_add_c32s(self, a: Self::c32s, b: Self::c32s, c: Self::c32s) -> Self::c32s {
1447
0
    let ab = cast!(a);
1448
0
    let xy = cast!(b);
1449
1450
0
    let yx = self.avx._mm_permute_ps::<0b10_11_00_01>(xy);
1451
0
    let aa = self.sse3._mm_moveldup_ps(ab);
1452
0
    let bb = self.sse3._mm_movehdup_ps(ab);
1453
1454
0
    cast!(
1455
0
      self.fma
1456
0
        ._mm_fmsubadd_ps(aa, xy, self.fma._mm_fmsubadd_ps(bb, yx, cast!(c)))
1457
    )
1458
0
  }
1459
1460
  #[inline(always)]
1461
0
  fn conj_mul_add_c64s(self, a: Self::c64s, b: Self::c64s, c: Self::c64s) -> Self::c64s {
1462
0
    let ab = cast!(a);
1463
0
    let xy = cast!(b);
1464
1465
0
    let yx = self.avx._mm_permute_pd::<0b01>(xy);
1466
0
    let aa = self.sse2._mm_unpacklo_pd(ab, ab);
1467
0
    let bb = self.sse2._mm_unpackhi_pd(ab, ab);
1468
1469
0
    cast!(
1470
0
      self.fma
1471
0
        ._mm_fmsubadd_pd(aa, xy, self.fma._mm_fmsubadd_pd(bb, yx, cast!(c)))
1472
    )
1473
0
  }
1474
1475
  #[inline(always)]
1476
0
  unsafe fn mask_load_ptr_c32s(self, mask: MemMask<Self::m32s>, ptr: *const c32) -> Self::c32s {
1477
0
    cast!(self.mask_load_ptr_u32s(mask, ptr as _))
1478
0
  }
1479
1480
  #[inline(always)]
1481
0
  unsafe fn mask_load_ptr_c64s(self, mask: MemMask<Self::m64s>, ptr: *const c64) -> Self::c64s {
1482
0
    cast!(self.mask_load_ptr_u64s(mask, ptr as _))
1483
0
  }
1484
1485
  #[inline(always)]
1486
0
  unsafe fn mask_load_ptr_u8s(self, mask: MemMask<Self::m8s>, ptr: *const u8) -> Self::u8s {
1487
0
    Scalar128b.mask_load_ptr_u8s(mask, ptr)
1488
0
  }
1489
1490
  #[inline(always)]
1491
0
  unsafe fn mask_load_ptr_u16s(self, mask: MemMask<Self::m16s>, ptr: *const u16) -> Self::u16s {
1492
0
    Scalar128b.mask_load_ptr_u16s(mask, ptr)
1493
0
  }
1494
1495
  #[inline(always)]
1496
0
  unsafe fn mask_load_ptr_u32s(self, mask: MemMask<Self::m32s>, ptr: *const u32) -> Self::u32s {
1497
    #[cfg(target_arch = "x86_64")]
1498
0
    if let Some(load) = mask.load {
1499
0
      return cast_lossy(avx_ld_u32s(ptr, load));
1500
0
    }
1501
0
    cast!(self.avx2._mm_maskload_epi32(ptr as _, cast!(mask.mask)))
1502
0
  }
1503
1504
  #[inline(always)]
1505
0
  unsafe fn mask_load_ptr_u64s(self, mask: MemMask<Self::m64s>, ptr: *const u64) -> Self::u64s {
1506
    #[cfg(target_arch = "x86_64")]
1507
0
    if let Some(load) = mask.load {
1508
0
      return cast_lossy(avx_ld_u32s(ptr as _, load));
1509
0
    }
1510
0
    cast!(self.avx2._mm_maskload_epi64(ptr as _, cast!(mask.mask)))
1511
0
  }
1512
1513
  #[inline(always)]
1514
0
  unsafe fn mask_store_ptr_c32s(
1515
0
    self,
1516
0
    mask: MemMask<Self::m32s>,
1517
0
    ptr: *mut c32,
1518
0
    values: Self::c32s,
1519
0
  ) {
1520
0
    self.mask_store_ptr_u32s(mask, ptr as _, cast!(values));
1521
0
  }
1522
1523
  #[inline(always)]
1524
0
  unsafe fn mask_store_ptr_c64s(
1525
0
    self,
1526
0
    mask: MemMask<Self::m64s>,
1527
0
    ptr: *mut c64,
1528
0
    values: Self::c64s,
1529
0
  ) {
1530
0
    self.mask_store_ptr_u64s(mask, ptr as _, cast!(values))
1531
0
  }
1532
1533
  #[inline(always)]
1534
0
  unsafe fn mask_store_ptr_u8s(self, mask: MemMask<Self::m8s>, ptr: *mut u8, values: Self::u8s) {
1535
0
    Scalar128b.mask_store_ptr_u8s(mask, ptr, values);
1536
0
  }
1537
1538
  #[inline(always)]
1539
0
  unsafe fn mask_store_ptr_u16s(
1540
0
    self,
1541
0
    mask: MemMask<Self::m16s>,
1542
0
    ptr: *mut u16,
1543
0
    values: Self::u16s,
1544
0
  ) {
1545
0
    Scalar128b.mask_store_ptr_u16s(mask, ptr, values);
1546
0
  }
1547
1548
  #[inline(always)]
1549
0
  unsafe fn mask_store_ptr_u32s(
1550
0
    self,
1551
0
    mask: MemMask<Self::m32s>,
1552
0
    ptr: *mut u32,
1553
0
    values: Self::u32s,
1554
0
  ) {
1555
    #[cfg(target_arch = "x86_64")]
1556
0
    if let Some(store) = mask.store {
1557
0
      return avx_st_u32s(ptr, cast!([values, self.splat_u32s(0)]), store);
1558
0
    }
1559
0
    self.avx2
1560
0
      ._mm_maskstore_epi32(ptr as _, cast!(mask.mask), cast!(values));
1561
0
  }
1562
1563
  #[inline(always)]
1564
0
  unsafe fn mask_store_ptr_u64s(
1565
0
    self,
1566
0
    mask: MemMask<Self::m64s>,
1567
0
    ptr: *mut u64,
1568
0
    values: Self::u64s,
1569
0
  ) {
1570
0
    self.mask_store_ptr_u32s(
1571
      MemMask {
1572
0
        mask: cast!(mask.mask),
1573
        #[cfg(target_arch = "x86_64")]
1574
0
        load: mask.load,
1575
        #[cfg(target_arch = "x86_64")]
1576
0
        store: mask.store,
1577
      },
1578
0
      ptr as _,
1579
0
      cast!(values),
1580
    )
1581
0
  }
1582
1583
  #[inline(always)]
1584
0
  fn mul_add_c32s(self, a: Self::c32s, b: Self::c32s, c: Self::c32s) -> Self::c32s {
1585
0
    let ab = cast!(a);
1586
0
    let xy = cast!(b);
1587
1588
0
    let yx = self.avx._mm_permute_ps::<0b10_11_00_01>(xy);
1589
0
    let aa = self.sse3._mm_moveldup_ps(ab);
1590
0
    let bb = self.sse3._mm_movehdup_ps(ab);
1591
1592
0
    cast!(
1593
0
      self.fma
1594
0
        ._mm_fmaddsub_ps(aa, xy, self.fma._mm_fmaddsub_ps(bb, yx, cast!(c)))
1595
    )
1596
0
  }
1597
1598
  #[inline(always)]
1599
0
  fn mul_add_c64s(self, a: Self::c64s, b: Self::c64s, c: Self::c64s) -> Self::c64s {
1600
0
    let ab = cast!(a);
1601
0
    let xy = cast!(b);
1602
1603
0
    let yx = self.avx._mm_permute_pd::<0b01>(xy);
1604
0
    let aa = self.sse2._mm_unpacklo_pd(ab, ab);
1605
0
    let bb = self.sse2._mm_unpackhi_pd(ab, ab);
1606
1607
0
    cast!(
1608
0
      self.fma
1609
0
        ._mm_fmaddsub_pd(aa, xy, self.fma._mm_fmaddsub_pd(bb, yx, cast!(c)))
1610
    )
1611
0
  }
1612
1613
  #[inline(always)]
1614
0
  fn mul_add_e_f32s(self, a: Self::f32s, b: Self::f32s, c: Self::f32s) -> Self::f32s {
1615
0
    self.mul_add_f32s(a, b, c)
1616
0
  }
1617
1618
  #[inline(always)]
1619
0
  fn mul_add_e_f64s(self, a: Self::f64s, b: Self::f64s, c: Self::f64s) -> Self::f64s {
1620
0
    self.mul_add_f64s(a, b, c)
1621
0
  }
1622
1623
  #[inline(always)]
1624
0
  fn mul_add_f32s(self, a: Self::f32s, b: Self::f32s, c: Self::f32s) -> Self::f32s {
1625
0
    self.mul_add_f32x4(a, b, c)
1626
0
  }
1627
1628
  #[inline(always)]
1629
0
  fn mul_add_f64s(self, a: Self::f64s, b: Self::f64s, c: Self::f64s) -> Self::f64s {
1630
0
    self.mul_add_f64x2(a, b, c)
1631
0
  }
1632
1633
  #[inline(always)]
1634
0
  fn negate_mul_add_e_f32s(self, a: Self::f32s, b: Self::f32s, c: Self::f32s) -> Self::f32s {
1635
0
    self.negate_mul_add_f32s(a, b, c)
1636
0
  }
1637
1638
  #[inline(always)]
1639
0
  fn negate_mul_add_e_f64s(self, a: Self::f64s, b: Self::f64s, c: Self::f64s) -> Self::f64s {
1640
0
    self.negate_mul_add_f64s(a, b, c)
1641
0
  }
1642
1643
  #[inline(always)]
1644
0
  fn negate_mul_add_f32s(self, a: Self::f32s, b: Self::f32s, c: Self::f32s) -> Self::f32s {
1645
0
    self.negate_mul_add_f32x4(a, b, c)
1646
0
  }
1647
1648
  #[inline(always)]
1649
0
  fn negate_mul_add_f64s(self, a: Self::f64s, b: Self::f64s, c: Self::f64s) -> Self::f64s {
1650
0
    self.negate_mul_add_f64x2(a, b, c)
1651
0
  }
1652
1653
  #[inline(always)]
1654
0
  fn mul_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::c32s {
1655
0
    let ab = cast!(a);
1656
0
    let xy = cast!(b);
1657
1658
0
    let yx = self.avx._mm_permute_ps::<0b10_11_00_01>(xy);
1659
0
    let aa = self.sse3._mm_moveldup_ps(ab);
1660
0
    let bb = self.sse3._mm_movehdup_ps(ab);
1661
1662
0
    cast!(
1663
0
      self.fma
1664
0
        ._mm_fmaddsub_ps(aa, xy, self.sse._mm_mul_ps(bb, yx))
1665
    )
1666
0
  }
1667
1668
  #[inline(always)]
1669
0
  fn mul_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::c64s {
1670
0
    let ab = cast!(a);
1671
0
    let xy = cast!(b);
1672
1673
0
    let yx = self.avx._mm_permute_pd::<0b01>(xy);
1674
0
    let aa = self.sse2._mm_unpacklo_pd(ab, ab);
1675
0
    let bb = self.sse2._mm_unpackhi_pd(ab, ab);
1676
1677
0
    cast!(
1678
0
      self.fma
1679
0
        ._mm_fmaddsub_pd(aa, xy, self.sse2._mm_mul_pd(bb, yx))
1680
    )
1681
0
  }
1682
1683
  #[inline(always)]
1684
0
  fn neg_c32s(self, a: Self::c32s) -> Self::c32s {
1685
0
    self.xor_f32s(a, self.splat_f32s(-0.0))
1686
0
  }
1687
1688
  #[inline(always)]
1689
0
  fn neg_c64s(self, a: Self::c64s) -> Self::c64s {
1690
0
    self.xor_f64s(a, self.splat_f64s(-0.0))
1691
0
  }
1692
1693
  #[cfg(target_arch = "x86_64")]
1694
  #[inline(always)]
1695
0
  fn partial_load_u32s(self, slice: &[u32]) -> Self::u32s {
1696
0
    cast_lossy(avx_load_u32s(self.avx2, slice))
1697
0
  }
1698
1699
  #[cfg(target_arch = "x86_64")]
1700
  #[inline(always)]
1701
0
  fn partial_load_u64s(self, slice: &[u64]) -> Self::u64s {
1702
0
    cast!(self.partial_load_u32s(bytemuck::cast_slice(slice)))
1703
0
  }
1704
1705
  #[cfg(target_arch = "x86_64")]
1706
  #[inline(always)]
1707
0
  fn partial_store_u32s(self, slice: &mut [u32], values: Self::u32s) {
1708
0
    avx_store_u32s(self.avx2, slice, cast!([values, self.splat_u32s(0)]))
1709
0
  }
1710
1711
  #[cfg(target_arch = "x86_64")]
1712
  #[inline(always)]
1713
0
  fn partial_store_u64s(self, slice: &mut [u64], values: Self::u64s) {
1714
0
    self.partial_store_u32s(bytemuck::cast_slice_mut(slice), cast!(values))
1715
0
  }
1716
1717
  #[inline(always)]
1718
0
  fn reduce_max_c32s(self, a: Self::c32s) -> c32 {
1719
0
    let a: __m128 = cast!(a);
1720
0
    let hi = self.sse._mm_movehl_ps(a, a);
1721
0
    let r0 = self.sse._mm_max_ps(a, hi);
1722
0
    cast!(self.sse2._mm_cvtsd_f64(cast!(r0)))
1723
0
  }
1724
1725
  #[inline(always)]
1726
0
  fn reduce_max_c64s(self, a: Self::c64s) -> c64 {
1727
0
    cast!(a)
1728
0
  }
1729
1730
  #[inline(always)]
1731
0
  fn reduce_max_f32s(self, a: Self::f32s) -> f32 {
1732
0
    let a: __m128 = cast!(a);
1733
0
    let hi = self.sse._mm_movehl_ps(a, a);
1734
0
    let r0 = self.sse._mm_max_ps(a, hi);
1735
0
    let r0_shuffled = self.sse._mm_shuffle_ps::<0b0001>(r0, r0);
1736
0
    let r = self.sse._mm_max_ss(r0, r0_shuffled);
1737
0
    self.sse._mm_cvtss_f32(r)
1738
0
  }
1739
1740
  #[inline(always)]
1741
0
  fn reduce_max_f64s(self, a: Self::f64s) -> f64 {
1742
0
    let a: __m128d = cast!(a);
1743
0
    let hi = cast!(self.sse._mm_movehl_ps(cast!(a), cast!(a)));
1744
0
    let r = self.sse2._mm_max_sd(a, hi);
1745
0
    self.sse2._mm_cvtsd_f64(r)
1746
0
  }
1747
1748
  #[inline(always)]
1749
0
  fn reduce_min_c32s(self, a: Self::c32s) -> c32 {
1750
0
    let a: __m128 = cast!(a);
1751
0
    let hi = self.sse._mm_movehl_ps(a, a);
1752
0
    let r0 = self.sse._mm_min_ps(a, hi);
1753
0
    cast!(self.sse2._mm_cvtsd_f64(cast!(r0)))
1754
0
  }
1755
1756
  #[inline(always)]
1757
0
  fn reduce_min_c64s(self, a: Self::c64s) -> c64 {
1758
0
    cast!(a)
1759
0
  }
1760
1761
  #[inline(always)]
1762
0
  fn reduce_min_f32s(self, a: Self::f32s) -> f32 {
1763
0
    let a: __m128 = cast!(a);
1764
0
    let hi = self.sse._mm_movehl_ps(a, a);
1765
0
    let r0 = self.sse._mm_min_ps(a, hi);
1766
0
    let r0_shuffled = self.sse._mm_shuffle_ps::<0b0001>(r0, r0);
1767
0
    let r = self.sse._mm_min_ss(r0, r0_shuffled);
1768
0
    self.sse._mm_cvtss_f32(r)
1769
0
  }
1770
1771
  #[inline(always)]
1772
0
  fn reduce_min_f64s(self, a: Self::f64s) -> f64 {
1773
0
    let a: __m128d = cast!(a);
1774
0
    let hi = cast!(self.sse._mm_movehl_ps(cast!(a), cast!(a)));
1775
0
    let r = self.sse2._mm_min_sd(a, hi);
1776
0
    self.sse2._mm_cvtsd_f64(r)
1777
0
  }
1778
1779
  #[inline(always)]
1780
0
  fn reduce_product_f32s(self, a: Self::f32s) -> f32 {
1781
0
    let a: __m128 = cast!(a);
1782
0
    let hi = self.sse._mm_movehl_ps(a, a);
1783
0
    let r0 = self.sse._mm_mul_ps(a, hi);
1784
0
    let r0_shuffled = self.sse._mm_shuffle_ps::<0b0001>(r0, r0);
1785
0
    let r = self.sse._mm_mul_ss(r0, r0_shuffled);
1786
0
    self.sse._mm_cvtss_f32(r)
1787
0
  }
1788
1789
  #[inline(always)]
1790
0
  fn reduce_product_f64s(self, a: Self::f64s) -> f64 {
1791
0
    let a: __m128d = cast!(a);
1792
0
    let hi = cast!(self.sse._mm_movehl_ps(cast!(a), cast!(a)));
1793
0
    let r = self.sse2._mm_mul_sd(a, hi);
1794
0
    self.sse2._mm_cvtsd_f64(r)
1795
0
  }
1796
1797
  #[inline(always)]
1798
0
  fn reduce_sum_c32s(self, a: Self::c32s) -> c32 {
1799
    // a0 a1 a2 a3
1800
0
    let a: __m128 = cast!(a);
1801
    // a2 a3 a2 a3
1802
0
    let hi = self.sse._mm_movehl_ps(a, a);
1803
1804
    // a0+a2 a1+a3 _ _
1805
0
    let r0 = self.sse._mm_add_ps(a, hi);
1806
1807
0
    cast!(self.sse2._mm_cvtsd_f64(cast!(r0)))
1808
0
  }
1809
1810
  #[inline(always)]
1811
0
  fn reduce_sum_c64s(self, a: Self::c64s) -> c64 {
1812
0
    cast!(a)
1813
0
  }
1814
1815
  #[inline(always)]
1816
0
  fn reduce_sum_f32s(self, a: Self::f32s) -> f32 {
1817
0
    let a: __m128 = cast!(a);
1818
0
    let hi = self.sse._mm_movehl_ps(a, a);
1819
0
    let r0 = self.sse._mm_add_ps(a, hi);
1820
0
    let r0_shuffled = self.sse._mm_shuffle_ps::<0b0001>(r0, r0);
1821
0
    let r = self.sse._mm_add_ss(r0, r0_shuffled);
1822
0
    self.sse._mm_cvtss_f32(r)
1823
0
  }
1824
1825
  #[inline(always)]
1826
0
  fn reduce_sum_f64s(self, a: Self::f64s) -> f64 {
1827
0
    let a: __m128d = cast!(a);
1828
0
    let hi = cast!(self.sse._mm_movehl_ps(cast!(a), cast!(a)));
1829
0
    let r = self.sse2._mm_add_sd(a, hi);
1830
0
    self.sse2._mm_cvtsd_f64(r)
1831
0
  }
1832
1833
  #[inline(always)]
1834
0
  fn rotate_right_c32s(self, a: Self::c32s, amount: usize) -> Self::c32s {
1835
0
    cast!(
1836
0
      self.ssse3
1837
0
        ._mm_shuffle_epi8(cast!(a), cast!(AVX2_128_ROTATE_IDX[8 * (amount % 2)]))
1838
    )
1839
0
  }
1840
1841
  #[inline(always)]
1842
0
  fn rotate_right_c64s(self, a: Self::c64s, amount: usize) -> Self::c64s {
1843
0
    _ = amount;
1844
0
    a
1845
0
  }
1846
1847
  #[inline(always)]
1848
0
  fn rotate_right_u32s(self, a: Self::u32s, amount: usize) -> Self::u32s {
1849
0
    cast!(
1850
0
      self.ssse3
1851
0
        ._mm_shuffle_epi8(cast!(a), cast!(AVX2_128_ROTATE_IDX[4 * (amount % 4)]))
1852
    )
1853
0
  }
1854
1855
  #[inline(always)]
1856
0
  fn rotate_right_u64s(self, a: Self::u64s, amount: usize) -> Self::u64s {
1857
0
    cast!(
1858
0
      self.ssse3
1859
0
        ._mm_shuffle_epi8(cast!(a), cast!(AVX2_128_ROTATE_IDX[8 * (amount % 2)]))
1860
    )
1861
0
  }
1862
1863
  #[inline(always)]
1864
0
  fn select_u32s(
1865
0
    self,
1866
0
    mask: Self::m32s,
1867
0
    if_true: Self::u32s,
1868
0
    if_false: Self::u32s,
1869
0
  ) -> Self::u32s {
1870
0
    self.select_u32x4(mask, if_true, if_false)
1871
0
  }
1872
1873
  #[inline(always)]
1874
0
  fn select_u64s(
1875
0
    self,
1876
0
    mask: Self::m64s,
1877
0
    if_true: Self::u64s,
1878
0
    if_false: Self::u64s,
1879
0
  ) -> Self::u64s {
1880
0
    self.select_u64x2(mask, if_true, if_false)
1881
0
  }
1882
1883
  #[inline(always)]
1884
0
  fn splat_c32s(self, value: c32) -> Self::c32s {
1885
0
    cast!(self.splat_f64x2(cast!(value)))
1886
0
  }
1887
1888
  #[inline(always)]
1889
0
  fn splat_c64s(self, value: c64) -> Self::c64s {
1890
0
    cast!(value)
1891
0
  }
1892
1893
  #[inline(always)]
1894
0
  fn sub_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::c32s {
1895
0
    self.sub_f32x4(a, b)
1896
0
  }
1897
1898
  #[inline(always)]
1899
0
  fn sub_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::c64s {
1900
0
    self.sub_f64x2(a, b)
1901
0
  }
1902
1903
  #[inline(always)]
1904
0
  fn swap_re_im_c32s(self, a: Self::c32s) -> Self::c32s {
1905
0
    cast!(self.avx._mm_permute_ps::<0b10_11_00_01>(cast!(a)))
1906
0
  }
1907
1908
  #[inline(always)]
1909
0
  fn swap_re_im_c64s(self, a: Self::c64s) -> Self::c64s {
1910
0
    cast!(self.avx._mm_permute_pd::<0b01>(cast!(a)))
1911
0
  }
1912
1913
  #[inline(always)]
1914
0
  fn vectorize<Op: WithSimd>(self, op: Op) -> Op::Output {
1915
0
    Simd::vectorize(self.0, op)
1916
0
  }
1917
1918
  #[inline(always)]
1919
0
  fn widening_mul_u32s(self, a: Self::u32s, b: Self::u32s) -> (Self::u32s, Self::u32s) {
1920
0
    self.widening_mul_u32x4(a, b)
1921
0
  }
1922
1923
  #[inline(always)]
1924
0
  fn wrapping_dyn_shl_u32s(self, a: Self::u32s, amount: Self::u32s) -> Self::u32s {
1925
0
    self.shl_dyn_u32x4(a, self.and_u32x4(amount, self.splat_u32x4(32 - 1)))
1926
0
  }
1927
1928
  #[inline(always)]
1929
0
  fn wrapping_dyn_shr_u32s(self, a: Self::u32s, amount: Self::u32s) -> Self::u32s {
1930
0
    self.shr_dyn_u32x4(a, self.and_u32x4(amount, self.splat_u32x4(32 - 1)))
1931
0
  }
1932
1933
  #[inline(always)]
1934
0
  fn sqrt_f32s(self, a: Self::f32s) -> Self::f32s {
1935
0
    self.sqrt_f32x4(a)
1936
0
  }
1937
1938
  #[inline(always)]
1939
0
  fn sqrt_f64s(self, a: Self::f64s) -> Self::f64s {
1940
0
    self.sqrt_f64x2(a)
1941
0
  }
1942
}
1943
1944
impl Simd for V3_256b {
1945
  type c32s = f32x8;
1946
  type c64s = f64x4;
1947
  type f32s = f32x8;
1948
  type f64s = f64x4;
1949
  type i16s = i16x16;
1950
  type i32s = i32x8;
1951
  type i64s = i64x4;
1952
  type i8s = i8x32;
1953
  type m16s = m16x16;
1954
  type m32s = m32x8;
1955
  type m64s = m64x4;
1956
  type m8s = m8x32;
1957
  type u16s = u16x16;
1958
  type u32s = u32x8;
1959
  type u64s = u64x4;
1960
  type u8s = u8x32;
1961
1962
  const REGISTER_COUNT: usize = 16;
1963
1964
  impl_simd_binop!(add, f32 x 8, f64 x 4);
1965
1966
  impl_simd_binop!(add, wrapping_add, u8 x 32, i8 x 32, u16 x 16, i16 x 16, u32 x 8, i32 x 8, u64 x 4, i64 x 4);
1967
1968
  impl_simd_binop!(sub, f32 x 8, f64 x 4);
1969
1970
  impl_simd_binop!(sub, wrapping_sub, u8 x 32, i8 x 32, u16 x 16, i16 x 16, u32 x 8, i32 x 8, u64 x 4, i64 x 4);
1971
1972
  impl_simd_binop!(mul, f32 x 8, f64 x 4);
1973
1974
  impl_simd_binop!(mul, wrapping_mul, u16 x 16, i16 x 16, u32 x 8, i32 x 8);
1975
1976
  impl_simd_binop!(and, m8 x 32, u8 x 32, i8 x 32, m16 x 16, u16 x 16, i16 x 16, m32 x 8, u32 x 8, i32 x 8, m64 x 4, u64 x 4, i64 x 4, f32 x 8, f64 x 4);
1977
1978
  impl_simd_binop!(or, m8 x 32, u8 x 32, i8 x 32, m16 x 16, u16 x 16, i16 x 16, m32 x 8, u32 x 8, i32 x 8, m64 x 4, u64 x 4, i64 x 4, f32 x 8, f64 x 4);
1979
1980
  impl_simd_binop!(xor, m8 x 32, u8 x 32, i8 x 32, m16 x 16, u16 x 16, i16 x 16, m32 x 8, u32 x 8, i32 x 8, m64 x 4, u64 x 4, i64 x 4, f32 x 8, f64 x 4);
1981
1982
  impl_simd_binop!(div, f32 x 8, f64 x 4);
1983
1984
  impl_simd_binop!(equal, cmp_eq, u8 x 32 => m8, u16 x 16 => m16, u32 x 8 => m32, u64 x 4 => m64, f32 x 8 => m32, f64 x 4 => m64);
1985
1986
  impl_simd_binop!(greater_than, cmp_gt, u8 x 32 => m8, i8 x 32 => m8, u16 x 16 => m16, i16 x 16 => m16, u32 x 8 => m32, i32 x 8 => m32, u64 x 4 => m64, i64 x 4 => m64, f32 x 8 => m32, f64 x 4 => m64);
1987
1988
  impl_simd_binop!(greater_than_or_equal, cmp_ge, u8 x 32 => m8, i8 x 32 => m8, u16 x 16 => m16, i16 x 16 => m16, u32 x 8 => m32, i32 x 8 => m32, u64 x 4 => m64, i64 x 4 => m64, f32 x 8 => m32, f64 x 4 => m64);
1989
1990
  impl_simd_binop!(less_than, cmp_lt, u8 x 32 => m8, i8 x 32 => m8, u16 x 16 => m16, i16 x 16 => m16, u32 x 8 => m32, i32 x 8 => m32, u64 x 4 => m64, i64 x 4 => m64, f32 x 8 => m32, f64 x 4 => m64);
1991
1992
  impl_simd_binop!(less_than_or_equal, cmp_le, u8 x 32 => m8, i8 x 32 => m8, u16 x 16 => m16, i16 x 16 => m16, u32 x 8 => m32, i32 x 8 => m32, u64 x 4 => m64, i64 x 4 => m64, f32 x 8 => m32, f64 x 4 => m64);
1993
1994
  splat!(u8 x 32, i8 x 32, u16 x 16, i16 x 16, u32 x 8, i32 x 8, u64 x 4, i64 x 4, f32 x 8, f64 x 4);
1995
1996
  impl_simd_binop!(max, u8 x 32, i8 x 32, u16 x 16, i16 x 16, u32 x 8, i32 x 8, f32 x 8, f64 x 4);
1997
1998
  impl_simd_binop!(min, u8 x 32, i8 x 32, u16 x 16, i16 x 16, u32 x 8, i32 x 8, f32 x 8, f64 x 4);
1999
2000
  impl_simd_unop!(not, m8 x 32, u8 x 32, m16 x 16, u16 x 16, m32 x 8, u32 x 8, m64 x 4, u64 x 4);
2001
2002
  inherit!({
2003
    fn abs2_c32s(self, a: Self::c32s) -> Self::c32s;
2004
    fn abs2_c64s(self, a: Self::c64s) -> Self::c64s;
2005
    fn abs_max_c32s(self, a: Self::c32s) -> Self::c32s;
2006
    fn abs_max_c64s(self, a: Self::c64s) -> Self::c64s;
2007
    fn add_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::c32s;
2008
    fn add_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::c64s;
2009
    fn conj_c32s(self, a: Self::c32s) -> Self::c32s;
2010
    fn conj_c64s(self, a: Self::c64s) -> Self::c64s;
2011
    fn conj_mul_add_c32s(self, a: Self::c32s, b: Self::c32s, c: Self::c32s) -> Self::c32s;
2012
    fn conj_mul_add_c64s(self, a: Self::c64s, b: Self::c64s, c: Self::c64s) -> Self::c64s;
2013
    fn conj_mul_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::c32s;
2014
    fn conj_mul_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::c64s;
2015
    fn equal_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::m32s;
2016
    fn equal_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::m64s;
2017
    fn mask_between_m32s(self, start: u32, end: u32) -> MemMask<Self::m32s>;
2018
    fn mask_between_m64s(self, start: u64, end: u64) -> MemMask<Self::m64s>;
2019
    /// # Safety
2020
    ///
2021
    /// See the trait-level safety documentation.
2022
    unsafe fn mask_load_ptr_c32s(
2023
      self,
2024
      mask: MemMask<Self::m32s>,
2025
      ptr: *const c32,
2026
    ) -> Self::c32s;
2027
    /// # Safety
2028
    ///
2029
    /// See the trait-level safety documentation.
2030
    unsafe fn mask_load_ptr_c64s(
2031
      self,
2032
      mask: MemMask<Self::m64s>,
2033
      ptr: *const c64,
2034
    ) -> Self::c64s;
2035
    /// # Safety
2036
    ///
2037
    /// See the trait-level safety documentation.
2038
    unsafe fn mask_load_ptr_u8s(self, mask: MemMask<Self::m8s>, ptr: *const u8) -> Self::u8s;
2039
    /// # Safety
2040
    ///
2041
    /// See the trait-level safety documentation.
2042
    unsafe fn mask_load_ptr_u16s(
2043
      self,
2044
      mask: MemMask<Self::m16s>,
2045
      ptr: *const u16,
2046
    ) -> Self::u16s;
2047
    /// # Safety
2048
    ///
2049
    /// See the trait-level safety documentation.
2050
    unsafe fn mask_load_ptr_u32s(
2051
      self,
2052
      mask: MemMask<Self::m32s>,
2053
      ptr: *const u32,
2054
    ) -> Self::u32s;
2055
    /// # Safety
2056
    ///
2057
    /// See the trait-level safety documentation.
2058
    unsafe fn mask_load_ptr_u64s(
2059
      self,
2060
      mask: MemMask<Self::m64s>,
2061
      ptr: *const u64,
2062
    ) -> Self::u64s;
2063
    /// # Safety
2064
    ///
2065
    /// See the trait-level safety documentation.
2066
    unsafe fn mask_store_ptr_c32s(
2067
      self,
2068
      mask: MemMask<Self::m32s>,
2069
      ptr: *mut c32,
2070
      values: Self::c32s,
2071
    );
2072
    /// # Safety
2073
    ///
2074
    /// See the trait-level safety documentation.
2075
    unsafe fn mask_store_ptr_c64s(
2076
      self,
2077
      mask: MemMask<Self::m64s>,
2078
      ptr: *mut c64,
2079
      values: Self::c64s,
2080
    );
2081
    /// # Safety
2082
    ///
2083
    /// See the trait-level safety documentation.
2084
    unsafe fn mask_store_ptr_u8s(
2085
      self,
2086
      mask: MemMask<Self::m8s>,
2087
      ptr: *mut u8,
2088
      values: Self::u8s,
2089
    );
2090
    /// # Safety
2091
    ///
2092
    /// See the trait-level safety documentation.
2093
    unsafe fn mask_store_ptr_u16s(
2094
      self,
2095
      mask: MemMask<Self::m16s>,
2096
      ptr: *mut u16,
2097
      values: Self::u16s,
2098
    );
2099
    /// # Safety
2100
    ///
2101
    /// See the trait-level safety documentation.
2102
    unsafe fn mask_store_ptr_u32s(
2103
      self,
2104
      mask: MemMask<Self::m32s>,
2105
      ptr: *mut u32,
2106
      values: Self::u32s,
2107
    );
2108
    /// # Safety
2109
    ///
2110
    /// See the trait-level safety documentation.
2111
    unsafe fn mask_store_ptr_u64s(
2112
      self,
2113
      mask: MemMask<Self::m64s>,
2114
      ptr: *mut u64,
2115
      values: Self::u64s,
2116
    );
2117
    fn mul_add_c32s(self, a: Self::c32s, b: Self::c32s, c: Self::c32s) -> Self::c32s;
2118
    fn mul_add_c64s(self, a: Self::c64s, b: Self::c64s, c: Self::c64s) -> Self::c64s;
2119
    fn mul_add_e_f32s(self, a: Self::f32s, b: Self::f32s, c: Self::f32s) -> Self::f32s;
2120
    fn mul_add_e_f64s(self, a: Self::f64s, b: Self::f64s, c: Self::f64s) -> Self::f64s;
2121
    fn mul_add_f32s(self, a: Self::f32s, b: Self::f32s, c: Self::f32s) -> Self::f32s;
2122
    fn mul_add_f64s(self, a: Self::f64s, b: Self::f64s, c: Self::f64s) -> Self::f64s;
2123
    fn negate_mul_add_e_f32s(self, a: Self::f32s, b: Self::f32s, c: Self::f32s) -> Self::f32s;
2124
    fn negate_mul_add_e_f64s(self, a: Self::f64s, b: Self::f64s, c: Self::f64s) -> Self::f64s;
2125
    fn negate_mul_add_f32s(self, a: Self::f32s, b: Self::f32s, c: Self::f32s) -> Self::f32s;
2126
    fn negate_mul_add_f64s(self, a: Self::f64s, b: Self::f64s, c: Self::f64s) -> Self::f64s;
2127
    fn mul_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::c32s;
2128
    fn mul_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::c64s;
2129
    fn neg_c32s(self, a: Self::c32s) -> Self::c32s;
2130
    fn neg_c64s(self, a: Self::c64s) -> Self::c64s;
2131
    fn min_u64s(self, a: Self::u64s, b: Self::u64s) -> Self::u64s;
2132
    fn min_i64s(self, a: Self::i64s, b: Self::i64s) -> Self::i64s;
2133
    fn max_u64s(self, a: Self::u64s, b: Self::u64s) -> Self::u64s;
2134
    fn max_i64s(self, a: Self::i64s, b: Self::i64s) -> Self::i64s;
2135
    fn mul_u64s(self, a: Self::u64s, b: Self::u64s) -> Self::u64s;
2136
    fn mul_i64s(self, a: Self::i64s, b: Self::i64s) -> Self::i64s;
2137
    fn partial_load_u32s(self, slice: &[u32]) -> Self::u32s;
2138
    fn partial_load_u64s(self, slice: &[u64]) -> Self::u64s;
2139
    fn partial_store_u32s(self, slice: &mut [u32], values: Self::u32s);
2140
    fn partial_store_u64s(self, slice: &mut [u64], values: Self::u64s);
2141
    fn reduce_max_c32s(self, a: Self::c32s) -> c32;
2142
    fn reduce_max_c64s(self, a: Self::c64s) -> c64;
2143
    fn reduce_max_f32s(self, a: Self::f32s) -> f32;
2144
    fn reduce_max_f64s(self, a: Self::f64s) -> f64;
2145
    fn reduce_min_c32s(self, a: Self::c32s) -> c32;
2146
    fn reduce_min_c64s(self, a: Self::c64s) -> c64;
2147
    fn reduce_min_f32s(self, a: Self::f32s) -> f32;
2148
    fn reduce_min_f64s(self, a: Self::f64s) -> f64;
2149
    fn reduce_product_f32s(self, a: Self::f32s) -> f32;
2150
    fn reduce_product_f64s(self, a: Self::f64s) -> f64;
2151
    fn reduce_sum_c32s(self, a: Self::c32s) -> c32;
2152
    fn reduce_sum_c64s(self, a: Self::c64s) -> c64;
2153
    fn reduce_sum_f32s(self, a: Self::f32s) -> f32;
2154
    fn reduce_sum_f64s(self, a: Self::f64s) -> f64;
2155
    fn rotate_right_c32s(self, a: Self::c32s, amount: usize) -> Self::c32s;
2156
    fn rotate_right_c64s(self, a: Self::c64s, amount: usize) -> Self::c64s;
2157
    fn rotate_right_u32s(self, a: Self::u32s, amount: usize) -> Self::u32s;
2158
    fn rotate_right_u64s(self, a: Self::u64s, amount: usize) -> Self::u64s;
2159
    fn select_u32s(
2160
      self,
2161
      mask: Self::m32s,
2162
      if_true: Self::u32s,
2163
      if_false: Self::u32s,
2164
    ) -> Self::u32s;
2165
    fn select_u64s(
2166
      self,
2167
      mask: Self::m64s,
2168
      if_true: Self::u64s,
2169
      if_false: Self::u64s,
2170
    ) -> Self::u64s;
2171
    fn splat_c32s(self, a: c32) -> Self::c32s;
2172
    fn splat_c64s(self, a: c64) -> Self::c64s;
2173
    fn sub_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::c32s;
2174
    fn sub_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::c64s;
2175
    fn swap_re_im_c32s(self, a: Self::c32s) -> Self::c32s;
2176
    fn swap_re_im_c64s(self, a: Self::c64s) -> Self::c64s;
2177
    fn widening_mul_u32s(self, a: Self::u32s, b: Self::u32s) -> (Self::u32s, Self::u32s);
2178
    fn wrapping_dyn_shl_u32s(self, a: Self::u32s, amount: Self::u32s) -> Self::u32s;
2179
    fn wrapping_dyn_shr_u32s(self, a: Self::u32s, amount: Self::u32s) -> Self::u32s;
2180
  });
2181
2182
  #[inline(always)]
2183
0
  fn vectorize<Op: WithSimd>(self, op: Op) -> Op::Output {
2184
0
    Simd::vectorize(self.0, op)
2185
0
  }
2186
2187
  #[inline(always)]
2188
0
  fn sqrt_f32s(self, a: Self::f32s) -> Self::f32s {
2189
0
    self.sqrt_f32x8(a)
2190
0
  }
2191
2192
  #[inline(always)]
2193
0
  fn sqrt_f64s(self, a: Self::f64s) -> Self::f64s {
2194
0
    self.sqrt_f64x4(a)
2195
0
  }
2196
}
2197
2198
impl Simd for V3_512b {
2199
  type c32s = f32x16;
2200
  type c64s = f64x8;
2201
  type f32s = f32x16;
2202
  type f64s = f64x8;
2203
  type i16s = i16x32;
2204
  type i32s = i32x16;
2205
  type i64s = i64x8;
2206
  type i8s = i8x64;
2207
  type m16s = m16x32;
2208
  type m32s = m32x16;
2209
  type m64s = m64x8;
2210
  type m8s = m8x64;
2211
  type u16s = u16x32;
2212
  type u32s = u32x16;
2213
  type u64s = u64x8;
2214
  type u8s = u8x64;
2215
2216
  const REGISTER_COUNT: usize = 8;
2217
2218
  inherit_x2!(V3_256b(*self), {
2219
    fn abs2_c32s(self, a: Self::c32s) -> Self::c32s;
2220
    fn abs2_c64s(self, a: Self::c64s) -> Self::c64s;
2221
    fn abs_max_c32s(self, a: Self::c32s) -> Self::c32s;
2222
    fn abs_max_c64s(self, a: Self::c64s) -> Self::c64s;
2223
    fn add_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::c32s;
2224
    fn add_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::c64s;
2225
    fn add_f32s(self, a: Self::f32s, b: Self::f32s) -> Self::f32s;
2226
    fn add_f64s(self, a: Self::f64s, b: Self::f64s) -> Self::f64s;
2227
    fn add_u8s(self, a: Self::u8s, b: Self::u8s) -> Self::u8s;
2228
    fn add_u16s(self, a: Self::u16s, b: Self::u16s) -> Self::u16s;
2229
    fn add_u32s(self, a: Self::u32s, b: Self::u32s) -> Self::u32s;
2230
    fn add_u64s(self, a: Self::u64s, b: Self::u64s) -> Self::u64s;
2231
    fn and_m32s(self, a: Self::m32s, b: Self::m32s) -> Self::m32s;
2232
    fn and_m64s(self, a: Self::m64s, b: Self::m64s) -> Self::m64s;
2233
    fn and_f32s(self, a: Self::f32s, b: Self::f32s) -> Self::f32s;
2234
    fn and_f64s(self, a: Self::f64s, b: Self::f64s) -> Self::f64s;
2235
    fn and_u8s(self, a: Self::u8s, b: Self::u8s) -> Self::u8s;
2236
    fn and_u16s(self, a: Self::u16s, b: Self::u16s) -> Self::u16s;
2237
    fn and_u32s(self, a: Self::u32s, b: Self::u32s) -> Self::u32s;
2238
    fn and_u64s(self, a: Self::u64s, b: Self::u64s) -> Self::u64s;
2239
    fn conj_c32s(self, a: Self::c32s) -> Self::c32s;
2240
    fn conj_c64s(self, a: Self::c64s) -> Self::c64s;
2241
    fn conj_mul_add_c32s(self, a: Self::c32s, b: Self::c32s, c: Self::c32s) -> Self::c32s;
2242
    fn conj_mul_add_c64s(self, a: Self::c64s, b: Self::c64s, c: Self::c64s) -> Self::c64s;
2243
    fn conj_mul_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::c32s;
2244
    fn conj_mul_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::c64s;
2245
    fn div_f32s(self, a: Self::f32s, b: Self::f32s) -> Self::f32s;
2246
    fn div_f64s(self, a: Self::f64s, b: Self::f64s) -> Self::f64s;
2247
    fn equal_f32s(self, a: Self::f32s, b: Self::f32s) -> Self::m32s;
2248
    fn equal_f64s(self, a: Self::f64s, b: Self::f64s) -> Self::m64s;
2249
    fn equal_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::m32s;
2250
    fn equal_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::m64s;
2251
    fn equal_u8s(self, a: Self::u8s, b: Self::u8s) -> Self::m8s;
2252
    fn equal_i8s(self, a: Self::i8s, b: Self::i8s) -> Self::m8s;
2253
    fn equal_u16s(self, a: Self::u16s, b: Self::u16s) -> Self::m16s;
2254
    fn equal_i16s(self, a: Self::i16s, b: Self::i16s) -> Self::m16s;
2255
    fn equal_u32s(self, a: Self::u32s, b: Self::u32s) -> Self::m32s;
2256
    fn equal_i32s(self, a: Self::i32s, b: Self::i32s) -> Self::m32s;
2257
    fn equal_u64s(self, a: Self::u64s, b: Self::u64s) -> Self::m64s;
2258
    fn equal_i64s(self, a: Self::i64s, b: Self::i64s) -> Self::m64s;
2259
    fn greater_than_or_equal_u8s(self, a: Self::u8s, b: Self::u8s) -> Self::m8s;
2260
    fn greater_than_or_equal_i8s(self, a: Self::i8s, b: Self::i8s) -> Self::m8s;
2261
    fn greater_than_or_equal_u16s(self, a: Self::u16s, b: Self::u16s) -> Self::m16s;
2262
    fn greater_than_or_equal_i16s(self, a: Self::i16s, b: Self::i16s) -> Self::m16s;
2263
    fn greater_than_or_equal_u32s(self, a: Self::u32s, b: Self::u32s) -> Self::m32s;
2264
    fn greater_than_or_equal_i32s(self, a: Self::i32s, b: Self::i32s) -> Self::m32s;
2265
    fn greater_than_or_equal_u64s(self, a: Self::u64s, b: Self::u64s) -> Self::m64s;
2266
    fn greater_than_or_equal_i64s(self, a: Self::i64s, b: Self::i64s) -> Self::m64s;
2267
    fn greater_than_or_equal_f32s(self, a: Self::f32s, b: Self::f32s) -> Self::m32s;
2268
    fn greater_than_or_equal_f64s(self, a: Self::f64s, b: Self::f64s) -> Self::m64s;
2269
    fn greater_than_u8s(self, a: Self::u8s, b: Self::u8s) -> Self::m8s;
2270
    fn greater_than_i8s(self, a: Self::i8s, b: Self::i8s) -> Self::m8s;
2271
    fn greater_than_u16s(self, a: Self::u16s, b: Self::u16s) -> Self::m16s;
2272
    fn greater_than_i16s(self, a: Self::i16s, b: Self::i16s) -> Self::m16s;
2273
    fn greater_than_u32s(self, a: Self::u32s, b: Self::u32s) -> Self::m32s;
2274
    fn greater_than_i32s(self, a: Self::i32s, b: Self::i32s) -> Self::m32s;
2275
    fn greater_than_u64s(self, a: Self::u64s, b: Self::u64s) -> Self::m64s;
2276
    fn greater_than_i64s(self, a: Self::i64s, b: Self::i64s) -> Self::m64s;
2277
    fn greater_than_f32s(self, a: Self::f32s, b: Self::f32s) -> Self::m32s;
2278
    fn greater_than_f64s(self, a: Self::f64s, b: Self::f64s) -> Self::m64s;
2279
    fn less_than_or_equal_u8s(self, a: Self::u8s, b: Self::u8s) -> Self::m8s;
2280
    fn less_than_or_equal_i8s(self, a: Self::i8s, b: Self::i8s) -> Self::m8s;
2281
    fn less_than_or_equal_u16s(self, a: Self::u16s, b: Self::u16s) -> Self::m16s;
2282
    fn less_than_or_equal_i16s(self, a: Self::i16s, b: Self::i16s) -> Self::m16s;
2283
    fn less_than_or_equal_u32s(self, a: Self::u32s, b: Self::u32s) -> Self::m32s;
2284
    fn less_than_or_equal_i32s(self, a: Self::i32s, b: Self::i32s) -> Self::m32s;
2285
    fn less_than_or_equal_u64s(self, a: Self::u64s, b: Self::u64s) -> Self::m64s;
2286
    fn less_than_or_equal_i64s(self, a: Self::i64s, b: Self::i64s) -> Self::m64s;
2287
    fn less_than_or_equal_f32s(self, a: Self::f32s, b: Self::f32s) -> Self::m32s;
2288
    fn less_than_or_equal_f64s(self, a: Self::f64s, b: Self::f64s) -> Self::m64s;
2289
    fn less_than_u8s(self, a: Self::u8s, b: Self::u8s) -> Self::m8s;
2290
    fn less_than_i8s(self, a: Self::i8s, b: Self::i8s) -> Self::m8s;
2291
    fn less_than_u16s(self, a: Self::u16s, b: Self::u16s) -> Self::m16s;
2292
    fn less_than_i16s(self, a: Self::i16s, b: Self::i16s) -> Self::m16s;
2293
    fn less_than_u32s(self, a: Self::u32s, b: Self::u32s) -> Self::m32s;
2294
    fn less_than_i32s(self, a: Self::i32s, b: Self::i32s) -> Self::m32s;
2295
    fn less_than_u64s(self, a: Self::u64s, b: Self::u64s) -> Self::m64s;
2296
    fn less_than_i64s(self, a: Self::i64s, b: Self::i64s) -> Self::m64s;
2297
    fn less_than_f32s(self, a: Self::f32s, b: Self::f32s) -> Self::m32s;
2298
    fn less_than_f64s(self, a: Self::f64s, b: Self::f64s) -> Self::m64s;
2299
    fn min_u8s(self, a: Self::u8s, b: Self::u8s) -> Self::u8s;
2300
    fn max_u8s(self, a: Self::u8s, b: Self::u8s) -> Self::u8s;
2301
    fn min_i8s(self, a: Self::i8s, b: Self::i8s) -> Self::i8s;
2302
    fn max_i8s(self, a: Self::i8s, b: Self::i8s) -> Self::i8s;
2303
    fn min_u16s(self, a: Self::u16s, b: Self::u16s) -> Self::u16s;
2304
    fn max_u16s(self, a: Self::u16s, b: Self::u16s) -> Self::u16s;
2305
    fn min_i16s(self, a: Self::i16s, b: Self::i16s) -> Self::i16s;
2306
    fn max_i16s(self, a: Self::i16s, b: Self::i16s) -> Self::i16s;
2307
    fn min_u32s(self, a: Self::u32s, b: Self::u32s) -> Self::u32s;
2308
    fn max_u32s(self, a: Self::u32s, b: Self::u32s) -> Self::u32s;
2309
    fn min_i32s(self, a: Self::i32s, b: Self::i32s) -> Self::i32s;
2310
    fn max_i32s(self, a: Self::i32s, b: Self::i32s) -> Self::i32s;
2311
    fn max_f32s(self, a: Self::f32s, b: Self::f32s) -> Self::f32s;
2312
    fn max_f64s(self, a: Self::f64s, b: Self::f64s) -> Self::f64s;
2313
    fn min_f32s(self, a: Self::f32s, b: Self::f32s) -> Self::f32s;
2314
    fn min_f64s(self, a: Self::f64s, b: Self::f64s) -> Self::f64s;
2315
    fn mul_add_c32s(self, a: Self::c32s, b: Self::c32s, c: Self::c32s) -> Self::c32s;
2316
    fn mul_add_c64s(self, a: Self::c64s, b: Self::c64s, c: Self::c64s) -> Self::c64s;
2317
    fn mul_add_e_f32s(self, a: Self::f32s, b: Self::f32s, c: Self::f32s) -> Self::f32s;
2318
    fn mul_add_e_f64s(self, a: Self::f64s, b: Self::f64s, c: Self::f64s) -> Self::f64s;
2319
    fn mul_add_f32s(self, a: Self::f32s, b: Self::f32s, c: Self::f32s) -> Self::f32s;
2320
    fn mul_add_f64s(self, a: Self::f64s, b: Self::f64s, c: Self::f64s) -> Self::f64s;
2321
    fn negate_mul_add_e_f32s(self, a: Self::f32s, b: Self::f32s, c: Self::f32s) -> Self::f32s;
2322
    fn negate_mul_add_e_f64s(self, a: Self::f64s, b: Self::f64s, c: Self::f64s) -> Self::f64s;
2323
    fn negate_mul_add_f32s(self, a: Self::f32s, b: Self::f32s, c: Self::f32s) -> Self::f32s;
2324
    fn negate_mul_add_f64s(self, a: Self::f64s, b: Self::f64s, c: Self::f64s) -> Self::f64s;
2325
    fn mul_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::c32s;
2326
    fn mul_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::c64s;
2327
    fn mul_f32s(self, a: Self::f32s, b: Self::f32s) -> Self::f32s;
2328
    fn mul_f64s(self, a: Self::f64s, b: Self::f64s) -> Self::f64s;
2329
    fn mul_u16s(self, a: Self::u16s, b: Self::u16s) -> Self::u16s;
2330
    fn mul_i16s(self, a: Self::i16s, b: Self::i16s) -> Self::i16s;
2331
    fn mul_u32s(self, a: Self::u32s, b: Self::u32s) -> Self::u32s;
2332
    fn mul_i32s(self, a: Self::i32s, b: Self::i32s) -> Self::i32s;
2333
    fn mul_u64s(self, a: Self::u64s, b: Self::u64s) -> Self::u64s;
2334
    fn mul_i64s(self, a: Self::i64s, b: Self::i64s) -> Self::i64s;
2335
    fn neg_c32s(self, a: Self::c32s) -> Self::c32s;
2336
    fn neg_c64s(self, a: Self::c64s) -> Self::c64s;
2337
    fn not_m8s(self, a: Self::m8s) -> Self::m8s;
2338
    fn not_m16s(self, a: Self::m16s) -> Self::m16s;
2339
    fn not_m32s(self, a: Self::m32s) -> Self::m32s;
2340
    fn not_m64s(self, a: Self::m64s) -> Self::m64s;
2341
    fn not_f32s(self, a: Self::f32s) -> Self::f32s;
2342
    fn not_f64s(self, a: Self::f64s) -> Self::f64s;
2343
    fn not_u8s(self, a: Self::u8s) -> Self::u8s;
2344
    fn not_u16s(self, a: Self::u16s) -> Self::u16s;
2345
    fn not_u32s(self, a: Self::u32s) -> Self::u32s;
2346
    fn not_u64s(self, a: Self::u64s) -> Self::u64s;
2347
    fn or_m8s(self, a: Self::m8s, b: Self::m8s) -> Self::m8s;
2348
    fn or_m16s(self, a: Self::m16s, b: Self::m16s) -> Self::m16s;
2349
    fn or_m32s(self, a: Self::m32s, b: Self::m32s) -> Self::m32s;
2350
    fn or_m64s(self, a: Self::m64s, b: Self::m64s) -> Self::m64s;
2351
    fn or_f32s(self, a: Self::f32s, b: Self::f32s) -> Self::f32s;
2352
    fn or_f64s(self, a: Self::f64s, b: Self::f64s) -> Self::f64s;
2353
    fn or_u8s(self, a: Self::u8s, b: Self::u8s) -> Self::u8s;
2354
    fn or_u16s(self, a: Self::u16s, b: Self::u16s) -> Self::u16s;
2355
    fn or_u32s(self, a: Self::u32s, b: Self::u32s) -> Self::u32s;
2356
    fn or_u64s(self, a: Self::u64s, b: Self::u64s) -> Self::u64s;
2357
    fn select_u32s(
2358
      self,
2359
      mask: Self::m32s,
2360
      if_true: Self::u32s,
2361
      if_false: Self::u32s,
2362
    ) -> Self::u32s;
2363
    fn select_u64s(
2364
      self,
2365
      mask: Self::m64s,
2366
      if_true: Self::u64s,
2367
      if_false: Self::u64s,
2368
    ) -> Self::u64s;
2369
    fn sub_c32s(self, a: Self::c32s, b: Self::c32s) -> Self::c32s;
2370
    fn sub_c64s(self, a: Self::c64s, b: Self::c64s) -> Self::c64s;
2371
    fn sub_f32s(self, a: Self::f32s, b: Self::f32s) -> Self::f32s;
2372
    fn sub_f64s(self, a: Self::f64s, b: Self::f64s) -> Self::f64s;
2373
    fn sub_u8s(self, a: Self::u8s, b: Self::u8s) -> Self::u8s;
2374
    fn sub_i8s(self, a: Self::i8s, b: Self::i8s) -> Self::i8s;
2375
    fn sub_u16s(self, a: Self::u16s, b: Self::u16s) -> Self::u16s;
2376
    fn sub_i16s(self, a: Self::i16s, b: Self::i16s) -> Self::i16s;
2377
    fn sub_u32s(self, a: Self::u32s, b: Self::u32s) -> Self::u32s;
2378
    fn sub_i32s(self, a: Self::i32s, b: Self::i32s) -> Self::i32s;
2379
    fn sub_u64s(self, a: Self::u64s, b: Self::u64s) -> Self::u64s;
2380
    fn sub_i64s(self, a: Self::i64s, b: Self::i64s) -> Self::i64s;
2381
    fn swap_re_im_c32s(self, a: Self::c32s) -> Self::c32s;
2382
    fn swap_re_im_c64s(self, a: Self::c64s) -> Self::c64s;
2383
    fn wrapping_dyn_shl_u32s(self, a: Self::u32s, amount: Self::u32s) -> Self::u32s;
2384
    fn wrapping_dyn_shr_u32s(self, a: Self::u32s, amount: Self::u32s) -> Self::u32s;
2385
    fn xor_m8s(self, a: Self::m8s, b: Self::m8s) -> Self::m8s;
2386
    fn xor_m16s(self, a: Self::m16s, b: Self::m16s) -> Self::m16s;
2387
    fn xor_m32s(self, a: Self::m32s, b: Self::m32s) -> Self::m32s;
2388
    fn xor_m64s(self, a: Self::m64s, b: Self::m64s) -> Self::m64s;
2389
    fn xor_f32s(self, a: Self::f32s, b: Self::f32s) -> Self::f32s;
2390
    fn xor_f64s(self, a: Self::f64s, b: Self::f64s) -> Self::f64s;
2391
    fn xor_u8s(self, a: Self::u8s, b: Self::u8s) -> Self::u8s;
2392
    fn xor_u16s(self, a: Self::u16s, b: Self::u16s) -> Self::u16s;
2393
    fn xor_u32s(self, a: Self::u32s, b: Self::u32s) -> Self::u32s;
2394
    fn xor_u64s(self, a: Self::u64s, b: Self::u64s) -> Self::u64s;
2395
  });
2396
2397
  inherit_x2!(V3_256b(*self), splat, {
2398
    fn splat_c32s(self, value: c32) -> Self::c32s;
2399
    fn splat_c64s(self, value: c64) -> Self::c64s;
2400
    fn splat_f32s(self, value: f32) -> Self::f32s;
2401
    fn splat_f64s(self, value: f64) -> Self::f64s;
2402
    fn splat_u8s(self, value: u8) -> Self::u8s;
2403
    fn splat_i8s(self, value: i8) -> Self::i8s;
2404
    fn splat_u16s(self, value: u16) -> Self::u16s;
2405
    fn splat_i16s(self, value: i16) -> Self::i16s;
2406
    fn splat_u32s(self, value: u32) -> Self::u32s;
2407
    fn splat_i32s(self, value: i32) -> Self::i32s;
2408
    fn splat_u64s(self, value: u64) -> Self::u64s;
2409
    fn splat_i64s(self, value: i64) -> Self::i64s;
2410
  });
2411
2412
  inherit_x2!(V3_256b(*self), wide, {
2413
    fn widening_mul_u32s(self, a: Self::u32s, b: Self::u32s) -> (Self::u32s, Self::u32s);
2414
  });
2415
2416
  #[inline(always)]
2417
0
  fn rotate_right_c32s(self, a: Self::c32s, amount: usize) -> Self::c32s {
2418
0
    let simd = V3_256b(*self);
2419
0
    let amount = amount % Self::C32_LANES;
2420
0
    let [mut a0, mut a1]: [_; 2] = cast!(a);
2421
0
    if amount >= Self::C32_LANES / 2 {
2422
0
      core::mem::swap(&mut a0, &mut a1);
2423
0
    }
2424
0
    let amount = amount % (Self::C32_LANES / 2);
2425
0
    let mask = simd.mask_between_m32s(0, amount as _).mask();
2426
0
    let a0 = simd.rotate_right_c32s(a0, amount);
2427
0
    let a1 = simd.rotate_right_c32s(a1, amount);
2428
2429
0
    cast!([
2430
0
      simd.select_f32s(mask, a1, a0),
2431
0
      simd.select_f32s(mask, a0, a1),
2432
0
    ])
2433
0
  }
2434
2435
  #[inline(always)]
2436
0
  fn rotate_right_c64s(self, a: Self::c64s, amount: usize) -> Self::c64s {
2437
0
    let simd = V3_256b(*self);
2438
0
    let amount = amount % Self::C64_LANES;
2439
0
    let [mut a0, mut a1]: [_; 2] = cast!(a);
2440
0
    if amount >= Self::C64_LANES / 2 {
2441
0
      core::mem::swap(&mut a0, &mut a1);
2442
0
    }
2443
0
    let amount = amount % (Self::C64_LANES / 2);
2444
0
    let mask = simd.mask_between_m64s(0, amount as _).mask();
2445
0
    let a0 = simd.rotate_right_c64s(a0, amount);
2446
0
    let a1 = simd.rotate_right_c64s(a1, amount);
2447
2448
0
    cast!([
2449
0
      simd.select_f64s(mask, a1, a0),
2450
0
      simd.select_f64s(mask, a0, a1),
2451
0
    ])
2452
0
  }
2453
2454
  #[inline(always)]
2455
0
  fn rotate_right_u32s(self, a: Self::u32s, amount: usize) -> Self::u32s {
2456
0
    let simd = V3_256b(*self);
2457
0
    let amount = amount % Self::U32_LANES;
2458
0
    let [mut a0, mut a1]: [_; 2] = cast!(a);
2459
0
    if amount >= Self::U32_LANES / 2 {
2460
0
      core::mem::swap(&mut a0, &mut a1);
2461
0
    }
2462
0
    let amount = amount % (Self::U32_LANES / 2);
2463
0
    let mask = simd.mask_between_m32s(0, amount as _).mask();
2464
0
    let a0 = simd.rotate_right_u32s(a0, amount);
2465
0
    let a1 = simd.rotate_right_u32s(a1, amount);
2466
2467
0
    cast!([
2468
0
      simd.select_u32s(mask, a1, a0),
2469
0
      simd.select_u32s(mask, a0, a1),
2470
0
    ])
2471
0
  }
2472
2473
  #[inline(always)]
2474
0
  fn rotate_right_u64s(self, a: Self::u64s, amount: usize) -> Self::u64s {
2475
0
    let simd = V3_256b(*self);
2476
0
    let amount = amount % Self::U64_LANES;
2477
0
    let [mut a0, mut a1]: [_; 2] = cast!(a);
2478
0
    if amount >= Self::U64_LANES / 2 {
2479
0
      core::mem::swap(&mut a0, &mut a1);
2480
0
    }
2481
0
    let amount = amount % (Self::U64_LANES / 2);
2482
0
    let mask = simd.mask_between_m64s(0, amount as _).mask();
2483
0
    let a0 = simd.rotate_right_u64s(a0, amount);
2484
0
    let a1 = simd.rotate_right_u64s(a1, amount);
2485
2486
0
    cast!([
2487
0
      simd.select_u64s(mask, a1, a0),
2488
0
      simd.select_u64s(mask, a0, a1),
2489
0
    ])
2490
0
  }
2491
2492
  /// # Safety
2493
  ///
2494
  /// See the trait-level safety documentation.
2495
  #[inline(always)]
2496
0
  unsafe fn mask_load_ptr_c32s(self, mask: MemMask<Self::m32s>, ptr: *const c32) -> Self::c32s {
2497
0
    let simd = V3_256b(*self);
2498
0
    let mask: [_; 2] = cast!(mask.mask());
2499
0
    cast!([
2500
0
      simd.mask_load_ptr_c32s(MemMask::new(mask[0]), ptr.wrapping_add(0)),
2501
0
      simd.mask_load_ptr_c32s(MemMask::new(mask[1]), ptr.wrapping_add(Self::C32_LANES)),
2502
0
    ])
2503
0
  }
2504
2505
  /// # Safety
2506
  ///
2507
  /// See the trait-level safety documentation.
2508
  #[inline(always)]
2509
0
  unsafe fn mask_load_ptr_c64s(self, mask: MemMask<Self::m64s>, ptr: *const c64) -> Self::c64s {
2510
0
    let simd = V3_256b(*self);
2511
0
    let mask: [_; 2] = cast!(mask.mask());
2512
0
    cast!([
2513
0
      simd.mask_load_ptr_c64s(MemMask::new(mask[0]), ptr.wrapping_add(0)),
2514
0
      simd.mask_load_ptr_c64s(MemMask::new(mask[1]), ptr.wrapping_add(Self::C64_LANES)),
2515
0
    ])
2516
0
  }
2517
2518
  /// # Safety
2519
  ///
2520
  /// See the trait-level safety documentation.
2521
  #[inline(always)]
2522
0
  unsafe fn mask_load_ptr_u8s(self, mask: MemMask<Self::m8s>, ptr: *const u8) -> Self::u8s {
2523
0
    let simd = V3_256b(*self);
2524
0
    let mask: [_; 2] = cast!(mask.mask());
2525
0
    cast!([
2526
0
      simd.mask_load_ptr_u8s(MemMask::new(mask[0]), ptr.wrapping_add(0)),
2527
0
      simd.mask_load_ptr_u8s(MemMask::new(mask[1]), ptr.wrapping_add(V3_256b::U8_LANES)),
2528
0
    ])
2529
0
  }
2530
2531
  /// # Safety
2532
  ///
2533
  /// See the trait-level safety documentation.
2534
  #[inline(always)]
2535
0
  unsafe fn mask_load_ptr_u16s(self, mask: MemMask<Self::m16s>, ptr: *const u16) -> Self::u16s {
2536
0
    let simd = V3_256b(*self);
2537
0
    let mask: [_; 2] = cast!(mask.mask());
2538
0
    cast!([
2539
0
      simd.mask_load_ptr_u16s(MemMask::new(mask[0]), ptr.wrapping_add(0)),
2540
0
      simd.mask_load_ptr_u16s(MemMask::new(mask[1]), ptr.wrapping_add(V3_256b::U16_LANES)),
2541
0
    ])
2542
0
  }
2543
2544
  /// # Safety
2545
  ///
2546
  /// See the trait-level safety documentation.
2547
  #[inline(always)]
2548
0
  unsafe fn mask_load_ptr_u32s(self, mask: MemMask<Self::m32s>, ptr: *const u32) -> Self::u32s {
2549
0
    let simd = V3_256b(*self);
2550
0
    let mask: [_; 2] = cast!(mask.mask());
2551
0
    cast!([
2552
0
      simd.mask_load_ptr_u32s(MemMask::new(mask[0]), ptr.wrapping_add(0)),
2553
0
      simd.mask_load_ptr_u32s(MemMask::new(mask[1]), ptr.wrapping_add(Self::U32_LANES)),
2554
0
    ])
2555
0
  }
2556
2557
  /// # Safety
2558
  ///
2559
  /// See the trait-level safety documentation.
2560
  #[inline(always)]
2561
0
  unsafe fn mask_load_ptr_u64s(self, mask: MemMask<Self::m64s>, ptr: *const u64) -> Self::u64s {
2562
0
    let simd = V3_256b(*self);
2563
0
    let mask: [_; 2] = cast!(mask.mask());
2564
0
    cast!([
2565
0
      simd.mask_load_ptr_u64s(MemMask::new(mask[0]), ptr.wrapping_add(0)),
2566
0
      simd.mask_load_ptr_u64s(MemMask::new(mask[1]), ptr.wrapping_add(Self::U64_LANES)),
2567
0
    ])
2568
0
  }
2569
2570
  /// # Safety
2571
  ///
2572
  /// See the trait-level safety documentation.
2573
  #[inline(always)]
2574
0
  unsafe fn mask_store_ptr_c32s(
2575
0
    self,
2576
0
    mask: MemMask<Self::m32s>,
2577
0
    ptr: *mut c32,
2578
0
    values: Self::c32s,
2579
0
  ) {
2580
0
    let simd = V3_256b(*self);
2581
0
    let mask: [_; 2] = cast!(mask.mask());
2582
0
    let values: [_; 2] = cast!(values);
2583
0
    cast!([
2584
0
      simd.mask_store_ptr_c32s(MemMask::new(mask[0]), ptr.wrapping_add(0), values[0]),
2585
0
      simd.mask_store_ptr_c32s(
2586
0
        MemMask::new(mask[1]),
2587
0
        ptr.wrapping_add(Self::C32_LANES),
2588
0
        values[1]
2589
0
      ),
2590
0
    ])
2591
0
  }
2592
2593
  /// # Safety
2594
  ///
2595
  /// See the trait-level safety documentation.
2596
  #[inline(always)]
2597
0
  unsafe fn mask_store_ptr_c64s(
2598
0
    self,
2599
0
    mask: MemMask<Self::m64s>,
2600
0
    ptr: *mut c64,
2601
0
    values: Self::c64s,
2602
0
  ) {
2603
0
    let simd = V3_256b(*self);
2604
0
    let mask: [_; 2] = cast!(mask.mask());
2605
0
    let values: [_; 2] = cast!(values);
2606
0
    cast!([
2607
0
      simd.mask_store_ptr_c64s(MemMask::new(mask[0]), ptr.wrapping_add(0), values[0]),
2608
0
      simd.mask_store_ptr_c64s(
2609
0
        MemMask::new(mask[1]),
2610
0
        ptr.wrapping_add(Self::C64_LANES),
2611
0
        values[1]
2612
0
      ),
2613
0
    ])
2614
0
  }
2615
2616
  /// # Safety
2617
  ///
2618
  /// See the trait-level safety documentation.
2619
  #[inline(always)]
2620
0
  unsafe fn mask_store_ptr_u8s(self, mask: MemMask<Self::m8s>, ptr: *mut u8, values: Self::u8s) {
2621
0
    let simd = V3_256b(*self);
2622
0
    let mask: [_; 2] = cast!(mask.mask());
2623
0
    let values: [_; 2] = cast!(values);
2624
0
    cast!([
2625
0
      simd.mask_store_ptr_u8s(MemMask::new(mask[0]), ptr.wrapping_add(0), values[0]),
2626
0
      simd.mask_store_ptr_u8s(
2627
0
        MemMask::new(mask[1]),
2628
0
        ptr.wrapping_add(V3_256b::U8_LANES),
2629
0
        values[1]
2630
0
      ),
2631
0
    ])
2632
0
  }
2633
2634
  /// # Safety
2635
  ///
2636
  /// See the trait-level safety documentation.
2637
  #[inline(always)]
2638
0
  unsafe fn mask_store_ptr_u16s(
2639
0
    self,
2640
0
    mask: MemMask<Self::m16s>,
2641
0
    ptr: *mut u16,
2642
0
    values: Self::u16s,
2643
0
  ) {
2644
0
    let simd = V3_256b(*self);
2645
0
    let mask: [_; 2] = cast!(mask.mask());
2646
0
    let values: [_; 2] = cast!(values);
2647
0
    cast!([
2648
0
      simd.mask_store_ptr_u16s(MemMask::new(mask[0]), ptr.wrapping_add(0), values[0]),
2649
0
      simd.mask_store_ptr_u16s(
2650
0
        MemMask::new(mask[1]),
2651
0
        ptr.wrapping_add(V3_256b::U16_LANES),
2652
0
        values[1]
2653
0
      ),
2654
0
    ])
2655
0
  }
2656
2657
  /// # Safety
2658
  ///
2659
  /// See the trait-level safety documentation.
2660
  #[inline(always)]
2661
0
  unsafe fn mask_store_ptr_u32s(
2662
0
    self,
2663
0
    mask: MemMask<Self::m32s>,
2664
0
    ptr: *mut u32,
2665
0
    values: Self::u32s,
2666
0
  ) {
2667
0
    let simd = V3_256b(*self);
2668
0
    let mask: [_; 2] = cast!(mask.mask());
2669
0
    let values: [_; 2] = cast!(values);
2670
0
    cast!([
2671
0
      simd.mask_store_ptr_u32s(MemMask::new(mask[0]), ptr.wrapping_add(0), values[0]),
2672
0
      simd.mask_store_ptr_u32s(
2673
0
        MemMask::new(mask[1]),
2674
0
        ptr.wrapping_add(Self::U32_LANES),
2675
0
        values[1]
2676
0
      ),
2677
0
    ])
2678
0
  }
2679
2680
  /// # Safety
2681
  ///
2682
  /// See the trait-level safety documentation.
2683
  #[inline(always)]
2684
0
  unsafe fn mask_store_ptr_u64s(
2685
0
    self,
2686
0
    mask: MemMask<Self::m64s>,
2687
0
    ptr: *mut u64,
2688
0
    values: Self::u64s,
2689
0
  ) {
2690
0
    let simd = V3_256b(*self);
2691
0
    let mask: [_; 2] = cast!(mask.mask());
2692
0
    let values: [_; 2] = cast!(values);
2693
0
    cast!([
2694
0
      simd.mask_store_ptr_u64s(MemMask::new(mask[0]), ptr.wrapping_add(0), values[0]),
2695
0
      simd.mask_store_ptr_u64s(
2696
0
        MemMask::new(mask[1]),
2697
0
        ptr.wrapping_add(Self::U64_LANES),
2698
0
        values[1]
2699
0
      ),
2700
0
    ])
2701
0
  }
2702
2703
  #[inline(always)]
2704
0
  fn reduce_max_c32s(self, a: Self::c32s) -> c32 {
2705
0
    let simd = V3_256b(*self);
2706
0
    let a: [_; 2] = cast!(a);
2707
0
    simd.reduce_max_c32s(simd.max_f32s(a[0], a[1]))
2708
0
  }
2709
2710
  #[inline(always)]
2711
0
  fn reduce_max_c64s(self, a: Self::c64s) -> c64 {
2712
0
    let simd = V3_256b(*self);
2713
0
    let a: [_; 2] = cast!(a);
2714
0
    simd.reduce_max_c64s(simd.max_f64s(a[0], a[1]))
2715
0
  }
2716
2717
  #[inline(always)]
2718
0
  fn reduce_max_f32s(self, a: Self::f32s) -> f32 {
2719
0
    let simd = V3_256b(*self);
2720
0
    let a: [_; 2] = cast!(a);
2721
0
    simd.reduce_max_f32s(simd.max_f32s(a[0], a[1]))
2722
0
  }
2723
2724
  #[inline(always)]
2725
0
  fn reduce_max_f64s(self, a: Self::f64s) -> f64 {
2726
0
    let simd = V3_256b(*self);
2727
0
    let a: [_; 2] = cast!(a);
2728
0
    simd.reduce_max_f64s(simd.max_f64s(a[0], a[1]))
2729
0
  }
2730
2731
  #[inline(always)]
2732
0
  fn reduce_min_c32s(self, a: Self::c32s) -> c32 {
2733
0
    let simd = V3_256b(*self);
2734
0
    let a: [_; 2] = cast!(a);
2735
0
    simd.reduce_min_c32s(simd.min_f32s(a[0], a[1]))
2736
0
  }
2737
2738
  #[inline(always)]
2739
0
  fn reduce_min_c64s(self, a: Self::c64s) -> c64 {
2740
0
    let simd = V3_256b(*self);
2741
0
    let a: [_; 2] = cast!(a);
2742
0
    simd.reduce_min_c64s(simd.min_f64s(a[0], a[1]))
2743
0
  }
2744
2745
  #[inline(always)]
2746
0
  fn reduce_min_f32s(self, a: Self::f32s) -> f32 {
2747
0
    let simd = V3_256b(*self);
2748
0
    let a: [_; 2] = cast!(a);
2749
0
    simd.reduce_min_f32s(simd.min_f32s(a[0], a[1]))
2750
0
  }
2751
2752
  #[inline(always)]
2753
0
  fn reduce_min_f64s(self, a: Self::f64s) -> f64 {
2754
0
    let simd = V3_256b(*self);
2755
0
    let a: [_; 2] = cast!(a);
2756
0
    simd.reduce_min_f64s(simd.min_f64s(a[0], a[1]))
2757
0
  }
2758
2759
  #[inline(always)]
2760
0
  fn reduce_product_f32s(self, a: Self::f32s) -> f32 {
2761
0
    let simd = V3_256b(*self);
2762
0
    let a: [_; 2] = cast!(a);
2763
0
    simd.reduce_product_f32s(simd.mul_f32s(a[0], a[1]))
2764
0
  }
2765
2766
  #[inline(always)]
2767
0
  fn reduce_product_f64s(self, a: Self::f64s) -> f64 {
2768
0
    let simd = V3_256b(*self);
2769
0
    let a: [_; 2] = cast!(a);
2770
0
    simd.reduce_product_f64s(simd.mul_f64s(a[0], a[1]))
2771
0
  }
2772
2773
  #[inline(always)]
2774
0
  fn reduce_sum_c32s(self, a: Self::c32s) -> c32 {
2775
0
    let simd = V3_256b(*self);
2776
0
    let a: [_; 2] = cast!(a);
2777
0
    simd.reduce_sum_c32s(simd.add_c32s(a[0], a[1]))
2778
0
  }
2779
2780
  #[inline(always)]
2781
0
  fn reduce_sum_c64s(self, a: Self::c64s) -> c64 {
2782
0
    let simd = V3_256b(*self);
2783
0
    let a: [_; 2] = cast!(a);
2784
0
    simd.reduce_sum_c64s(simd.add_c64s(a[0], a[1]))
2785
0
  }
2786
2787
  #[inline(always)]
2788
0
  fn reduce_sum_f32s(self, a: Self::f32s) -> f32 {
2789
0
    let simd = V3_256b(*self);
2790
0
    let a: [_; 2] = cast!(a);
2791
0
    simd.reduce_sum_f32s(simd.add_f32s(a[0], a[1]))
2792
0
  }
2793
2794
  #[inline(always)]
2795
0
  fn reduce_sum_f64s(self, a: Self::f64s) -> f64 {
2796
0
    let simd = V3_256b(*self);
2797
0
    let a: [_; 2] = cast!(a);
2798
0
    simd.reduce_sum_f64s(simd.add_f64s(a[0], a[1]))
2799
0
  }
2800
2801
  #[inline(always)]
2802
0
  fn vectorize<Op: WithSimd>(self, op: Op) -> Op::Output {
2803
0
    Simd::vectorize(self.0, op)
2804
0
  }
2805
2806
  #[inline(always)]
2807
0
  fn max_u64s(self, a: Self::u64s, b: Self::u64s) -> Self::u64s {
2808
0
    Scalar512b.max_u64s(a, b)
2809
0
  }
2810
2811
  #[inline(always)]
2812
0
  fn max_i64s(self, a: Self::i64s, b: Self::i64s) -> Self::i64s {
2813
0
    Scalar512b.max_i64s(a, b)
2814
0
  }
2815
2816
  #[inline(always)]
2817
0
  fn min_u64s(self, a: Self::u64s, b: Self::u64s) -> Self::u64s {
2818
0
    Scalar512b.min_u64s(a, b)
2819
0
  }
2820
2821
  #[inline(always)]
2822
0
  fn min_i64s(self, a: Self::i64s, b: Self::i64s) -> Self::i64s {
2823
0
    Scalar512b.max_i64s(a, b)
2824
0
  }
2825
2826
  #[inline(always)]
2827
0
  fn sqrt_f32s(self, a: Self::f32s) -> Self::f32s {
2828
0
    let a: [_; 2] = cast!(a);
2829
0
    cast!([self.sqrt_f32x8(a[0]), self.sqrt_f32x8(a[1]),])
2830
0
  }
2831
2832
  #[inline(always)]
2833
0
  fn sqrt_f64s(self, a: Self::f64s) -> Self::f64s {
2834
0
    let a: [_; 2] = cast!(a);
2835
0
    cast!([self.sqrt_f64x4(a[0]), self.sqrt_f64x4(a[1]),])
2836
0
  }
2837
}
2838
2839
impl V3 {
2840
  binop_256_nosign!(avx: add, "Adds the elements of each lane of `a` and `b`.", f32 x 8, f64 x 4);
2841
2842
  binop_256_nosign!(avx2: add, "Adds the elements of each lane of `a` and `b`, with wrapping on overflow.", wrapping_add, u8 x 32, i8 x 32, u16 x 16, i16 x 16, u32 x 8, i32 x 8, u64 x 4, i64 x 4);
2843
2844
  binop_256!(avx: and, "Returns `a & b` for each bit in `a` and `b`.", f32 x 8, f64 x 4);
2845
2846
  binop_256_full!(avx2: and, "Returns `a & b` for each bit in `a` and `b`.", m8 x 32, u8 x 32, i8 x 32, m16 x 16, u16 x 16, i16 x 16, m32 x 8, u32 x 8, i32 x 8, m64 x 4, u64 x 4, i64 x 4);
2847
2848
  binop_256!(avx: andnot, "Returns `!a & b` for each bit in `a` and `b`.", f32 x 8, f64 x 4);
2849
2850
  binop_256_full!(avx2: andnot, "Returns `!a & b` for each bit in `a` and `b`.", m8 x 32, u8 x 32, i8 x 32, m16 x 16, u16 x 16, i16 x 16, m32 x 8, u32 x 8, i32 x 8, m64 x 4, u64 x 4, i64 x 4);
2851
2852
  binop_256!(avx2: sign, r#"Applies the sign of each element of `sign` to the corresponding lane in `a`.
2853
- If `sign` is zero, the corresponding element is zeroed.
2854
- If `sign` is positive, the corresponding element is returned as is.
2855
- If `sign` is negative, the corresponding element is negated."#, apply_sign, i8 x 32, i16 x 16, i32 x 8);
2856
2857
  binop_256!(avx2: avg, "Computes `average(a, b)` for each lane of `a` and `b`.", average, u8 x 32, u16 x 16);
2858
2859
  unop_256!(avx: ceil, "Returns `ceil(a)` for each lane of `a`, rounding towards positive infinity.", f32 x 8, f64 x 4);
2860
2861
  binop_256_nosign!(avx2: cmpeq, "Compares the elements in each lane of `a` and `b` for equality.", cmp_eq, m8 x 32 => m8, u8 x 32 => m8, i8 x 32 => m8, m16 x 16 => m16, u16 x 16 => m16, i16 x 16 => m16, m32 x 8 => m32, u32 x 8 => m32, i32 x 8 => m32, m64 x 4 => m64, u64 x 4 => m64, i64 x 4 => m64);
2862
2863
  binop_256!(avx2: cmpgt, "Compares the elements in each lane of `a` and `b` for equality.", cmp_gt, i8 x 32 => m8, i16 x 16 => m16, i32 x 8 => m32, i64 x 4 => m64);
2864
2865
  binop_256!(avx: div, "Divides the elements of each lane of `a` and `b`.", f32 x 8, f64 x 4);
2866
2867
  unop_256!(avx: floor, "Rounds the elements of each lane of `a` to the nearest integer towards negative infinity.", f32 x 8, f64 x 4);
2868
2869
  binop_256_nosign!(avx: hadd, "[_mm_hadd_ps](core::arch::x86_64::_mm_hadd_ps)", horizontal_add_pack, f32 x 8, f64 x 4);
2870
2871
  binop_256_nosign!(avx2: hadd, "[_mm_hadd_ps](core::arch::x86_64::_mm_hadd_ps)", horizontal_add_pack, u16 x 16, i16 x 16, u32 x 8, i32 x 8);
2872
2873
  binop_256_nosign!(avx: hsub, "[_mm_hsub_ps](core::arch::x86_64::_mm_hsub_ps)", horizontal_sub_pack, f32 x 8, f64 x 4);
2874
2875
  binop_256_nosign!(avx2: hsub, "[_mm_hsub_ps](core::arch::x86_64::_mm_hsub_ps)", horizontal_sub_pack, u16 x 16, i16 x 16, u32 x 8, i32 x 8);
2876
2877
  binop_256!(avx: max, "Computes `max(a, b)`. for each lane in `a` and `b`.", f32 x 8, f64 x 4);
2878
2879
  binop_256!(avx2: max, "Computes `max(a, b)`. for each lane in `a` and `b`.", u8 x 32, i8 x 32, u16 x 16, i16 x 16, u32 x 8, i32 x 8);
2880
2881
  binop_256!(avx: min, "Computes `min(a, b)`. for each lane in `a` and `b`.", f32 x 8, f64 x 4);
2882
2883
  binop_256!(avx2: min, "Computes `min(a, b)`. for each lane in `a` and `b`.", u8 x 32, i8 x 32, u16 x 16, i16 x 16, u32 x 8, i32 x 8);
2884
2885
  binop_256!(avx: mul, "Computes `a * b` for each lane in `a` and `b`.", f32 x 8, f64 x 4);
2886
2887
  binop_256_nosign!(avx2: mullo, "Computes `a * b` for each lane in `a` and `b`, with wrapping overflow.", wrapping_mul, u16 x 16, i16 x 16, u32 x 8, i32 x 8);
2888
2889
  binop_256!(avx: or, "Returns `a | b` for each bit in `a` and `b`.", f32 x 8, f64 x 4);
2890
2891
  binop_256_full!(avx2: or, "Returns `a | b` for each bit in `a` and `b`.", m8 x 32, u8 x 32, i8 x 32, m16 x 16, u16 x 16, i16 x 16, m32 x 8, u32 x 8, i32 x 8, m64 x 4, u64 x 4, i64 x 4);
2892
2893
  binop_256!(avx2: adds, "Adds the elements of each lane of `a` and `b`, with saturation.", saturating_add, u8 x 32, i8 x 32, u16 x 16, i16 x 16);
2894
2895
  binop_256!(avx2: subs, "Subtracts the elements of each lane of `a` and `b`, with saturation.", saturating_sub, u8 x 32, i8 x 32, u16 x 16, i16 x 16);
2896
2897
  binop_256_nosign!(avx: sub, "Subtracts the elements of each lane of `a` and `b`.", f32 x 8, f64 x 4);
2898
2899
  binop_256_nosign!(avx2: sub, "Subtracts the elements of each lane of `a` and `b`, with wrapping overflow.", wrapping_sub, u8 x 32, i8 x 32, u16 x 16, i16 x 16, u32 x 8, i32 x 8, u64 x 4, i64 x 4);
2900
2901
  binop_256!(avx: addsub, "Alternatively subtracts and adds the elements of each lane of `a` and `b`.", subadd, f32 x 8, f64 x 4);
2902
2903
  unop_256!(avx2: abs, "Computes the unsigned absolute value of the elements of each lane of `a`.", unsigned_abs, i8 x 32, i16 x 16, i32 x 8);
2904
2905
  binop_256!(avx: xor, "Returns `a ^ b` for each bit in `a` and `b`.", f32 x 8, f64 x 4);
2906
2907
  binop_256_full!(avx2: xor, "Returns `a ^ b` for each bit in `a` and `b`.", m8 x 32, u8 x 32, i8 x 32, m16 x 16, u16 x 16, i16 x 16, m32 x 8, u32 x 8, i32 x 8, m64 x 4, u64 x 4, i64 x 4);
2908
2909
  /// Computes `abs(a)` for each lane of `a`.
2910
  #[inline(always)]
2911
0
  pub fn abs_f32x8(self, a: f32x8) -> f32x8 {
2912
0
    self.and_f32x8(a, cast!(self.splat_u32x8((1 << 31) - 1)))
2913
0
  }
2914
2915
  /// Computes `abs(a)` for each lane of `a`.
2916
  #[inline(always)]
2917
0
  pub fn abs_f64x4(self, a: f64x4) -> f64x4 {
2918
0
    self.and_f64x4(a, cast!(self.splat_u64x4((1 << 63) - 1)))
2919
0
  }
2920
2921
  /// Computes the approximate reciprocal of the elements of each lane of `a`.
2922
  #[inline(always)]
2923
0
  pub fn approx_reciprocal_f32x8(self, a: f32x8) -> f32x8 {
2924
0
    cast!(self.avx._mm256_rcp_ps(cast!(a)))
2925
0
  }
2926
2927
  /// Computes the approximate reciprocal of the square roots of the elements of each lane of `a`.
2928
  #[inline(always)]
2929
0
  pub fn approx_reciprocal_sqrt_f32x8(self, a: f32x8) -> f32x8 {
2930
0
    cast!(self.avx._mm256_rsqrt_ps(cast!(a)))
2931
0
  }
2932
2933
  /// Compares the elements in each lane of `a` and `b` for equality.
2934
  #[inline(always)]
2935
0
  pub fn cmp_eq_f32x8(self, a: f32x8, b: f32x8) -> m32x8 {
2936
0
    cast!(self.avx._mm256_cmp_ps::<_CMP_EQ_OQ>(cast!(a), cast!(b)))
2937
0
  }
2938
2939
  /// Compares the elements in each lane of `a` and `b` for equality.
2940
  #[inline(always)]
2941
0
  pub fn cmp_eq_f64x4(self, a: f64x4, b: f64x4) -> m64x4 {
2942
0
    cast!(self.avx._mm256_cmp_pd::<_CMP_EQ_OQ>(cast!(a), cast!(b)))
2943
0
  }
2944
2945
  /// Compares the elements in each lane of `a` and `b` for greater-than-or-equal-to.
2946
  #[inline(always)]
2947
0
  pub fn cmp_ge_f32x8(self, a: f32x8, b: f32x8) -> m32x8 {
2948
0
    cast!(self.avx._mm256_cmp_ps::<_CMP_GE_OQ>(cast!(a), cast!(b)))
2949
0
  }
2950
2951
  /// Compares the elements in each lane of `a` and `b` for greater-than-or-equal-to.
2952
  #[inline(always)]
2953
0
  pub fn cmp_ge_f64x4(self, a: f64x4, b: f64x4) -> m64x4 {
2954
0
    cast!(self.avx._mm256_cmp_pd::<_CMP_GE_OQ>(cast!(a), cast!(b)))
2955
0
  }
2956
2957
  /// Compares the elements in each lane of `a` and `b` for greater-than-or-equal-to.
2958
  #[inline(always)]
2959
0
  pub fn cmp_ge_i16x16(self, a: i16x16, b: i16x16) -> m16x16 {
2960
0
    self.not_m16x16(self.cmp_lt_i16x16(a, b))
2961
0
  }
2962
2963
  /// Compares the elements in each lane of `a` and `b` for greater-than-or-equal-to.
2964
  #[inline(always)]
2965
0
  pub fn cmp_ge_i32x8(self, a: i32x8, b: i32x8) -> m32x8 {
2966
0
    self.not_m32x8(self.cmp_lt_i32x8(a, b))
2967
0
  }
2968
2969
  /// Compares the elements in each lane of `a` and `b` for greater-than-or-equal-to.
2970
  #[inline(always)]
2971
0
  pub fn cmp_ge_i64x4(self, a: i64x4, b: i64x4) -> m64x4 {
2972
0
    self.not_m64x4(self.cmp_lt_i64x4(a, b))
2973
0
  }
2974
2975
  /// Compares the elements in each lane of `a` and `b` for greater-than-or-equal-to.
2976
  #[inline(always)]
2977
0
  pub fn cmp_ge_i8x32(self, a: i8x32, b: i8x32) -> m8x32 {
2978
0
    self.not_m8x32(self.cmp_lt_i8x32(a, b))
2979
0
  }
2980
2981
  /// Compares the elements in each lane of `a` and `b` for greater-than-or-equal-to.
2982
  #[inline(always)]
2983
0
  pub fn cmp_ge_u16x16(self, a: u16x16, b: u16x16) -> m16x16 {
2984
0
    self.not_m16x16(self.cmp_lt_u16x16(a, b))
2985
0
  }
2986
2987
  /// Compares the elements in each lane of `a` and `b` for greater-than-or-equal-to.
2988
  #[inline(always)]
2989
0
  pub fn cmp_ge_u32x8(self, a: u32x8, b: u32x8) -> m32x8 {
2990
0
    self.not_m32x8(self.cmp_lt_u32x8(a, b))
2991
0
  }
2992
2993
  /// Compares the elements in each lane of `a` and `b` for greater-than-or-equal-to.
2994
  #[inline(always)]
2995
0
  pub fn cmp_ge_u64x4(self, a: u64x4, b: u64x4) -> m64x4 {
2996
0
    self.not_m64x4(self.cmp_lt_u64x4(a, b))
2997
0
  }
2998
2999
  /// Compares the elements in each lane of `a` and `b` for greater-than-or-equal-to.
3000
  #[inline(always)]
3001
0
  pub fn cmp_ge_u8x32(self, a: u8x32, b: u8x32) -> m8x32 {
3002
0
    self.not_m8x32(self.cmp_lt_u8x32(a, b))
3003
0
  }
3004
3005
  /// Compares the elements in each lane of `a` and `b` for greater-than.
3006
  #[inline(always)]
3007
0
  pub fn cmp_gt_f32x8(self, a: f32x8, b: f32x8) -> m32x8 {
3008
0
    cast!(self.avx._mm256_cmp_ps::<_CMP_GT_OQ>(cast!(a), cast!(b)))
3009
0
  }
3010
3011
  /// Compares the elements in each lane of `a` and `b` for greater-than.
3012
  #[inline(always)]
3013
0
  pub fn cmp_gt_f64x4(self, a: f64x4, b: f64x4) -> m64x4 {
3014
0
    cast!(self.avx._mm256_cmp_pd::<_CMP_GT_OQ>(cast!(a), cast!(b)))
3015
0
  }
3016
3017
  /// Compares the elements in each lane of `a` and `b` for greater-than.
3018
  #[inline(always)]
3019
0
  pub fn cmp_gt_u16x16(self, a: u16x16, b: u16x16) -> m16x16 {
3020
0
    let k = self.splat_u16x16(0x8000);
3021
0
    self.cmp_gt_i16x16(cast!(self.xor_u16x16(a, k)), cast!(self.xor_u16x16(b, k)))
3022
0
  }
3023
3024
  /// Compares the elements in each lane of `a` and `b` for greater-than.
3025
  #[inline(always)]
3026
0
  pub fn cmp_gt_u32x8(self, a: u32x8, b: u32x8) -> m32x8 {
3027
0
    let k = self.splat_u32x8(0x80000000);
3028
0
    self.cmp_gt_i32x8(cast!(self.xor_u32x8(a, k)), cast!(self.xor_u32x8(b, k)))
3029
0
  }
3030
3031
  /// Compares the elements in each lane of `a` and `b` for greater-than.
3032
  #[inline(always)]
3033
0
  pub fn cmp_gt_u64x4(self, a: u64x4, b: u64x4) -> m64x4 {
3034
0
    let k = self.splat_u64x4(0x8000000000000000);
3035
0
    self.cmp_gt_i64x4(cast!(self.xor_u64x4(a, k)), cast!(self.xor_u64x4(b, k)))
3036
0
  }
3037
3038
  /// Compares the elements in each lane of `a` and `b` for greater-than.
3039
  #[inline(always)]
3040
0
  pub fn cmp_gt_u8x32(self, a: u8x32, b: u8x32) -> m8x32 {
3041
0
    let k = self.splat_u8x32(0x80);
3042
0
    self.cmp_gt_i8x32(cast!(self.xor_u8x32(a, k)), cast!(self.xor_u8x32(b, k)))
3043
0
  }
3044
3045
  /// Compares the elements in each lane of `a` and `b` for less-than-or-equal-to.
3046
  #[inline(always)]
3047
0
  pub fn cmp_le_f32x8(self, a: f32x8, b: f32x8) -> m32x8 {
3048
0
    cast!(self.avx._mm256_cmp_ps::<_CMP_LE_OQ>(cast!(a), cast!(b)))
3049
0
  }
3050
3051
  /// Compares the elements in each lane of `a` and `b` for less-than-or-equal-to.
3052
  #[inline(always)]
3053
0
  pub fn cmp_le_f64x4(self, a: f64x4, b: f64x4) -> m64x4 {
3054
0
    cast!(self.avx._mm256_cmp_pd::<_CMP_LE_OQ>(cast!(a), cast!(b)))
3055
0
  }
3056
3057
  /// Compares the elements in each lane of `a` and `b` for less-than-or-equal-to.
3058
  #[inline(always)]
3059
0
  pub fn cmp_le_i16x16(self, a: i16x16, b: i16x16) -> m16x16 {
3060
0
    self.not_m16x16(self.cmp_gt_i16x16(a, b))
3061
0
  }
3062
3063
  /// Compares the elements in each lane of `a` and `b` for less-than-or-equal-to.
3064
  #[inline(always)]
3065
0
  pub fn cmp_le_i32x8(self, a: i32x8, b: i32x8) -> m32x8 {
3066
0
    self.not_m32x8(self.cmp_gt_i32x8(a, b))
3067
0
  }
3068
3069
  /// Compares the elements in each lane of `a` and `b` for less-than-or-equal-to.
3070
  #[inline(always)]
3071
0
  pub fn cmp_le_i64x4(self, a: i64x4, b: i64x4) -> m64x4 {
3072
0
    self.not_m64x4(self.cmp_gt_i64x4(a, b))
3073
0
  }
3074
3075
  /// Compares the elements in each lane of `a` and `b` for less-than-or-equal-to.
3076
  #[inline(always)]
3077
0
  pub fn cmp_le_i8x32(self, a: i8x32, b: i8x32) -> m8x32 {
3078
0
    self.not_m8x32(self.cmp_gt_i8x32(a, b))
3079
0
  }
3080
3081
  /// Compares the elements in each lane of `a` and `b` for less-than-or-equal-to.
3082
  #[inline(always)]
3083
0
  pub fn cmp_le_u16x16(self, a: u16x16, b: u16x16) -> m16x16 {
3084
0
    self.not_m16x16(self.cmp_gt_u16x16(a, b))
3085
0
  }
3086
3087
  /// Compares the elements in each lane of `a` and `b` for less-than-or-equal-to.
3088
  #[inline(always)]
3089
0
  pub fn cmp_le_u32x8(self, a: u32x8, b: u32x8) -> m32x8 {
3090
0
    self.not_m32x8(self.cmp_gt_u32x8(a, b))
3091
0
  }
3092
3093
  /// Compares the elements in each lane of `a` and `b` for less-than-or-equal-to.
3094
  #[inline(always)]
3095
0
  pub fn cmp_le_u64x4(self, a: u64x4, b: u64x4) -> m64x4 {
3096
0
    self.not_m64x4(self.cmp_gt_u64x4(a, b))
3097
0
  }
3098
3099
  /// Compares the elements in each lane of `a` and `b` for less-than-or-equal-to.
3100
  #[inline(always)]
3101
0
  pub fn cmp_le_u8x32(self, a: u8x32, b: u8x32) -> m8x32 {
3102
0
    self.not_m8x32(self.cmp_gt_u8x32(a, b))
3103
0
  }
3104
3105
  /// Compares the elements in each lane of `a` and `b` for less-than.
3106
  #[inline(always)]
3107
0
  pub fn cmp_lt_f32x8(self, a: f32x8, b: f32x8) -> m32x8 {
3108
0
    cast!(self.avx._mm256_cmp_ps::<_CMP_LT_OQ>(cast!(a), cast!(b)))
3109
0
  }
3110
3111
  /// Compares the elements in each lane of `a` and `b` for less-than.
3112
  #[inline(always)]
3113
0
  pub fn cmp_lt_f64x4(self, a: f64x4, b: f64x4) -> m64x4 {
3114
0
    cast!(self.avx._mm256_cmp_pd::<_CMP_LT_OQ>(cast!(a), cast!(b)))
3115
0
  }
3116
3117
  /// Compares the elements in each lane of `a` and `b` for less-than.
3118
  #[inline(always)]
3119
0
  pub fn cmp_lt_i16x16(self, a: i16x16, b: i16x16) -> m16x16 {
3120
0
    cast!(self.avx2._mm256_cmpgt_epi16(cast!(b), cast!(a)))
3121
0
  }
3122
3123
  /// Compares the elements in each lane of `a` and `b` for less-than.
3124
  #[inline(always)]
3125
0
  pub fn cmp_lt_i32x8(self, a: i32x8, b: i32x8) -> m32x8 {
3126
0
    cast!(self.avx2._mm256_cmpgt_epi32(cast!(b), cast!(a)))
3127
0
  }
3128
3129
  /// Compares the elements in each lane of `a` and `b` for less-than.
3130
  #[inline(always)]
3131
0
  pub fn cmp_lt_i64x4(self, a: i64x4, b: i64x4) -> m64x4 {
3132
0
    cast!(self.avx2._mm256_cmpgt_epi64(cast!(b), cast!(a)))
3133
0
  }
3134
3135
  /// Compares the elements in each lane of `a` and `b` for less-than.
3136
  #[inline(always)]
3137
0
  pub fn cmp_lt_i8x32(self, a: i8x32, b: i8x32) -> m8x32 {
3138
0
    cast!(self.avx2._mm256_cmpgt_epi8(cast!(b), cast!(a)))
3139
0
  }
3140
3141
  /// Compares the elements in each lane of `a` and `b` for less-than.
3142
  #[inline(always)]
3143
0
  pub fn cmp_lt_u16x16(self, a: u16x16, b: u16x16) -> m16x16 {
3144
0
    let k = self.splat_u16x16(0x8000);
3145
0
    self.cmp_lt_i16x16(cast!(self.xor_u16x16(a, k)), cast!(self.xor_u16x16(b, k)))
3146
0
  }
3147
3148
  /// Compares the elements in each lane of `a` and `b` for less-than.
3149
  #[inline(always)]
3150
0
  pub fn cmp_lt_u32x8(self, a: u32x8, b: u32x8) -> m32x8 {
3151
0
    let k = self.splat_u32x8(0x80000000);
3152
0
    self.cmp_lt_i32x8(cast!(self.xor_u32x8(a, k)), cast!(self.xor_u32x8(b, k)))
3153
0
  }
3154
3155
  /// Compares the elements in each lane of `a` and `b` for less-than.
3156
  #[inline(always)]
3157
0
  pub fn cmp_lt_u64x4(self, a: u64x4, b: u64x4) -> m64x4 {
3158
0
    let k = self.splat_u64x4(0x8000000000000000);
3159
0
    self.cmp_lt_i64x4(cast!(self.xor_u64x4(a, k)), cast!(self.xor_u64x4(b, k)))
3160
0
  }
3161
3162
  /// Compares the elements in each lane of `a` and `b` for less-than.
3163
  #[inline(always)]
3164
0
  pub fn cmp_lt_u8x32(self, a: u8x32, b: u8x32) -> m8x32 {
3165
0
    let k = self.splat_u8x32(0x80);
3166
0
    self.cmp_lt_i8x32(cast!(self.xor_u8x32(a, k)), cast!(self.xor_u8x32(b, k)))
3167
0
  }
3168
3169
  /// Compares the elements in each lane of `a` and `b` for inequality.
3170
  #[inline(always)]
3171
0
  pub fn cmp_not_eq_f32x8(self, a: f32x8, b: f32x8) -> m32x8 {
3172
0
    cast!(self.avx._mm256_cmp_ps::<_CMP_NEQ_UQ>(cast!(a), cast!(b)))
3173
0
  }
3174
3175
  /// Compares the elements in each lane of `a` and `b` for inequality.
3176
  #[inline(always)]
3177
0
  pub fn cmp_not_eq_f64x4(self, a: f64x4, b: f64x4) -> m64x4 {
3178
0
    cast!(self.avx._mm256_cmp_pd::<_CMP_NEQ_UQ>(cast!(a), cast!(b)))
3179
0
  }
3180
3181
  /// Compares the elements in each lane of `a` and `b` for not-greater-than-or-equal.
3182
  #[inline(always)]
3183
0
  pub fn cmp_not_ge_f32x8(self, a: f32x8, b: f32x8) -> m32x8 {
3184
0
    cast!(self.avx._mm256_cmp_ps::<_CMP_NGE_UQ>(cast!(a), cast!(b)))
3185
0
  }
3186
3187
  /// Compares the elements in each lane of `a` and `b` for not-greater-than-or-equal.
3188
  #[inline(always)]
3189
0
  pub fn cmp_not_ge_f64x4(self, a: f64x4, b: f64x4) -> m64x4 {
3190
0
    cast!(self.avx._mm256_cmp_pd::<_CMP_NGE_UQ>(cast!(a), cast!(b)))
3191
0
  }
3192
3193
  /// Compares the elements in each lane of `a` and `b` for not-greater-than.
3194
  #[inline(always)]
3195
0
  pub fn cmp_not_gt_f32x8(self, a: f32x8, b: f32x8) -> m32x8 {
3196
0
    cast!(self.avx._mm256_cmp_ps::<_CMP_NGT_UQ>(cast!(a), cast!(b)))
3197
0
  }
3198
3199
  /// Compares the elements in each lane of `a` and `b` for not-greater-than.
3200
  #[inline(always)]
3201
0
  pub fn cmp_not_gt_f64x4(self, a: f64x4, b: f64x4) -> m64x4 {
3202
0
    cast!(self.avx._mm256_cmp_pd::<_CMP_NGT_UQ>(cast!(a), cast!(b)))
3203
0
  }
3204
3205
  /// Compares the elements in each lane of `a` and `b` for not-less-than-or-equal.
3206
  #[inline(always)]
3207
0
  pub fn cmp_not_le_f32x8(self, a: f32x8, b: f32x8) -> m32x8 {
3208
0
    cast!(self.avx._mm256_cmp_ps::<_CMP_NLE_UQ>(cast!(a), cast!(b)))
3209
0
  }
3210
3211
  /// Compares the elements in each lane of `a` and `b` for not-less-than-or-equal.
3212
  #[inline(always)]
3213
0
  pub fn cmp_not_le_f64x4(self, a: f64x4, b: f64x4) -> m64x4 {
3214
0
    cast!(self.avx._mm256_cmp_pd::<_CMP_NLE_UQ>(cast!(a), cast!(b)))
3215
0
  }
3216
3217
  /// Compares the elements in each lane of `a` and `b` for not-less-than.
3218
  #[inline(always)]
3219
0
  pub fn cmp_not_lt_f32x8(self, a: f32x8, b: f32x8) -> m32x8 {
3220
0
    cast!(self.avx._mm256_cmp_ps::<_CMP_NLT_UQ>(cast!(a), cast!(b)))
3221
0
  }
3222
3223
  /// Compares the elements in each lane of `a` and `b` for not-less-than.
3224
  #[inline(always)]
3225
0
  pub fn cmp_not_lt_f64x4(self, a: f64x4, b: f64x4) -> m64x4 {
3226
0
    cast!(self.avx._mm256_cmp_pd::<_CMP_NLT_UQ>(cast!(a), cast!(b)))
3227
0
  }
3228
3229
  /// Converts a `f32x4` to `f64x4`, elementwise.
3230
  #[inline(always)]
3231
0
  pub fn convert_f32x4_to_f64x4(self, a: f32x4) -> f64x4 {
3232
0
    cast!(self.avx._mm256_cvtps_pd(cast!(a)))
3233
0
  }
3234
3235
  /// Converts a `f32x8` to `i32x8`, elementwise.
3236
  #[inline(always)]
3237
0
  pub fn convert_f32x8_to_i32x8(self, a: f32x8) -> i32x8 {
3238
0
    cast!(self.avx._mm256_cvttps_epi32(cast!(a)))
3239
0
  }
3240
3241
  /// Converts a `f64x4` to `f32x4`, elementwise.
3242
  #[inline(always)]
3243
0
  pub fn convert_f64x4_to_f32x4(self, a: f64x4) -> f32x4 {
3244
0
    cast!(self.avx._mm256_cvtpd_ps(cast!(a)))
3245
0
  }
3246
3247
  /// Converts a `f64x4` to `i32x4`, elementwise.
3248
  #[inline(always)]
3249
0
  pub fn convert_f64x4_to_i32x4(self, a: f64x4) -> i32x4 {
3250
0
    cast!(self.avx._mm256_cvttpd_epi32(cast!(a)))
3251
0
  }
3252
3253
  /// Converts a `i16x16` to `u16x16`, elementwise.
3254
  #[inline(always)]
3255
0
  pub fn convert_i16x16_to_u16x16(self, a: i16x16) -> u16x16 {
3256
0
    cast!(a)
3257
0
  }
3258
3259
  /// Converts a `i16x8` to `i32x8`, elementwise.
3260
  #[inline(always)]
3261
0
  pub fn convert_i16x8_to_i32x8(self, a: i16x8) -> i32x8 {
3262
0
    cast!(self.avx2._mm256_cvtepi16_epi32(cast!(a)))
3263
0
  }
3264
3265
  /// Converts a `i16x8` to `i64x4`, elementwise, while truncating the extra elements.
3266
  #[inline(always)]
3267
0
  pub fn convert_i16x8_to_i64x4(self, a: i16x8) -> i64x4 {
3268
0
    cast!(self.avx2._mm256_cvtepi16_epi64(cast!(a)))
3269
0
  }
3270
3271
  /// Converts a `i16x8` to `u32x8`, elementwise.
3272
  #[inline(always)]
3273
0
  pub fn convert_i16x8_to_u32x8(self, a: i16x8) -> u32x8 {
3274
0
    cast!(self.avx2._mm256_cvtepi16_epi32(cast!(a)))
3275
0
  }
3276
3277
  /// Converts a `i16x8` to `u64x4`, elementwise, while truncating the extra elements.
3278
  #[inline(always)]
3279
0
  pub fn convert_i16x8_to_u64x4(self, a: i16x8) -> u64x4 {
3280
0
    cast!(self.avx2._mm256_cvtepi16_epi64(cast!(a)))
3281
0
  }
3282
3283
  /// Converts a `i32x4` to `f64x4`, elementwise.
3284
  #[inline(always)]
3285
0
  pub fn convert_i32x4_to_f64x4(self, a: i32x4) -> f64x4 {
3286
0
    cast!(self.avx._mm256_cvtepi32_pd(cast!(a)))
3287
0
  }
3288
3289
  /// Converts a `i32x4` to `i64x4`, elementwise.
3290
  #[inline(always)]
3291
0
  pub fn convert_i32x4_to_i64x4(self, a: i32x4) -> i64x4 {
3292
0
    cast!(self.avx2._mm256_cvtepi32_epi64(cast!(a)))
3293
0
  }
3294
3295
  /// Converts a `i32x4` to `u64x4`, elementwise.
3296
  #[inline(always)]
3297
0
  pub fn convert_i32x4_to_u64x4(self, a: i32x4) -> u64x4 {
3298
0
    cast!(self.avx2._mm256_cvtepi32_epi64(cast!(a)))
3299
0
  }
3300
3301
  /// Converts a `i32x8` to `f32x8`, elementwise.
3302
  #[inline(always)]
3303
0
  pub fn convert_i32x8_to_f32x8(self, a: i32x8) -> f32x8 {
3304
0
    cast!(self.avx._mm256_cvtepi32_ps(cast!(a)))
3305
0
  }
3306
3307
  /// Converts a `i32x8` to `u32x8`, elementwise.
3308
  #[inline(always)]
3309
0
  pub fn convert_i32x8_to_u32x8(self, a: i32x8) -> u32x8 {
3310
0
    cast!(a)
3311
0
  }
3312
3313
  /// Converts a `i8x16` to `i16x16`, elementwise.
3314
  #[inline(always)]
3315
0
  pub fn convert_i8x16_to_i16x16(self, a: i8x16) -> i16x16 {
3316
0
    cast!(self.avx2._mm256_cvtepi8_epi16(cast!(a)))
3317
0
  }
3318
3319
  /// Converts a `i8x16` to `i32x8`, elementwise, while truncating the extra elements.
3320
  #[inline(always)]
3321
0
  pub fn convert_i8x16_to_i32x8(self, a: i8x16) -> i32x8 {
3322
0
    cast!(self.avx2._mm256_cvtepi8_epi32(cast!(a)))
3323
0
  }
3324
3325
  /// Converts a `i8x16` to `i64x4`, elementwise, while truncating the extra elements.
3326
  #[inline(always)]
3327
0
  pub fn convert_i8x16_to_i64x4(self, a: i8x16) -> i64x4 {
3328
0
    cast!(self.avx2._mm256_cvtepi8_epi64(cast!(a)))
3329
0
  }
3330
3331
  /// Converts a `i8x16` to `u16x16`, elementwise.
3332
  #[inline(always)]
3333
0
  pub fn convert_i8x16_to_u16x16(self, a: i8x16) -> u16x16 {
3334
0
    cast!(self.avx2._mm256_cvtepi8_epi16(cast!(a)))
3335
0
  }
3336
3337
  /// Converts a `i8x16` to `u32x8`, elementwise, while truncating the extra elements.
3338
  #[inline(always)]
3339
0
  pub fn convert_i8x16_to_u32x8(self, a: i8x16) -> u32x8 {
3340
0
    cast!(self.avx2._mm256_cvtepi8_epi32(cast!(a)))
3341
0
  }
3342
3343
  /// Converts a `i8x16` to `u64x4`, elementwise, while truncating the extra elements.
3344
  #[inline(always)]
3345
0
  pub fn convert_i8x16_to_u64x4(self, a: i8x16) -> u64x4 {
3346
0
    cast!(self.avx2._mm256_cvtepi8_epi64(cast!(a)))
3347
0
  }
3348
3349
  /// Converts a `i8x32` to `u8x32`, elementwise.
3350
  #[inline(always)]
3351
0
  pub fn convert_i8x32_to_u8x32(self, a: i8x32) -> u8x32 {
3352
0
    cast!(a)
3353
0
  }
3354
3355
  /// Converts a `u16x16` to `i16x16`, elementwise.
3356
  #[inline(always)]
3357
0
  pub fn convert_u16x16_to_i16x16(self, a: u16x16) -> i16x16 {
3358
0
    cast!(a)
3359
0
  }
3360
3361
  /// Converts a `u16x8` to `i32x8`, elementwise.
3362
  #[inline(always)]
3363
0
  pub fn convert_u16x8_to_i32x8(self, a: u16x8) -> i32x8 {
3364
0
    cast!(self.avx2._mm256_cvtepu16_epi32(cast!(a)))
3365
0
  }
3366
3367
  /// Converts a `u16x8` to `i64x4`, elementwise, while truncating the extra elements.
3368
  #[inline(always)]
3369
0
  pub fn convert_u16x8_to_i64x4(self, a: u16x8) -> i64x4 {
3370
0
    cast!(self.avx2._mm256_cvtepu16_epi64(cast!(a)))
3371
0
  }
3372
3373
  /// Converts a `u16x8` to `u32x8`, elementwise.
3374
  #[inline(always)]
3375
0
  pub fn convert_u16x8_to_u32x8(self, a: u16x8) -> u32x8 {
3376
0
    cast!(self.avx2._mm256_cvtepu16_epi32(cast!(a)))
3377
0
  }
3378
3379
  /// Converts a `u16x8` to `u64x4`, elementwise, while truncating the extra elements.
3380
  #[inline(always)]
3381
0
  pub fn convert_u16x8_to_u64x4(self, a: u16x8) -> u64x4 {
3382
0
    cast!(self.avx2._mm256_cvtepu16_epi64(cast!(a)))
3383
0
  }
3384
3385
  /// Converts a `u32x4` to `i64x4`, elementwise.
3386
  #[inline(always)]
3387
0
  pub fn convert_u32x4_to_i64x4(self, a: u32x4) -> i64x4 {
3388
0
    cast!(self.avx2._mm256_cvtepu32_epi64(cast!(a)))
3389
0
  }
3390
3391
  /// Converts a `u32x4` to `u64x4`, elementwise.
3392
  #[inline(always)]
3393
0
  pub fn convert_u32x4_to_u64x4(self, a: u32x4) -> u64x4 {
3394
0
    cast!(self.avx2._mm256_cvtepu32_epi64(cast!(a)))
3395
0
  }
3396
3397
  /// Converts a `u32x8` to `i32x8`, elementwise.
3398
  #[inline(always)]
3399
0
  pub fn convert_u32x8_to_i32x8(self, a: u32x8) -> i32x8 {
3400
0
    cast!(a)
3401
0
  }
3402
3403
  /// Converts a `u8x16` to `i16x16`, elementwise.
3404
  #[inline(always)]
3405
0
  pub fn convert_u8x16_to_i16x16(self, a: u8x16) -> i16x16 {
3406
0
    cast!(self.avx2._mm256_cvtepu8_epi16(cast!(a)))
3407
0
  }
3408
3409
  /// Converts a `u8x16` to `i32x8`, elementwise, while truncating the extra elements.
3410
  #[inline(always)]
3411
0
  pub fn convert_u8x16_to_i32x8(self, a: u8x16) -> i32x8 {
3412
0
    cast!(self.avx2._mm256_cvtepu8_epi32(cast!(a)))
3413
0
  }
3414
3415
  /// Converts a `u8x16` to `i64x4`, elementwise, while truncating the extra elements.
3416
  #[inline(always)]
3417
0
  pub fn convert_u8x16_to_i64x4(self, a: u8x16) -> i64x4 {
3418
0
    cast!(self.avx2._mm256_cvtepu8_epi64(cast!(a)))
3419
0
  }
3420
3421
  /// Converts a `u8x16` to `u16x16`, elementwise.
3422
  #[inline(always)]
3423
0
  pub fn convert_u8x16_to_u16x16(self, a: u8x16) -> u16x16 {
3424
0
    cast!(self.avx2._mm256_cvtepu8_epi16(cast!(a)))
3425
0
  }
3426
3427
  /// Converts a `u8x16` to `u32x8`, elementwise, while truncating the extra elements.
3428
  #[inline(always)]
3429
0
  pub fn convert_u8x16_to_u32x8(self, a: u8x16) -> u32x8 {
3430
0
    cast!(self.avx2._mm256_cvtepu8_epi32(cast!(a)))
3431
0
  }
3432
3433
  /// Converts a `u8x16` to `u64x4`, elementwise, while truncating the extra elements.
3434
  #[inline(always)]
3435
0
  pub fn convert_u8x16_to_u64x4(self, a: u8x16) -> u64x4 {
3436
0
    cast!(self.avx2._mm256_cvtepu8_epi64(cast!(a)))
3437
0
  }
3438
3439
  /// Converts a `u8x32` to `i8x32`, elementwise.
3440
  #[inline(always)]
3441
0
  pub fn convert_u8x32_to_i8x32(self, a: u8x32) -> i8x32 {
3442
0
    cast!(a)
3443
0
  }
3444
3445
  /// See [_mm_hadds_epi16].
3446
  ///
3447
  /// [_mm_hadds_epi16]: core::arch::x86_64::_mm_hadds_epi16
3448
  #[inline(always)]
3449
0
  pub fn horizontal_saturating_add_pack_i16x16(self, a: i16x16, b: i16x16) -> i16x16 {
3450
0
    cast!(self.avx2._mm256_hadds_epi16(cast!(a), cast!(b)))
3451
0
  }
3452
3453
  /// See [_mm_hsubs_epi16].
3454
  ///
3455
  /// [_mm_hsubs_epi16]: core::arch::x86_64::_mm_hsubs_epi16
3456
  #[inline(always)]
3457
0
  pub fn horizontal_saturating_sub_pack_i16x16(self, a: i16x16, b: i16x16) -> i16x16 {
3458
0
    cast!(self.avx2._mm256_hsubs_epi16(cast!(a), cast!(b)))
3459
0
  }
3460
3461
  /// Checks if the elements in each lane of `a` are NaN.
3462
  #[inline(always)]
3463
0
  pub fn is_nan_f32x8(self, a: f32x8) -> m32x8 {
3464
0
    cast!(self.avx._mm256_cmp_ps::<_CMP_UNORD_Q>(cast!(a), cast!(a)))
3465
0
  }
3466
3467
  /// Checks if the elements in each lane of `a` are NaN.
3468
  #[inline(always)]
3469
0
  pub fn is_nan_f64x4(self, a: f64x4) -> m64x4 {
3470
0
    cast!(self.avx._mm256_cmp_pd::<_CMP_UNORD_Q>(cast!(a), cast!(a)))
3471
0
  }
3472
3473
  /// Checks if the elements in each lane of `a` are not NaN.
3474
  #[inline(always)]
3475
0
  pub fn is_not_nan_f32x8(self, a: f32x8) -> m32x8 {
3476
0
    cast!(self.avx._mm256_cmp_ps::<_CMP_ORD_Q>(cast!(a), cast!(a)))
3477
0
  }
3478
3479
  /// Checks if the elements in each lane of `a` are not NaN.
3480
  #[inline(always)]
3481
0
  pub fn is_not_nan_f64x4(self, a: f64x4) -> m64x4 {
3482
0
    cast!(self.avx._mm256_cmp_pd::<_CMP_ORD_Q>(cast!(a), cast!(a)))
3483
0
  }
3484
3485
  /// Multiplies the elements in each lane of `a` and `b`, and adds the results to each lane of
3486
  /// `c`.
3487
  #[inline(always)]
3488
0
  pub fn mul_add_f32x4(self, a: f32x4, b: f32x4, c: f32x4) -> f32x4 {
3489
0
    cast!(self.fma._mm_fmadd_ps(cast!(a), cast!(b), cast!(c)))
3490
0
  }
3491
3492
  /// Multiplies the elements in each lane of `a` and `b`, and adds the results to each lane of
3493
  /// `c`.
3494
  #[inline(always)]
3495
0
  pub fn mul_add_f32x8(self, a: f32x8, b: f32x8, c: f32x8) -> f32x8 {
3496
0
    cast!(self.fma._mm256_fmadd_ps(cast!(a), cast!(b), cast!(c)))
3497
0
  }
3498
3499
  /// Multiplies the elements in each lane of `a` and `b`, and adds the results to each lane of
3500
  /// `c`.
3501
  #[inline(always)]
3502
0
  pub fn mul_add_f64x2(self, a: f64x2, b: f64x2, c: f64x2) -> f64x2 {
3503
0
    cast!(self.fma._mm_fmadd_pd(cast!(a), cast!(b), cast!(c)))
3504
0
  }
3505
3506
  /// Multiplies the elements in each lane of `a` and `b`, and adds the results to each lane of
3507
  /// `c`.
3508
  #[inline(always)]
3509
0
  pub fn mul_add_f64x4(self, a: f64x4, b: f64x4, c: f64x4) -> f64x4 {
3510
0
    cast!(self.fma._mm256_fmadd_pd(cast!(a), cast!(b), cast!(c)))
3511
0
  }
3512
3513
  /// Multiplies the elements in each lane of `a` and `b`, and alternatively adds/subtracts 'c'
3514
  /// to/from the results.
3515
  #[inline(always)]
3516
0
  pub fn mul_addsub_f32x4(self, a: f32x4, b: f32x4, c: f32x4) -> f32x4 {
3517
0
    cast!(self.fma._mm_fmsubadd_ps(cast!(a), cast!(b), cast!(c)))
3518
0
  }
3519
3520
  /// Multiplies the elements in each lane of `a` and `b`, and alternatively adds/subtracts 'c'
3521
  /// to/from the results.
3522
  #[inline(always)]
3523
0
  pub fn mul_addsub_f32x8(self, a: f32x8, b: f32x8, c: f32x8) -> f32x8 {
3524
0
    cast!(self.fma._mm256_fmsubadd_ps(cast!(a), cast!(b), cast!(c)))
3525
0
  }
3526
3527
  /// Multiplies the elements in each lane of `a` and `b`, and alternatively adds/subtracts 'c'
3528
  /// to/from the results.
3529
  #[inline(always)]
3530
0
  pub fn mul_addsub_f64x2(self, a: f64x2, b: f64x2, c: f64x2) -> f64x2 {
3531
0
    cast!(self.fma._mm_fmsubadd_pd(cast!(a), cast!(b), cast!(c)))
3532
0
  }
3533
3534
  /// Multiplies the elements in each lane of `a` and `b`, and alternatively adds/subtracts 'c'
3535
  /// to/from the results.
3536
  #[inline(always)]
3537
0
  pub fn mul_addsub_f64x4(self, a: f64x4, b: f64x4, c: f64x4) -> f64x4 {
3538
0
    cast!(self.fma._mm256_fmsubadd_pd(cast!(a), cast!(b), cast!(c)))
3539
0
  }
3540
3541
  /// Multiplies the elements in each lane of `a` and `b`, and subtracts each lane of `c` from
3542
  /// the results.
3543
  #[inline(always)]
3544
0
  pub fn mul_sub_f32x4(self, a: f32x4, b: f32x4, c: f32x4) -> f32x4 {
3545
0
    cast!(self.fma._mm_fmsub_ps(cast!(a), cast!(b), cast!(c)))
3546
0
  }
3547
3548
  /// Multiplies the elements in each lane of `a` and `b`, and subtracts each lane of `c` from
3549
  /// the results.
3550
  #[inline(always)]
3551
0
  pub fn mul_sub_f32x8(self, a: f32x8, b: f32x8, c: f32x8) -> f32x8 {
3552
0
    cast!(self.fma._mm256_fmsub_ps(cast!(a), cast!(b), cast!(c)))
3553
0
  }
3554
3555
  /// Multiplies the elements in each lane of `a` and `b`, and subtracts each lane of `c` from
3556
  /// the results.
3557
  #[inline(always)]
3558
0
  pub fn mul_sub_f64x2(self, a: f64x2, b: f64x2, c: f64x2) -> f64x2 {
3559
0
    cast!(self.fma._mm_fmsub_pd(cast!(a), cast!(b), cast!(c)))
3560
0
  }
3561
3562
  /// Multiplies the elements in each lane of `a` and `b`, and subtracts each lane of `c` from
3563
  /// the results.
3564
  #[inline(always)]
3565
0
  pub fn mul_sub_f64x4(self, a: f64x4, b: f64x4, c: f64x4) -> f64x4 {
3566
0
    cast!(self.fma._mm256_fmsub_pd(cast!(a), cast!(b), cast!(c)))
3567
0
  }
3568
3569
  /// Multiplies the elements in each lane of `a` and `b`, and alternatively subtracts/adds 'c'
3570
  /// to/from the results.
3571
  #[inline(always)]
3572
0
  pub fn mul_subadd_f32x4(self, a: f32x4, b: f32x4, c: f32x4) -> f32x4 {
3573
0
    cast!(self.fma._mm_fmaddsub_ps(cast!(a), cast!(b), cast!(c)))
3574
0
  }
3575
3576
  /// Multiplies the elements in each lane of `a` and `b`, and alternatively subtracts/adds 'c'
3577
  /// to/from the results.
3578
  #[inline(always)]
3579
0
  pub fn mul_subadd_f32x8(self, a: f32x8, b: f32x8, c: f32x8) -> f32x8 {
3580
0
    cast!(self.fma._mm256_fmaddsub_ps(cast!(a), cast!(b), cast!(c)))
3581
0
  }
3582
3583
  /// Multiplies the elements in each lane of `a` and `b`, and alternatively subtracts/adds 'c'
3584
  /// to/from the results.
3585
  #[inline(always)]
3586
0
  pub fn mul_subadd_f64x2(self, a: f64x2, b: f64x2, c: f64x2) -> f64x2 {
3587
0
    cast!(self.fma._mm_fmaddsub_pd(cast!(a), cast!(b), cast!(c)))
3588
0
  }
3589
3590
  /// Multiplies the elements in each lane of `a` and `b`, and alternatively subtracts/adds 'c'
3591
  /// to/from the results.
3592
  #[inline(always)]
3593
0
  pub fn mul_subadd_f64x4(self, a: f64x4, b: f64x4, c: f64x4) -> f64x4 {
3594
0
    cast!(self.fma._mm256_fmaddsub_pd(cast!(a), cast!(b), cast!(c)))
3595
0
  }
3596
3597
  /// See [_mm256_maddubs_epi16].
3598
  ///
3599
  /// [_mm256_maddubs_epi16]: core::arch::x86_64::_mm256_maddubs_epi16
3600
  #[inline(always)]
3601
0
  pub fn multiply_saturating_add_adjacent_i8x32(self, a: i8x32, b: i8x32) -> i16x16 {
3602
0
    cast!(self.avx2._mm256_maddubs_epi16(cast!(a), cast!(b)))
3603
0
  }
3604
3605
  /// See [_mm256_madd_epi16].
3606
  ///
3607
  /// [_mm256_madd_epi16]: core::arch::x86_64::_mm256_madd_epi16
3608
  #[inline(always)]
3609
0
  pub fn multiply_wrapping_add_adjacent_i16x16(self, a: i16x16, b: i16x16) -> i32x8 {
3610
0
    cast!(self.avx2._mm256_madd_epi16(cast!(a), cast!(b)))
3611
0
  }
3612
3613
  /// See [_mm256_mpsadbw_epu8].
3614
  ///
3615
  /// [_mm256_mpsadbw_epu8]: core::arch::x86_64::_mm256_mpsadbw_epu8
3616
  #[inline(always)]
3617
0
  pub fn multisum_of_absolute_differences_u8x32<const OFFSETS: i32>(
3618
0
    self,
3619
0
    a: u8x32,
3620
0
    b: u8x32,
3621
0
  ) -> u16x16 {
3622
0
    cast!(self.avx2._mm256_mpsadbw_epu8::<OFFSETS>(cast!(a), cast!(b)))
3623
0
  }
3624
3625
  /// Multiplies the elements in each lane of `a` and `b`, negates the results, and adds them to
3626
  /// each lane of `c`.
3627
  #[inline(always)]
3628
0
  pub fn negate_mul_add_f32x4(self, a: f32x4, b: f32x4, c: f32x4) -> f32x4 {
3629
0
    cast!(self.fma._mm_fnmadd_ps(cast!(a), cast!(b), cast!(c)))
3630
0
  }
3631
3632
  /// Multiplies the elements in each lane of `a` and `b`, negates the results, and adds them to
3633
  /// each lane of `c`.
3634
  #[inline(always)]
3635
0
  pub fn negate_mul_add_f32x8(self, a: f32x8, b: f32x8, c: f32x8) -> f32x8 {
3636
0
    cast!(self.fma._mm256_fnmadd_ps(cast!(a), cast!(b), cast!(c)))
3637
0
  }
3638
3639
  /// Multiplies the elements in each lane of `a` and `b`, negates the results, and adds them to
3640
  /// each lane of `c`.
3641
  #[inline(always)]
3642
0
  pub fn negate_mul_add_f64x2(self, a: f64x2, b: f64x2, c: f64x2) -> f64x2 {
3643
0
    cast!(self.fma._mm_fnmadd_pd(cast!(a), cast!(b), cast!(c)))
3644
0
  }
3645
3646
  /// Multiplies the elements in each lane of `a` and `b`, negates the results, and adds them to
3647
  /// each lane of `c`.
3648
  #[inline(always)]
3649
0
  pub fn negate_mul_add_f64x4(self, a: f64x4, b: f64x4, c: f64x4) -> f64x4 {
3650
0
    cast!(self.fma._mm256_fnmadd_pd(cast!(a), cast!(b), cast!(c)))
3651
0
  }
3652
3653
  /// Multiplies the elements in each lane of `a` and `b`, and subtracts each lane of `c` from
3654
  /// the negation of the results.
3655
  #[inline(always)]
3656
0
  pub fn negate_mul_sub_f32x4(self, a: f32x4, b: f32x4, c: f32x4) -> f32x4 {
3657
0
    cast!(self.fma._mm_fnmsub_ps(cast!(a), cast!(b), cast!(c)))
3658
0
  }
3659
3660
  /// Multiplies the elements in each lane of `a` and `b`, and subtracts each lane of `c` from
3661
  /// the negation of the results.
3662
  #[inline(always)]
3663
0
  pub fn negate_mul_sub_f32x8(self, a: f32x8, b: f32x8, c: f32x8) -> f32x8 {
3664
0
    cast!(self.fma._mm256_fnmsub_ps(cast!(a), cast!(b), cast!(c)))
3665
0
  }
3666
3667
  /// Multiplies the elements in each lane of `a` and `b`, and subtracts each lane of `c` from
3668
  /// the negation of the results.
3669
  #[inline(always)]
3670
0
  pub fn negate_mul_sub_f64x2(self, a: f64x2, b: f64x2, c: f64x2) -> f64x2 {
3671
0
    cast!(self.fma._mm_fnmsub_pd(cast!(a), cast!(b), cast!(c)))
3672
0
  }
3673
3674
  /// Multiplies the elements in each lane of `a` and `b`, and subtracts each lane of `c` from
3675
  /// the negation of the results.
3676
  #[inline(always)]
3677
0
  pub fn negate_mul_sub_f64x4(self, a: f64x4, b: f64x4, c: f64x4) -> f64x4 {
3678
0
    cast!(self.fma._mm256_fnmsub_pd(cast!(a), cast!(b), cast!(c)))
3679
0
  }
3680
3681
  /// Returns `!a` for each bit in a.
3682
  #[inline(always)]
3683
0
  pub fn not_i16x16(self, a: i16x16) -> i16x16 {
3684
0
    self.xor_i16x16(a, self.splat_i16x16(!0))
3685
0
  }
3686
3687
  /// Returns `!a` for each bit in a.
3688
  #[inline(always)]
3689
0
  pub fn not_i32x8(self, a: i32x8) -> i32x8 {
3690
0
    self.xor_i32x8(a, self.splat_i32x8(!0))
3691
0
  }
3692
3693
  /// Returns `!a` for each bit in a.
3694
  #[inline(always)]
3695
0
  pub fn not_i64x4(self, a: i64x4) -> i64x4 {
3696
0
    self.xor_i64x4(a, self.splat_i64x4(!0))
3697
0
  }
3698
3699
  /// Returns `!a` for each bit in a.
3700
  #[inline(always)]
3701
0
  pub fn not_i8x32(self, a: i8x32) -> i8x32 {
3702
0
    self.xor_i8x32(a, self.splat_i8x32(!0))
3703
0
  }
3704
3705
  /// Returns `!a` for each bit in a.
3706
  #[inline(always)]
3707
0
  pub fn not_m16x16(self, a: m16x16) -> m16x16 {
3708
0
    self.xor_m16x16(a, self.splat_m16x16(m16::new(true)))
3709
0
  }
3710
3711
  /// Returns `!a` for each bit in a.
3712
  #[inline(always)]
3713
0
  pub fn not_m32x8(self, a: m32x8) -> m32x8 {
3714
0
    self.xor_m32x8(a, self.splat_m32x8(m32::new(true)))
3715
0
  }
3716
3717
  /// Returns `!a` for each bit in a.
3718
  #[inline(always)]
3719
0
  pub fn not_m64x4(self, a: m64x4) -> m64x4 {
3720
0
    self.xor_m64x4(a, self.splat_m64x4(m64::new(true)))
3721
0
  }
3722
3723
  /// Returns `!a` for each bit in a.
3724
  #[inline(always)]
3725
0
  pub fn not_m8x32(self, a: m8x32) -> m8x32 {
3726
0
    self.xor_m8x32(a, self.splat_m8x32(m8::new(true)))
3727
0
  }
3728
3729
  /// Returns `!a` for each bit in a.
3730
  #[inline(always)]
3731
0
  pub fn not_u16x16(self, a: u16x16) -> u16x16 {
3732
0
    self.xor_u16x16(a, self.splat_u16x16(!0))
3733
0
  }
3734
3735
  /// Returns `!a` for each bit in a.
3736
  #[inline(always)]
3737
0
  pub fn not_u32x8(self, a: u32x8) -> u32x8 {
3738
0
    self.xor_u32x8(a, self.splat_u32x8(!0))
3739
0
  }
3740
3741
  /// Returns `!a` for each bit in a.
3742
  #[inline(always)]
3743
0
  pub fn not_u64x4(self, a: u64x4) -> u64x4 {
3744
0
    self.xor_u64x4(a, self.splat_u64x4(!0))
3745
0
  }
3746
3747
  /// Returns `!a` for each bit in a.
3748
  #[inline(always)]
3749
0
  pub fn not_u8x32(self, a: u8x32) -> u8x32 {
3750
0
    self.xor_u8x32(a, self.splat_u8x32(!0))
3751
0
  }
3752
3753
  /// See [_mm256_packs_epi16].
3754
  ///
3755
  /// [_mm256_packs_epi16]: core::arch::x86_64::_mm256_packs_epi16
3756
  #[inline(always)]
3757
0
  pub fn pack_with_signed_saturation_i16x16(self, a: i16x16, b: i16x16) -> i8x32 {
3758
0
    cast!(self.avx2._mm256_packs_epi16(cast!(a), cast!(b)))
3759
0
  }
3760
3761
  /// See [_mm256_packs_epi32].
3762
  ///
3763
  /// [_mm256_packs_epi32]: core::arch::x86_64::_mm256_packs_epi32
3764
  #[inline(always)]
3765
0
  pub fn pack_with_signed_saturation_i32x8(self, a: i32x8, b: i32x8) -> i16x16 {
3766
0
    cast!(self.avx2._mm256_packs_epi32(cast!(a), cast!(b)))
3767
0
  }
3768
3769
  /// See [_mm256_packus_epi16].
3770
  ///
3771
  /// [_mm256_packus_epi16]: core::arch::x86_64::_mm256_packus_epi16
3772
  #[inline(always)]
3773
0
  pub fn pack_with_unsigned_saturation_i16x16(self, a: i16x16, b: i16x16) -> u8x32 {
3774
0
    cast!(self.avx2._mm256_packus_epi16(cast!(a), cast!(b)))
3775
0
  }
3776
3777
  /// See [_mm256_packus_epi32].
3778
  ///
3779
  /// [_mm256_packus_epi32]: core::arch::x86_64::_mm256_packus_epi32
3780
  #[inline(always)]
3781
0
  pub fn pack_with_unsigned_saturation_i32x8(self, a: i32x8, b: i32x8) -> u16x16 {
3782
0
    cast!(self.avx2._mm256_packus_epi32(cast!(a), cast!(b)))
3783
0
  }
3784
3785
  /// Rounds the elements of each lane of `a` to the nearest integer. If two values are equally
3786
  /// close, the even value is returned.
3787
  #[inline(always)]
3788
0
  pub fn round_f32x8(self, a: f32x8) -> f32x8 {
3789
    const ROUNDING: i32 = _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC;
3790
0
    cast!(self.avx._mm256_round_ps::<ROUNDING>(cast!(a)))
3791
0
  }
3792
3793
  /// Rounds the elements of each lane of `a` to the nearest integer. If two values are equally
3794
  /// close, the even value is returned.
3795
  #[inline(always)]
3796
0
  pub fn round_f64x4(self, a: f64x4) -> f64x4 {
3797
    const ROUNDING: i32 = _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC;
3798
0
    cast!(self.avx._mm256_round_pd::<ROUNDING>(cast!(a)))
3799
0
  }
3800
3801
  /// Combines `if_true` and `if_false`, selecting elements from `if_true` if the corresponding
3802
  /// bit in the mask is set, otherwise selecting elements from `if_false`.
3803
  #[inline(always)]
3804
0
  pub fn select_const_f32x8<const MASK8: i32>(self, if_true: f32x8, if_false: f32x8) -> f32x8 {
3805
0
    cast!(
3806
0
      self.avx
3807
0
        ._mm256_blend_ps::<MASK8>(cast!(if_false), cast!(if_true)),
3808
    )
3809
0
  }
3810
3811
  /// Combines `if_true` and `if_false`, selecting elements from `if_true` if the corresponding
3812
  /// bit in the mask is set, otherwise selecting elements from `if_false`.
3813
  #[inline(always)]
3814
0
  pub fn select_const_f64x4<const MASK4: i32>(self, if_true: f64x4, if_false: f64x4) -> f64x4 {
3815
0
    cast!(self.select_const_u64x4::<MASK4>(cast!(if_true), cast!(if_false)))
3816
0
  }
3817
3818
  /// Combines `if_true` and `if_false`, selecting elements from `if_true` if the corresponding
3819
  /// bit in the mask is set, otherwise selecting elements from `if_false`.
3820
  #[inline(always)]
3821
0
  pub fn select_const_i32x8<const MASK8: i32>(self, if_true: i32x8, if_false: i32x8) -> i32x8 {
3822
0
    cast!(self.select_const_u32x8::<MASK8>(cast!(if_true), cast!(if_false)))
3823
0
  }
3824
3825
  /// Combines `if_true` and `if_false`, selecting elements from `if_true` if the corresponding
3826
  /// bit in the mask is set, otherwise selecting elements from `if_false`.
3827
  #[inline(always)]
3828
0
  pub fn select_const_i64x4<const MASK4: i32>(self, if_true: i64x4, if_false: i64x4) -> i64x4 {
3829
0
    cast!(self.select_const_u64x4::<MASK4>(cast!(if_true), cast!(if_false)))
3830
0
  }
3831
3832
  /// Combines `if_true` and `if_false`, selecting elements from `if_true` if the corresponding
3833
  /// bit in the mask is set, otherwise selecting elements from `if_false`.
3834
  #[inline(always)]
3835
0
  pub fn select_const_u32x8<const MASK8: i32>(self, if_true: u32x8, if_false: u32x8) -> u32x8 {
3836
0
    cast!(
3837
0
      self.avx2
3838
0
        ._mm256_blend_epi32::<MASK8>(cast!(if_false), cast!(if_true)),
3839
    )
3840
0
  }
3841
3842
  /// Combines `if_true` and `if_false`, selecting elements from `if_true` if the corresponding
3843
  /// bit in the mask is set, otherwise selecting elements from `if_false`.
3844
  #[inline(always)]
3845
0
  pub fn select_const_u64x4<const MASK4: i32>(self, if_true: u64x4, if_false: u64x4) -> u64x4 {
3846
0
    cast!(
3847
0
      self.avx
3848
0
        ._mm256_blend_pd::<MASK4>(cast!(if_false), cast!(if_true)),
3849
    )
3850
0
  }
3851
3852
  /// Combines `if_true` and `if_false`, selecting elements from `if_true` if the corresponding
3853
  /// mask in `mask` is set, otherwise selecting elements from `if_false`.
3854
  #[inline(always)]
3855
0
  pub fn select_f32x8(self, mask: m32x8, if_true: f32x8, if_false: f32x8) -> f32x8 {
3856
0
    cast!(
3857
0
      self.avx
3858
0
        ._mm256_blendv_ps(cast!(if_false), cast!(if_true), cast!(mask)),
3859
    )
3860
0
  }
3861
3862
  /// Combines `if_true` and `if_false`, selecting elements from `if_true` if the corresponding
3863
  /// mask in `mask` is set, otherwise selecting elements from `if_false`.
3864
  #[inline(always)]
3865
0
  pub fn select_f64x4(self, mask: m64x4, if_true: f64x4, if_false: f64x4) -> f64x4 {
3866
0
    cast!(
3867
0
      self.avx
3868
0
        ._mm256_blendv_pd(cast!(if_false), cast!(if_true), cast!(mask)),
3869
    )
3870
0
  }
3871
3872
  /// Combines `if_true` and `if_false`, selecting elements from `if_true` if the corresponding
3873
  /// mask in `mask` is set, otherwise selecting elements from `if_false`.
3874
  #[inline(always)]
3875
0
  pub fn select_i16x16(self, mask: m16x16, if_true: i16x16, if_false: i16x16) -> i16x16 {
3876
0
    cast!(self.select_u16x16(mask, cast!(if_true), cast!(if_false)))
3877
0
  }
3878
3879
  /// Combines `if_true` and `if_false`, selecting elements from `if_true` if the corresponding
3880
  /// mask in `mask` is set, otherwise selecting elements from `if_false`.
3881
  #[inline(always)]
3882
0
  pub fn select_i32x8(self, mask: m32x8, if_true: i32x8, if_false: i32x8) -> i32x8 {
3883
0
    cast!(self.select_u32x8(mask, cast!(if_true), cast!(if_false)))
3884
0
  }
3885
3886
  /// Combines `if_true` and `if_false`, selecting elements from `if_true` if the corresponding
3887
  /// mask in `mask` is set, otherwise selecting elements from `if_false`.
3888
  #[inline(always)]
3889
0
  pub fn select_i64x4(self, mask: m64x4, if_true: i64x4, if_false: i64x4) -> i64x4 {
3890
0
    cast!(self.select_u64x4(mask, cast!(if_true), cast!(if_false)))
3891
0
  }
3892
3893
  /// Combines `if_true` and `if_false`, selecting elements from `if_true` if the corresponding
3894
  /// mask in `mask` is set, otherwise selecting elements from `if_false`.
3895
  #[inline(always)]
3896
0
  pub fn select_i8x32(self, mask: m8x32, if_true: i8x32, if_false: i8x32) -> i8x32 {
3897
0
    cast!(self.select_u8x32(mask, cast!(if_true), cast!(if_false)))
3898
0
  }
3899
3900
  /// Combines `if_true` and `if_false`, selecting elements from `if_true` if the corresponding
3901
  /// mask in `mask` is set, otherwise selecting elements from `if_false`.
3902
  #[inline(always)]
3903
0
  pub fn select_u16x16(self, mask: m16x16, if_true: u16x16, if_false: u16x16) -> u16x16 {
3904
0
    cast!(
3905
0
      self.avx2
3906
0
        ._mm256_blendv_epi8(cast!(if_false), cast!(if_true), cast!(mask)),
3907
    )
3908
0
  }
3909
3910
  /// Combines `if_true` and `if_false`, selecting elements from `if_true` if the corresponding
3911
  /// mask in `mask` is set, otherwise selecting elements from `if_false`.
3912
  #[inline(always)]
3913
0
  pub fn select_u32x8(self, mask: m32x8, if_true: u32x8, if_false: u32x8) -> u32x8 {
3914
0
    cast!(
3915
0
      self.avx2
3916
0
        ._mm256_blendv_epi8(cast!(if_false), cast!(if_true), cast!(mask)),
3917
    )
3918
0
  }
3919
3920
  /// Combines `if_true` and `if_false`, selecting elements from `if_true` if the corresponding
3921
  /// mask in `mask` is set, otherwise selecting elements from `if_false`.
3922
  #[inline(always)]
3923
0
  pub fn select_u64x4(self, mask: m64x4, if_true: u64x4, if_false: u64x4) -> u64x4 {
3924
0
    cast!(
3925
0
      self.avx2
3926
0
        ._mm256_blendv_epi8(cast!(if_false), cast!(if_true), cast!(mask)),
3927
    )
3928
0
  }
3929
3930
  /// Combines `if_true` and `if_false`, selecting elements from `if_true` if the corresponding
3931
  /// mask in `mask` is set, otherwise selecting elements from `if_false`.
3932
  #[inline(always)]
3933
0
  pub fn select_u8x32(self, mask: m8x32, if_true: u8x32, if_false: u8x32) -> u8x32 {
3934
0
    cast!(
3935
0
      self.avx2
3936
0
        ._mm256_blendv_epi8(cast!(if_false), cast!(if_true), cast!(mask)),
3937
    )
3938
0
  }
3939
3940
  /// Shift the bits of each lane of `a` to the left by `AMOUNT`, while shifting in zeros.
3941
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
3942
  #[inline(always)]
3943
0
  pub fn shl_const_i16x16<const AMOUNT: i32>(self, a: i16x16) -> i16x16 {
3944
0
    cast!(self.avx2._mm256_slli_epi16::<AMOUNT>(cast!(a)))
3945
0
  }
3946
3947
  /// Shift the bits of each lane of `a` to the left by `AMOUNT`, while shifting in zeros.
3948
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
3949
  #[inline(always)]
3950
0
  pub fn shl_const_i32x8<const AMOUNT: i32>(self, a: i32x8) -> i32x8 {
3951
0
    cast!(self.avx2._mm256_slli_epi32::<AMOUNT>(cast!(a)))
3952
0
  }
3953
3954
  /// Shift the bits of each lane of `a` to the left by `AMOUNT`, while shifting in zeros.
3955
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
3956
  #[inline(always)]
3957
0
  pub fn shl_const_i64x4<const AMOUNT: i32>(self, a: i64x4) -> i64x4 {
3958
0
    cast!(self.avx2._mm256_slli_epi64::<AMOUNT>(cast!(a)))
3959
0
  }
3960
3961
  /// Shift the bits of each lane of `a` to the left by `AMOUNT`, while shifting in zeros.
3962
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
3963
  #[inline(always)]
3964
0
  pub fn shl_const_u16x16<const AMOUNT: i32>(self, a: u16x16) -> u16x16 {
3965
0
    cast!(self.avx2._mm256_slli_epi16::<AMOUNT>(cast!(a)))
3966
0
  }
3967
3968
  /// Shift the bits of each lane of `a` to the left by `AMOUNT`, while shifting in zeros.
3969
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
3970
  #[inline(always)]
3971
0
  pub fn shl_const_u32x8<const AMOUNT: i32>(self, a: u32x8) -> u32x8 {
3972
0
    cast!(self.avx2._mm256_slli_epi32::<AMOUNT>(cast!(a)))
3973
0
  }
3974
3975
  /// Shift the bits of each lane of `a` to the left by `AMOUNT`, while shifting in zeros.
3976
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
3977
  #[inline(always)]
3978
0
  pub fn shl_const_u64x4<const AMOUNT: i32>(self, a: u64x4) -> u64x4 {
3979
0
    cast!(self.avx2._mm256_slli_epi64::<AMOUNT>(cast!(a)))
3980
0
  }
3981
3982
  /// Shift the bits of each lane of `a` to the left by the element in the corresponding lane in
3983
  /// `amount`, while shifting in zeros.
3984
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
3985
  #[inline(always)]
3986
0
  pub fn shl_dyn_i32x4(self, a: i32x4, amount: u32x4) -> i32x4 {
3987
0
    cast!(self.avx2._mm_sllv_epi32(cast!(a), cast!(amount)))
3988
0
  }
3989
3990
  /// Shift the bits of each lane of `a` to the left by the element in the corresponding lane in
3991
  /// `amount`, while shifting in zeros.
3992
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
3993
  #[inline(always)]
3994
0
  pub fn shl_dyn_i32x8(self, a: i32x8, amount: u32x8) -> i32x8 {
3995
0
    cast!(self.avx2._mm256_sllv_epi32(cast!(a), cast!(amount)))
3996
0
  }
3997
3998
  /// Shift the bits of each lane of `a` to the left by the element in the corresponding lane in
3999
  /// `amount`, while shifting in zeros.
4000
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4001
  #[inline(always)]
4002
0
  pub fn shl_dyn_i64x2(self, a: i64x2, amount: u64x2) -> i64x2 {
4003
0
    cast!(self.avx2._mm_sllv_epi64(cast!(a), cast!(amount)))
4004
0
  }
4005
4006
  /// Shift the bits of each lane of `a` to the left by the element in the corresponding lane in
4007
  /// `amount`, while shifting in zeros.
4008
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4009
  #[inline(always)]
4010
0
  pub fn shl_dyn_i64x4(self, a: i64x4, amount: u64x4) -> i64x4 {
4011
0
    cast!(self.avx2._mm256_sllv_epi64(cast!(a), cast!(amount)))
4012
0
  }
4013
4014
  /// Shift the bits of each lane of `a` to the left by the element in the corresponding lane in
4015
  /// `amount`, while shifting in zeros.
4016
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4017
  #[inline(always)]
4018
0
  pub fn shl_dyn_u32x4(self, a: u32x4, amount: u32x4) -> u32x4 {
4019
0
    cast!(self.avx2._mm_sllv_epi32(cast!(a), cast!(amount)))
4020
0
  }
4021
4022
  /// Shift the bits of each lane of `a` to the left by the element in the corresponding lane in
4023
  /// `amount`, while shifting in zeros.
4024
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4025
  #[inline(always)]
4026
0
  pub fn shl_dyn_u32x8(self, a: u32x8, amount: u32x8) -> u32x8 {
4027
0
    cast!(self.avx2._mm256_sllv_epi32(cast!(a), cast!(amount)))
4028
0
  }
4029
4030
  /// Shift the bits of each lane of `a` to the left by the element in the corresponding lane in
4031
  /// `amount`, while shifting in zeros.
4032
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4033
  #[inline(always)]
4034
0
  pub fn shl_dyn_u64x2(self, a: u64x2, amount: u64x2) -> u64x2 {
4035
0
    cast!(self.avx2._mm_sllv_epi64(cast!(a), cast!(amount)))
4036
0
  }
4037
4038
  /// Shift the bits of each lane of `a` to the left by the element in the corresponding lane in
4039
  /// `amount`, while shifting in zeros.
4040
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4041
  #[inline(always)]
4042
0
  pub fn shl_dyn_u64x4(self, a: u64x4, amount: u64x4) -> u64x4 {
4043
0
    cast!(self.avx2._mm256_sllv_epi64(cast!(a), cast!(amount)))
4044
0
  }
4045
4046
  /// Shift the bits of each lane of `a` to the left by the first element in `amount`, while
4047
  /// shifting in zeros.
4048
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4049
  #[inline(always)]
4050
0
  pub fn shl_i16x16(self, a: i16x16, amount: u64x2) -> i16x16 {
4051
0
    cast!(self.avx2._mm256_sll_epi16(cast!(a), cast!(amount)))
4052
0
  }
4053
4054
  /// Shift the bits of each lane of `a` to the left by the first element in `amount`, while
4055
  /// shifting in zeros.
4056
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4057
  #[inline(always)]
4058
0
  pub fn shl_i32x8(self, a: i32x8, amount: u64x2) -> i32x8 {
4059
0
    cast!(self.avx2._mm256_sll_epi32(cast!(a), cast!(amount)))
4060
0
  }
4061
4062
  /// Shift the bits of each lane of `a` to the left by the first element in `amount`, while
4063
  /// shifting in zeros.
4064
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4065
  #[inline(always)]
4066
0
  pub fn shl_i64x4(self, a: i64x4, amount: u64x2) -> i64x4 {
4067
0
    cast!(self.avx2._mm256_sll_epi64(cast!(a), cast!(amount)))
4068
0
  }
4069
4070
  /// Shift the bits of each lane of `a` to the left by the first element in `amount`, while
4071
  /// shifting in zeros.
4072
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4073
  #[inline(always)]
4074
0
  pub fn shl_u16x16(self, a: u16x16, amount: u64x2) -> u16x16 {
4075
0
    cast!(self.avx2._mm256_sll_epi16(cast!(a), cast!(amount)))
4076
0
  }
4077
4078
  /// Shift the bits of each lane of `a` to the left by the first element in `amount`, while
4079
  /// shifting in zeros.
4080
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4081
  #[inline(always)]
4082
0
  pub fn shl_u32x8(self, a: u32x8, amount: u64x2) -> u32x8 {
4083
0
    cast!(self.avx2._mm256_sll_epi32(cast!(a), cast!(amount)))
4084
0
  }
4085
4086
  /// Shift the bits of each lane of `a` to the left by the first element in `amount`, while
4087
  /// shifting in zeros.
4088
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4089
  #[inline(always)]
4090
0
  pub fn shl_u64x4(self, a: u64x4, amount: u64x2) -> u64x4 {
4091
0
    cast!(self.avx2._mm256_sll_epi64(cast!(a), cast!(amount)))
4092
0
  }
4093
4094
  /// Shift the bits of each lane of `a` to the right by `AMOUNT`, while shifting in sign bits.
4095
  /// Shifting by a value greater than the bit width of the type sets the result to zero if the
4096
  /// sign bit is not set, and to `-1` if the sign bit is set.
4097
  #[inline(always)]
4098
0
  pub fn shr_const_i16x16<const AMOUNT: i32>(self, a: i16x16) -> i16x16 {
4099
0
    cast!(self.avx2._mm256_srai_epi16::<AMOUNT>(cast!(a)))
4100
0
  }
4101
4102
  /// Shift the bits of each lane of `a` to the right by `AMOUNT`, while shifting in sign bits.
4103
  /// Shifting by a value greater than the bit width of the type sets the result to zero if the
4104
  /// sign bit is not set, and to `-1` if the sign bit is set.
4105
  #[inline(always)]
4106
0
  pub fn shr_const_i32x8<const AMOUNT: i32>(self, a: i32x8) -> i32x8 {
4107
0
    cast!(self.avx2._mm256_srai_epi32::<AMOUNT>(cast!(a)))
4108
0
  }
4109
4110
  /// Shift the bits of each lane of `a` to the right by `AMOUNT`, while shifting in zeros.
4111
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4112
  #[inline(always)]
4113
0
  pub fn shr_const_u16x16<const AMOUNT: i32>(self, a: u16x16) -> u16x16 {
4114
0
    cast!(self.avx2._mm256_srli_epi16::<AMOUNT>(cast!(a)))
4115
0
  }
4116
4117
  /// Shift the bits of each lane of `a` to the right by `AMOUNT`, while shifting in zeros.
4118
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4119
  #[inline(always)]
4120
0
  pub fn shr_const_u32x8<const AMOUNT: i32>(self, a: u32x8) -> u32x8 {
4121
0
    cast!(self.avx2._mm256_srli_epi32::<AMOUNT>(cast!(a)))
4122
0
  }
4123
4124
  /// Shift the bits of each lane of `a` to the right by `AMOUNT`, while shifting in zeros.
4125
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4126
  #[inline(always)]
4127
0
  pub fn shr_const_u64x4<const AMOUNT: i32>(self, a: u64x4) -> u64x4 {
4128
0
    cast!(self.avx2._mm256_srli_epi64::<AMOUNT>(cast!(a)))
4129
0
  }
4130
4131
  /// Shift the bits of each lane of `a` to the right by the element in the corresponding lane in
4132
  /// `amount`, while shifting in sign bits.
4133
  /// Shifting by a value greater than the bit width of the type sets the result to zero if the
4134
  /// sign bit is not set, and to `-1` if the sign bit is set.
4135
  #[inline(always)]
4136
0
  pub fn shr_dyn_i32x4(self, a: i32x4, amount: u32x4) -> i32x4 {
4137
0
    cast!(self.avx2._mm_srav_epi32(cast!(a), cast!(amount)))
4138
0
  }
4139
4140
  /// Shift the bits of each lane of `a` to the right by the element in the corresponding lane in
4141
  /// `amount`, while shifting in sign bits.
4142
  /// Shifting by a value greater than the bit width of the type sets the result to zero if the
4143
  /// sign bit is not set, and to `-1` if the sign bit is set.
4144
  #[inline(always)]
4145
0
  pub fn shr_dyn_i32x8(self, a: i32x8, amount: u32x8) -> i32x8 {
4146
0
    cast!(self.avx2._mm256_srav_epi32(cast!(a), cast!(amount)))
4147
0
  }
4148
4149
  /// Shift the bits of each lane of `a` to the right by the element in the corresponding lane in
4150
  /// `amount`, while shifting in zeros.
4151
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4152
  #[inline(always)]
4153
0
  pub fn shr_dyn_u32x4(self, a: u32x4, amount: u32x4) -> u32x4 {
4154
0
    cast!(self.avx2._mm_srlv_epi32(cast!(a), cast!(amount)))
4155
0
  }
4156
4157
  /// Shift the bits of each lane of `a` to the right by the element in the corresponding lane in
4158
  /// `amount`, while shifting in zeros.
4159
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4160
  #[inline(always)]
4161
0
  pub fn shr_dyn_u32x8(self, a: u32x8, amount: u32x8) -> u32x8 {
4162
0
    cast!(self.avx2._mm256_srlv_epi32(cast!(a), cast!(amount)))
4163
0
  }
4164
4165
  /// Shift the bits of each lane of `a` to the right by the element in the corresponding lane in
4166
  /// `amount`, while shifting in zeros.
4167
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4168
  #[inline(always)]
4169
0
  pub fn shr_dyn_u64x2(self, a: u64x2, amount: u64x2) -> u64x2 {
4170
0
    cast!(self.avx2._mm_srlv_epi64(cast!(a), cast!(amount)))
4171
0
  }
4172
4173
  /// Shift the bits of each lane of `a` to the right by the element in the corresponding lane in
4174
  /// `amount`, while shifting in zeros.
4175
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4176
  #[inline(always)]
4177
0
  pub fn shr_dyn_u64x4(self, a: u64x4, amount: u64x4) -> u64x4 {
4178
0
    cast!(self.avx2._mm256_srlv_epi64(cast!(a), cast!(amount)))
4179
0
  }
4180
4181
  /// Shift the bits of each lane of `a` to the right by the first element in `amount`, while
4182
  /// shifting in zeros.
4183
  /// Shifting by a value greater than the bit width of the type sets the result to zero if the
4184
  /// sign bit is not set, and to `-1` if the sign bit is set.
4185
  #[inline(always)]
4186
0
  pub fn shr_i16x16(self, a: i16x16, amount: u64x2) -> i16x16 {
4187
0
    cast!(self.avx2._mm256_sra_epi16(cast!(a), cast!(amount)))
4188
0
  }
4189
4190
  /// Shift the bits of each lane of `a` to the right by the first element in `amount`, while
4191
  /// shifting in zeros.
4192
  /// Shifting by a value greater than the bit width of the type sets the result to zero if the
4193
  /// sign bit is not set, and to `-1` if the sign bit is set.
4194
  #[inline(always)]
4195
0
  pub fn shr_i32x8(self, a: i32x8, amount: u64x2) -> i32x8 {
4196
0
    cast!(self.avx2._mm256_sra_epi32(cast!(a), cast!(amount)))
4197
0
  }
4198
4199
  /// Shift the bits of each lane of `a` to the right by the first element in `amount`, while
4200
  /// shifting in zeros.
4201
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4202
  #[inline(always)]
4203
0
  pub fn shr_u16x16(self, a: u16x16, amount: u64x2) -> u16x16 {
4204
0
    cast!(self.avx2._mm256_srl_epi16(cast!(a), cast!(amount)))
4205
0
  }
4206
4207
  /// Shift the bits of each lane of `a` to the right by the first element in `amount`, while
4208
  /// shifting in zeros.
4209
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4210
  #[inline(always)]
4211
0
  pub fn shr_u32x8(self, a: u32x8, amount: u64x2) -> u32x8 {
4212
0
    cast!(self.avx2._mm256_srl_epi32(cast!(a), cast!(amount)))
4213
0
  }
4214
4215
  /// Shift the bits of each lane of `a` to the right by the first element in `amount`, while
4216
  /// shifting in zeros.
4217
  /// Shifting by a value greater than the bit width of the type sets the result to zero.
4218
  #[inline(always)]
4219
0
  pub fn shr_u64x4(self, a: u64x4, amount: u64x2) -> u64x4 {
4220
0
    cast!(self.avx2._mm256_srl_epi64(cast!(a), cast!(amount)))
4221
0
  }
4222
4223
  /// Returns a SIMD vector with all lanes set to the given value.
4224
  #[inline(always)]
4225
0
  pub fn splat_f32x8(self, value: f32) -> f32x8 {
4226
0
    cast!(self.avx._mm256_set1_ps(value))
4227
0
  }
4228
4229
  /// Returns a SIMD vector with all lanes set to the given value.
4230
  #[inline(always)]
4231
0
  pub fn splat_f64x4(self, value: f64) -> f64x4 {
4232
0
    cast!(self.avx._mm256_set1_pd(value))
4233
0
  }
4234
4235
  /// Returns a SIMD vector with all lanes set to the given value.
4236
  #[inline(always)]
4237
0
  pub fn splat_i16x16(self, value: i16) -> i16x16 {
4238
0
    cast!(self.avx._mm256_set1_epi16(value))
4239
0
  }
4240
4241
  /// Returns a SIMD vector with all lanes set to the given value.
4242
  #[inline(always)]
4243
0
  pub fn splat_i32x8(self, value: i32) -> i32x8 {
4244
0
    cast!(self.avx._mm256_set1_epi32(value))
4245
0
  }
4246
4247
  /// Returns a SIMD vector with all lanes set to the given value.
4248
  #[inline(always)]
4249
0
  pub fn splat_i64x4(self, value: i64) -> i64x4 {
4250
0
    cast!(self.avx._mm256_set1_epi64x(value))
4251
0
  }
4252
4253
  /// Returns a SIMD vector with all lanes set to the given value.
4254
  #[inline(always)]
4255
0
  pub fn splat_i8x32(self, value: i8) -> i8x32 {
4256
0
    cast!(self.avx._mm256_set1_epi8(value))
4257
0
  }
4258
4259
  /// Returns a SIMD vector with all lanes set to the given value.
4260
  #[inline(always)]
4261
0
  pub fn splat_m16x16(self, value: m16) -> m16x16 {
4262
0
    cast!(self.avx._mm256_set1_epi16(value.0 as i16))
4263
0
  }
4264
4265
  /// Returns a SIMD vector with all lanes set to the given value.
4266
  #[inline(always)]
4267
0
  pub fn splat_m32x8(self, value: m32) -> m32x8 {
4268
0
    cast!(self.avx._mm256_set1_epi32(value.0 as i32))
4269
0
  }
4270
4271
  /// Returns a SIMD vector with all lanes set to the given value.
4272
  #[inline(always)]
4273
0
  pub fn splat_m64x4(self, value: m64) -> m64x4 {
4274
0
    cast!(self.avx._mm256_set1_epi64x(value.0 as i64))
4275
0
  }
4276
4277
  /// Returns a SIMD vector with all lanes set to the given value.
4278
  #[inline(always)]
4279
0
  pub fn splat_m8x32(self, value: m8) -> m8x32 {
4280
0
    cast!(self.avx._mm256_set1_epi8(value.0 as i8))
4281
0
  }
4282
4283
  /// Returns a SIMD vector with all lanes set to the given value.
4284
  #[inline(always)]
4285
0
  pub fn splat_u16x16(self, value: u16) -> u16x16 {
4286
0
    cast!(self.avx._mm256_set1_epi16(value as i16))
4287
0
  }
4288
4289
  /// Returns a SIMD vector with all lanes set to the given value.
4290
  #[inline(always)]
4291
0
  pub fn splat_u32x8(self, value: u32) -> u32x8 {
4292
0
    cast!(self.avx._mm256_set1_epi32(value as i32))
4293
0
  }
4294
4295
  /// Returns a SIMD vector with all lanes set to the given value.
4296
  #[inline(always)]
4297
0
  pub fn splat_u64x4(self, value: u64) -> u64x4 {
4298
0
    cast!(self.avx._mm256_set1_epi64x(value as i64))
4299
0
  }
4300
4301
  /// Returns a SIMD vector with all lanes set to the given value.
4302
  #[inline(always)]
4303
0
  pub fn splat_u8x32(self, value: u8) -> u8x32 {
4304
0
    cast!(self.avx._mm256_set1_epi8(value as i8))
4305
0
  }
4306
4307
  /// Computes the square roots of the elements of each lane of `a`.
4308
  #[inline(always)]
4309
0
  pub fn sqrt_f32x8(self, a: f32x8) -> f32x8 {
4310
0
    cast!(self.avx._mm256_sqrt_ps(cast!(a)))
4311
0
  }
4312
4313
  /// Computes the square roots of the elements of each lane of `a`.
4314
  #[inline(always)]
4315
0
  pub fn sqrt_f64x4(self, a: f64x4) -> f64x4 {
4316
0
    cast!(self.avx._mm256_sqrt_pd(cast!(a)))
4317
0
  }
4318
4319
  /// See [_mm256_sad_epu8].
4320
  ///
4321
  /// [_mm256_sad_epu8]: core::arch::x86_64::_mm256_sad_epu8
4322
  #[inline(always)]
4323
0
  pub fn sum_of_absolute_differences_u8x32(self, a: u8x32, b: u8x32) -> u64x4 {
4324
0
    cast!(self.avx2._mm256_sad_epu8(cast!(a), cast!(b)))
4325
0
  }
4326
4327
  /// Rounds the elements of each lane of `a` to the nearest integer towards zero.
4328
  #[inline(always)]
4329
0
  pub fn truncate_f32x8(self, a: f32x8) -> f32x8 {
4330
    const ROUNDING: i32 = _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC;
4331
0
    cast!(self.avx._mm256_round_ps::<ROUNDING>(cast!(a)))
4332
0
  }
4333
4334
  /// Rounds the elements of each lane of `a` to the nearest integer towards zero.
4335
  #[inline(always)]
4336
0
  pub fn truncate_f64x4(self, a: f64x4) -> f64x4 {
4337
    const ROUNDING: i32 = _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC;
4338
0
    cast!(self.avx._mm256_round_pd::<ROUNDING>(cast!(a)))
4339
0
  }
4340
4341
  /// Multiplies the elements of each lane of `a` and `b`, and returns separately the low and
4342
  /// high bits of the result.
4343
  #[inline(always)]
4344
0
  pub fn widening_mul_i16x16(self, a: i16x16, b: i16x16) -> (u16x16, i16x16) {
4345
    (
4346
0
      cast!(self.avx2._mm256_mullo_epi16(cast!(a), cast!(b))),
4347
0
      cast!(self.avx2._mm256_mulhi_epi16(cast!(a), cast!(b))),
4348
    )
4349
0
  }
4350
4351
  /// Multiplies the elements of each lane of `a` and `b`, and returns separately the low and
4352
  /// high bits of the result.
4353
  #[inline(always)]
4354
0
  pub fn widening_mul_i32x8(self, a: i32x8, b: i32x8) -> (u32x8, i32x8) {
4355
0
    let a = cast!(a);
4356
0
    let b = cast!(b);
4357
0
    let avx2 = self.avx2;
4358
4359
    // a0b0_lo a0b0_hi a2b2_lo a2b2_hi
4360
0
    let ab_evens = self.avx2._mm256_mul_epi32(a, b);
4361
    // a1b1_lo a1b1_hi a3b3_lo a3b3_hi
4362
0
    let ab_odds = self.avx2._mm256_mul_epi32(
4363
0
      avx2._mm256_srli_epi64::<32>(a),
4364
0
      avx2._mm256_srli_epi64::<32>(b),
4365
    );
4366
4367
0
    let ab_lo = self.avx2._mm256_blend_epi32::<0b10101010>(
4368
      // a0b0_lo xxxxxxx a2b2_lo xxxxxxx
4369
0
      ab_evens,
4370
      // xxxxxxx a1b1_lo xxxxxxx a3b3_lo
4371
0
      avx2._mm256_slli_epi64::<32>(ab_odds),
4372
    );
4373
0
    let ab_hi = self.avx2._mm256_blend_epi32::<0b10101010>(
4374
      // a0b0_hi xxxxxxx a2b2_hi xxxxxxx
4375
0
      avx2._mm256_srli_epi64::<32>(ab_evens),
4376
      // xxxxxxx a1b1_hi xxxxxxx a3b3_hi
4377
0
      ab_odds,
4378
    );
4379
4380
0
    (cast!(ab_lo), cast!(ab_hi))
4381
0
  }
4382
4383
  /// Multiplies the elements of each lane of `a` and `b`, and returns separately the low and
4384
  /// high bits of the result.
4385
  #[inline(always)]
4386
0
  pub fn widening_mul_u16x16(self, a: u16x16, b: u16x16) -> (u16x16, u16x16) {
4387
    (
4388
0
      cast!(self.avx2._mm256_mullo_epi16(cast!(a), cast!(b))),
4389
0
      cast!(self.avx2._mm256_mulhi_epu16(cast!(a), cast!(b))),
4390
    )
4391
0
  }
4392
4393
  /// Multiplies the elements of each lane of `a` and `b`, and returns separately the low and
4394
  /// high bits of the result.
4395
  #[inline(always)]
4396
0
  pub fn widening_mul_u32x8(self, a: u32x8, b: u32x8) -> (u32x8, u32x8) {
4397
0
    let a = cast!(a);
4398
0
    let b = cast!(b);
4399
0
    let avx2 = self.avx2;
4400
4401
    // a0b0_lo a0b0_hi a2b2_lo a2b2_hi
4402
0
    let ab_evens = avx2._mm256_mul_epu32(a, b);
4403
    // a1b1_lo a1b1_hi a3b3_lo a3b3_hi
4404
0
    let ab_odds = avx2._mm256_mul_epu32(
4405
0
      avx2._mm256_srli_epi64::<32>(a),
4406
0
      avx2._mm256_srli_epi64::<32>(b),
4407
    );
4408
4409
0
    let ab_lo = self.avx2._mm256_blend_epi32::<0b10101010>(
4410
      // a0b0_lo xxxxxxx a2b2_lo xxxxxxx
4411
0
      ab_evens,
4412
      // xxxxxxx a1b1_lo xxxxxxx a3b3_lo
4413
0
      avx2._mm256_slli_epi64::<32>(ab_odds),
4414
    );
4415
0
    let ab_hi = self.avx2._mm256_blend_epi32::<0b10101010>(
4416
      // a0b0_hi xxxxxxx a2b2_hi xxxxxxx
4417
0
      avx2._mm256_srli_epi64::<32>(ab_evens),
4418
      // xxxxxxx a1b1_hi xxxxxxx a3b3_hi
4419
0
      ab_odds,
4420
    );
4421
4422
0
    (cast!(ab_lo), cast!(ab_hi))
4423
0
  }
4424
}