1use crate::{Bytes, Select, Simd, SimdBase, SimdCvtFloat, SimdCvtTruncate, SimdFrom, SimdInto};
7#[doc = "A SIMD vector of 4 [`f32`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, f32x4};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = f32x4::splat(simd, 1.0);\n let b = f32x4::simd_from(simd, 1.0);\n\n // From a slice:\n let c = f32x4::from_slice(simd, &[1.0, 2.0, 3.0, 4.0]);\n\n // From an array:\n let d = f32x4::simd_from(simd, [1.0, 2.0, 3.0, 4.0]);\n\n // From an element-wise function:\n let e = f32x4::from_fn(simd, |i| i as f32);\n}\n```"]
8#[derive(Clone, Copy)]
9#[repr(C, align(16))]
10pub struct f32x4<S: Simd> {
11 pub(crate) val: S::f32x4,
12 pub simd: S,
13}
14impl<S: Simd> SimdFrom<[f32; 4], S> for f32x4<S> {
15 #[inline(always)]
16 fn simd_from(simd: S, val: [f32; 4]) -> Self {
17 simd.load_array_f32x4(val)
18 }
19}
20impl<S: Simd> From<f32x4<S>> for [f32; 4] {
21 #[inline(always)]
22 fn from(value: f32x4<S>) -> Self {
23 value.simd.as_array_f32x4(value)
24 }
25}
26impl<S: Simd> core::ops::Deref for f32x4<S> {
27 type Target = [f32; 4];
28 #[inline(always)]
29 fn deref(&self) -> &Self::Target {
30 self.simd.as_array_ref_f32x4(self)
31 }
32}
33impl<S: Simd> core::ops::DerefMut for f32x4<S> {
34 #[inline(always)]
35 fn deref_mut(&mut self) -> &mut Self::Target {
36 self.simd.as_array_mut_f32x4(self)
37 }
38}
39impl<S: Simd + core::fmt::Debug> core::fmt::Debug for f32x4<S> {
40 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
41 crate::support::simd_debug_impl(f, "f32x4", &self.simd, self.simd.as_array_ref_f32x4(self))
42 }
43}
44impl<S: Simd> SimdFrom<f32, S> for f32x4<S> {
45 #[inline(always)]
46 fn simd_from(simd: S, value: f32) -> Self {
47 simd.splat_f32x4(value)
48 }
49}
50impl<S: Simd> core::ops::Index<usize> for f32x4<S> {
51 type Output = f32;
52 #[inline(always)]
53 fn index(&self, i: usize) -> &Self::Output {
54 &self.simd.as_array_ref_f32x4(self)[i]
55 }
56}
57impl<S: Simd> core::ops::IndexMut<usize> for f32x4<S> {
58 #[inline(always)]
59 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
60 &mut self.simd.as_array_mut_f32x4(self)[i]
61 }
62}
63impl<S: Simd> Select<f32x4<S>> for mask32x4<S> {
64 #[inline(always)]
65 fn select(self, if_true: f32x4<S>, if_false: f32x4<S>) -> f32x4<S> {
66 self.simd.select_f32x4(self, if_true, if_false)
67 }
68}
69impl<S: Simd> Bytes for f32x4<S> {
70 type Bytes = u8x16<S>;
71 #[inline(always)]
72 fn to_bytes(self) -> Self::Bytes {
73 self.simd.cvt_to_bytes_f32x4(self)
74 }
75 #[inline(always)]
76 fn from_bytes(value: Self::Bytes) -> Self {
77 value.simd.cvt_from_bytes_f32x4(value)
78 }
79}
80impl<S: Simd> SimdBase<S> for f32x4<S> {
81 type Element = f32;
82 const N: usize = 4;
83 type Mask = mask32x4<S>;
84 type Block = f32x4<S>;
85 type Array = [f32; 4];
86 #[inline(always)]
87 fn witness(&self) -> S {
88 self.simd
89 }
90 #[inline(always)]
91 fn as_slice(&self) -> &[f32] {
92 self.simd.as_array_ref_f32x4(self).as_slice()
93 }
94 #[inline(always)]
95 fn as_mut_slice(&mut self) -> &mut [f32] {
96 self.simd.as_array_mut_f32x4(self).as_mut_slice()
97 }
98 #[inline(always)]
99 fn from_slice(simd: S, slice: &[f32]) -> Self {
100 simd.load_array_ref_f32x4(slice.try_into().unwrap())
101 }
102 #[inline(always)]
103 fn store_slice(&self, slice: &mut [f32]) {
104 self.simd
105 .store_array_f32x4(*self, slice.try_into().unwrap());
106 }
107 #[inline(always)]
108 fn splat(simd: S, val: f32) -> Self {
109 simd.splat_f32x4(val)
110 }
111 #[inline(always)]
112 fn block_splat(block: Self::Block) -> Self {
113 block
114 }
115 #[inline(always)]
116 fn from_fn(simd: S, f: impl FnMut(usize) -> f32) -> Self {
117 simd.load_array_f32x4(core::array::from_fn(f))
118 }
119 #[inline(always)]
120 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
121 self.simd
122 .slide_f32x4::<SHIFT>(self, rhs.simd_into(self.simd))
123 }
124 #[inline(always)]
125 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
126 self.simd
127 .slide_within_blocks_f32x4::<SHIFT>(self, rhs.simd_into(self.simd))
128 }
129}
130impl<S: Simd> crate::SimdFloat<S> for f32x4<S> {
131 #[inline(always)]
132 fn abs(self) -> Self {
133 self.simd.abs_f32x4(self)
134 }
135 #[inline(always)]
136 fn sqrt(self) -> Self {
137 self.simd.sqrt_f32x4(self)
138 }
139 #[inline(always)]
140 fn copysign(self, rhs: impl SimdInto<Self, S>) -> Self {
141 self.simd.copysign_f32x4(self, rhs.simd_into(self.simd))
142 }
143 #[inline(always)]
144 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
145 self.simd.simd_eq_f32x4(self, rhs.simd_into(self.simd))
146 }
147 #[inline(always)]
148 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
149 self.simd.simd_lt_f32x4(self, rhs.simd_into(self.simd))
150 }
151 #[inline(always)]
152 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
153 self.simd.simd_le_f32x4(self, rhs.simd_into(self.simd))
154 }
155 #[inline(always)]
156 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
157 self.simd.simd_ge_f32x4(self, rhs.simd_into(self.simd))
158 }
159 #[inline(always)]
160 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
161 self.simd.simd_gt_f32x4(self, rhs.simd_into(self.simd))
162 }
163 #[inline(always)]
164 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
165 self.simd.zip_low_f32x4(self, rhs.simd_into(self.simd))
166 }
167 #[inline(always)]
168 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
169 self.simd.zip_high_f32x4(self, rhs.simd_into(self.simd))
170 }
171 #[inline(always)]
172 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
173 self.simd.unzip_low_f32x4(self, rhs.simd_into(self.simd))
174 }
175 #[inline(always)]
176 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
177 self.simd.unzip_high_f32x4(self, rhs.simd_into(self.simd))
178 }
179 #[inline(always)]
180 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
181 self.simd.interleave_f32x4(self, rhs.simd_into(self.simd))
182 }
183 #[inline(always)]
184 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
185 self.simd.deinterleave_f32x4(self, rhs.simd_into(self.simd))
186 }
187 #[inline(always)]
188 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
189 self.simd.max_f32x4(self, rhs.simd_into(self.simd))
190 }
191 #[inline(always)]
192 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
193 self.simd.min_f32x4(self, rhs.simd_into(self.simd))
194 }
195 #[inline(always)]
196 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
197 self.simd.max_precise_f32x4(self, rhs.simd_into(self.simd))
198 }
199 #[inline(always)]
200 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
201 self.simd.min_precise_f32x4(self, rhs.simd_into(self.simd))
202 }
203 #[inline(always)]
204 fn mul_add(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
205 self.simd
206 .mul_add_f32x4(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
207 }
208 #[inline(always)]
209 fn mul_sub(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
210 self.simd
211 .mul_sub_f32x4(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
212 }
213 #[inline(always)]
214 fn floor(self) -> Self {
215 self.simd.floor_f32x4(self)
216 }
217 #[inline(always)]
218 fn ceil(self) -> Self {
219 self.simd.ceil_f32x4(self)
220 }
221 #[inline(always)]
222 fn round_ties_even(self) -> Self {
223 self.simd.round_ties_even_f32x4(self)
224 }
225 #[inline(always)]
226 fn fract(self) -> Self {
227 self.simd.fract_f32x4(self)
228 }
229 #[inline(always)]
230 fn trunc(self) -> Self {
231 self.simd.trunc_f32x4(self)
232 }
233}
234impl<S: Simd> SimdCvtFloat<u32x4<S>> for f32x4<S> {
235 #[doc = "Convert each unsigned 32-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
236 #[inline(always)]
237 fn float_from(x: u32x4<S>) -> Self {
238 x.simd.cvt_f32_u32x4(x)
239 }
240}
241impl<S: Simd> SimdCvtFloat<i32x4<S>> for f32x4<S> {
242 #[doc = "Convert each signed 32-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
243 #[inline(always)]
244 fn float_from(x: i32x4<S>) -> Self {
245 x.simd.cvt_f32_i32x4(x)
246 }
247}
248impl<S: Simd> crate::SimdCombine<S> for f32x4<S> {
249 type Combined = f32x8<S>;
250 #[inline(always)]
251 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
252 self.simd.combine_f32x4(self, rhs.simd_into(self.simd))
253 }
254}
255#[doc = "A SIMD vector of 16 [`i8`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, i8x16};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = i8x16::splat(simd, 1);\n let b = i8x16::simd_from(simd, 1);\n\n // From a slice:\n let c = i8x16::from_slice(simd, &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);\n\n // From an array:\n let d = i8x16::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);\n\n // From an element-wise function:\n let e = i8x16::from_fn(simd, |i| i as i8);\n}\n```"]
256#[derive(Clone, Copy)]
257#[repr(C, align(16))]
258pub struct i8x16<S: Simd> {
259 pub(crate) val: S::i8x16,
260 pub simd: S,
261}
262impl<S: Simd> SimdFrom<[i8; 16], S> for i8x16<S> {
263 #[inline(always)]
264 fn simd_from(simd: S, val: [i8; 16]) -> Self {
265 simd.load_array_i8x16(val)
266 }
267}
268impl<S: Simd> From<i8x16<S>> for [i8; 16] {
269 #[inline(always)]
270 fn from(value: i8x16<S>) -> Self {
271 value.simd.as_array_i8x16(value)
272 }
273}
274impl<S: Simd> core::ops::Deref for i8x16<S> {
275 type Target = [i8; 16];
276 #[inline(always)]
277 fn deref(&self) -> &Self::Target {
278 self.simd.as_array_ref_i8x16(self)
279 }
280}
281impl<S: Simd> core::ops::DerefMut for i8x16<S> {
282 #[inline(always)]
283 fn deref_mut(&mut self) -> &mut Self::Target {
284 self.simd.as_array_mut_i8x16(self)
285 }
286}
287impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i8x16<S> {
288 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
289 crate::support::simd_debug_impl(f, "i8x16", &self.simd, self.simd.as_array_ref_i8x16(self))
290 }
291}
292impl<S: Simd> SimdFrom<i8, S> for i8x16<S> {
293 #[inline(always)]
294 fn simd_from(simd: S, value: i8) -> Self {
295 simd.splat_i8x16(value)
296 }
297}
298impl<S: Simd> core::ops::Index<usize> for i8x16<S> {
299 type Output = i8;
300 #[inline(always)]
301 fn index(&self, i: usize) -> &Self::Output {
302 &self.simd.as_array_ref_i8x16(self)[i]
303 }
304}
305impl<S: Simd> core::ops::IndexMut<usize> for i8x16<S> {
306 #[inline(always)]
307 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
308 &mut self.simd.as_array_mut_i8x16(self)[i]
309 }
310}
311impl<S: Simd> Select<i8x16<S>> for mask8x16<S> {
312 #[inline(always)]
313 fn select(self, if_true: i8x16<S>, if_false: i8x16<S>) -> i8x16<S> {
314 self.simd.select_i8x16(self, if_true, if_false)
315 }
316}
317impl<S: Simd> Bytes for i8x16<S> {
318 type Bytes = u8x16<S>;
319 #[inline(always)]
320 fn to_bytes(self) -> Self::Bytes {
321 self.simd.cvt_to_bytes_i8x16(self)
322 }
323 #[inline(always)]
324 fn from_bytes(value: Self::Bytes) -> Self {
325 value.simd.cvt_from_bytes_i8x16(value)
326 }
327}
328impl<S: Simd> SimdBase<S> for i8x16<S> {
329 type Element = i8;
330 const N: usize = 16;
331 type Mask = mask8x16<S>;
332 type Block = i8x16<S>;
333 type Array = [i8; 16];
334 #[inline(always)]
335 fn witness(&self) -> S {
336 self.simd
337 }
338 #[inline(always)]
339 fn as_slice(&self) -> &[i8] {
340 self.simd.as_array_ref_i8x16(self).as_slice()
341 }
342 #[inline(always)]
343 fn as_mut_slice(&mut self) -> &mut [i8] {
344 self.simd.as_array_mut_i8x16(self).as_mut_slice()
345 }
346 #[inline(always)]
347 fn from_slice(simd: S, slice: &[i8]) -> Self {
348 simd.load_array_ref_i8x16(slice.try_into().unwrap())
349 }
350 #[inline(always)]
351 fn store_slice(&self, slice: &mut [i8]) {
352 self.simd
353 .store_array_i8x16(*self, slice.try_into().unwrap());
354 }
355 #[inline(always)]
356 fn splat(simd: S, val: i8) -> Self {
357 simd.splat_i8x16(val)
358 }
359 #[inline(always)]
360 fn block_splat(block: Self::Block) -> Self {
361 block
362 }
363 #[inline(always)]
364 fn from_fn(simd: S, f: impl FnMut(usize) -> i8) -> Self {
365 simd.load_array_i8x16(core::array::from_fn(f))
366 }
367 #[inline(always)]
368 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
369 self.simd
370 .slide_i8x16::<SHIFT>(self, rhs.simd_into(self.simd))
371 }
372 #[inline(always)]
373 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
374 self.simd
375 .slide_within_blocks_i8x16::<SHIFT>(self, rhs.simd_into(self.simd))
376 }
377}
378impl<S: Simd> crate::SimdInt<S> for i8x16<S> {
379 #[inline(always)]
380 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
381 self.simd.simd_eq_i8x16(self, rhs.simd_into(self.simd))
382 }
383 #[inline(always)]
384 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
385 self.simd.simd_lt_i8x16(self, rhs.simd_into(self.simd))
386 }
387 #[inline(always)]
388 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
389 self.simd.simd_le_i8x16(self, rhs.simd_into(self.simd))
390 }
391 #[inline(always)]
392 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
393 self.simd.simd_ge_i8x16(self, rhs.simd_into(self.simd))
394 }
395 #[inline(always)]
396 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
397 self.simd.simd_gt_i8x16(self, rhs.simd_into(self.simd))
398 }
399 #[inline(always)]
400 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
401 self.simd.zip_low_i8x16(self, rhs.simd_into(self.simd))
402 }
403 #[inline(always)]
404 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
405 self.simd.zip_high_i8x16(self, rhs.simd_into(self.simd))
406 }
407 #[inline(always)]
408 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
409 self.simd.unzip_low_i8x16(self, rhs.simd_into(self.simd))
410 }
411 #[inline(always)]
412 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
413 self.simd.unzip_high_i8x16(self, rhs.simd_into(self.simd))
414 }
415 #[inline(always)]
416 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
417 self.simd.interleave_i8x16(self, rhs.simd_into(self.simd))
418 }
419 #[inline(always)]
420 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
421 self.simd.deinterleave_i8x16(self, rhs.simd_into(self.simd))
422 }
423 #[inline(always)]
424 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
425 self.simd.min_i8x16(self, rhs.simd_into(self.simd))
426 }
427 #[inline(always)]
428 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
429 self.simd.max_i8x16(self, rhs.simd_into(self.simd))
430 }
431}
432impl<S: Simd> crate::SimdCombine<S> for i8x16<S> {
433 type Combined = i8x32<S>;
434 #[inline(always)]
435 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
436 self.simd.combine_i8x16(self, rhs.simd_into(self.simd))
437 }
438}
439#[doc = "A SIMD vector of 16 [`u8`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, u8x16};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = u8x16::splat(simd, 1);\n let b = u8x16::simd_from(simd, 1);\n\n // From a slice:\n let c = u8x16::from_slice(simd, &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);\n\n // From an array:\n let d = u8x16::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);\n\n // From an element-wise function:\n let e = u8x16::from_fn(simd, |i| i as u8);\n}\n```"]
440#[derive(Clone, Copy)]
441#[repr(C, align(16))]
442pub struct u8x16<S: Simd> {
443 pub(crate) val: S::u8x16,
444 pub simd: S,
445}
446impl<S: Simd> SimdFrom<[u8; 16], S> for u8x16<S> {
447 #[inline(always)]
448 fn simd_from(simd: S, val: [u8; 16]) -> Self {
449 simd.load_array_u8x16(val)
450 }
451}
452impl<S: Simd> From<u8x16<S>> for [u8; 16] {
453 #[inline(always)]
454 fn from(value: u8x16<S>) -> Self {
455 value.simd.as_array_u8x16(value)
456 }
457}
458impl<S: Simd> core::ops::Deref for u8x16<S> {
459 type Target = [u8; 16];
460 #[inline(always)]
461 fn deref(&self) -> &Self::Target {
462 self.simd.as_array_ref_u8x16(self)
463 }
464}
465impl<S: Simd> core::ops::DerefMut for u8x16<S> {
466 #[inline(always)]
467 fn deref_mut(&mut self) -> &mut Self::Target {
468 self.simd.as_array_mut_u8x16(self)
469 }
470}
471impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u8x16<S> {
472 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
473 crate::support::simd_debug_impl(f, "u8x16", &self.simd, self.simd.as_array_ref_u8x16(self))
474 }
475}
476impl<S: Simd> SimdFrom<u8, S> for u8x16<S> {
477 #[inline(always)]
478 fn simd_from(simd: S, value: u8) -> Self {
479 simd.splat_u8x16(value)
480 }
481}
482impl<S: Simd> core::ops::Index<usize> for u8x16<S> {
483 type Output = u8;
484 #[inline(always)]
485 fn index(&self, i: usize) -> &Self::Output {
486 &self.simd.as_array_ref_u8x16(self)[i]
487 }
488}
489impl<S: Simd> core::ops::IndexMut<usize> for u8x16<S> {
490 #[inline(always)]
491 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
492 &mut self.simd.as_array_mut_u8x16(self)[i]
493 }
494}
495impl<S: Simd> Select<u8x16<S>> for mask8x16<S> {
496 #[inline(always)]
497 fn select(self, if_true: u8x16<S>, if_false: u8x16<S>) -> u8x16<S> {
498 self.simd.select_u8x16(self, if_true, if_false)
499 }
500}
501impl<S: Simd> Bytes for u8x16<S> {
502 type Bytes = u8x16<S>;
503 #[inline(always)]
504 fn to_bytes(self) -> Self::Bytes {
505 self.simd.cvt_to_bytes_u8x16(self)
506 }
507 #[inline(always)]
508 fn from_bytes(value: Self::Bytes) -> Self {
509 value.simd.cvt_from_bytes_u8x16(value)
510 }
511}
512impl<S: Simd> SimdBase<S> for u8x16<S> {
513 type Element = u8;
514 const N: usize = 16;
515 type Mask = mask8x16<S>;
516 type Block = u8x16<S>;
517 type Array = [u8; 16];
518 #[inline(always)]
519 fn witness(&self) -> S {
520 self.simd
521 }
522 #[inline(always)]
523 fn as_slice(&self) -> &[u8] {
524 self.simd.as_array_ref_u8x16(self).as_slice()
525 }
526 #[inline(always)]
527 fn as_mut_slice(&mut self) -> &mut [u8] {
528 self.simd.as_array_mut_u8x16(self).as_mut_slice()
529 }
530 #[inline(always)]
531 fn from_slice(simd: S, slice: &[u8]) -> Self {
532 simd.load_array_ref_u8x16(slice.try_into().unwrap())
533 }
534 #[inline(always)]
535 fn store_slice(&self, slice: &mut [u8]) {
536 self.simd
537 .store_array_u8x16(*self, slice.try_into().unwrap());
538 }
539 #[inline(always)]
540 fn splat(simd: S, val: u8) -> Self {
541 simd.splat_u8x16(val)
542 }
543 #[inline(always)]
544 fn block_splat(block: Self::Block) -> Self {
545 block
546 }
547 #[inline(always)]
548 fn from_fn(simd: S, f: impl FnMut(usize) -> u8) -> Self {
549 simd.load_array_u8x16(core::array::from_fn(f))
550 }
551 #[inline(always)]
552 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
553 self.simd
554 .slide_u8x16::<SHIFT>(self, rhs.simd_into(self.simd))
555 }
556 #[inline(always)]
557 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
558 self.simd
559 .slide_within_blocks_u8x16::<SHIFT>(self, rhs.simd_into(self.simd))
560 }
561}
562impl<S: Simd> crate::SimdInt<S> for u8x16<S> {
563 #[inline(always)]
564 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
565 self.simd.simd_eq_u8x16(self, rhs.simd_into(self.simd))
566 }
567 #[inline(always)]
568 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
569 self.simd.simd_lt_u8x16(self, rhs.simd_into(self.simd))
570 }
571 #[inline(always)]
572 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
573 self.simd.simd_le_u8x16(self, rhs.simd_into(self.simd))
574 }
575 #[inline(always)]
576 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
577 self.simd.simd_ge_u8x16(self, rhs.simd_into(self.simd))
578 }
579 #[inline(always)]
580 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
581 self.simd.simd_gt_u8x16(self, rhs.simd_into(self.simd))
582 }
583 #[inline(always)]
584 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
585 self.simd.zip_low_u8x16(self, rhs.simd_into(self.simd))
586 }
587 #[inline(always)]
588 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
589 self.simd.zip_high_u8x16(self, rhs.simd_into(self.simd))
590 }
591 #[inline(always)]
592 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
593 self.simd.unzip_low_u8x16(self, rhs.simd_into(self.simd))
594 }
595 #[inline(always)]
596 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
597 self.simd.unzip_high_u8x16(self, rhs.simd_into(self.simd))
598 }
599 #[inline(always)]
600 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
601 self.simd.interleave_u8x16(self, rhs.simd_into(self.simd))
602 }
603 #[inline(always)]
604 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
605 self.simd.deinterleave_u8x16(self, rhs.simd_into(self.simd))
606 }
607 #[inline(always)]
608 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
609 self.simd.min_u8x16(self, rhs.simd_into(self.simd))
610 }
611 #[inline(always)]
612 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
613 self.simd.max_u8x16(self, rhs.simd_into(self.simd))
614 }
615}
616impl<S: Simd> crate::SimdCombine<S> for u8x16<S> {
617 type Combined = u8x32<S>;
618 #[inline(always)]
619 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
620 self.simd.combine_u8x16(self, rhs.simd_into(self.simd))
621 }
622}
623#[doc = "A SIMD mask of 16 8-bit elements.\n\nWhen created from a comparison operation, and as it should be used in a [`Self::select`] operation, each element will be all ones if it's \"true\", and all zeroes if it's \"false\"."]
624#[derive(Clone, Copy)]
625#[repr(C, align(16))]
626pub struct mask8x16<S: Simd> {
627 pub(crate) val: S::mask8x16,
628 pub simd: S,
629}
630impl<S: Simd> SimdFrom<[i8; 16], S> for mask8x16<S> {
631 #[inline(always)]
632 fn simd_from(simd: S, val: [i8; 16]) -> Self {
633 simd.load_array_mask8x16(val)
634 }
635}
636impl<S: Simd> From<mask8x16<S>> for [i8; 16] {
637 #[inline(always)]
638 fn from(value: mask8x16<S>) -> Self {
639 value.simd.as_array_mask8x16(value)
640 }
641}
642impl<S: Simd> core::ops::Deref for mask8x16<S> {
643 type Target = [i8; 16];
644 #[inline(always)]
645 fn deref(&self) -> &Self::Target {
646 self.simd.as_array_ref_mask8x16(self)
647 }
648}
649impl<S: Simd> core::ops::DerefMut for mask8x16<S> {
650 #[inline(always)]
651 fn deref_mut(&mut self) -> &mut Self::Target {
652 self.simd.as_array_mut_mask8x16(self)
653 }
654}
655impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask8x16<S> {
656 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
657 crate::support::simd_debug_impl(
658 f,
659 "mask8x16",
660 &self.simd,
661 self.simd.as_array_ref_mask8x16(self),
662 )
663 }
664}
665impl<S: Simd> SimdFrom<i8, S> for mask8x16<S> {
666 #[inline(always)]
667 fn simd_from(simd: S, value: i8) -> Self {
668 simd.splat_mask8x16(value)
669 }
670}
671impl<S: Simd> core::ops::Index<usize> for mask8x16<S> {
672 type Output = i8;
673 #[inline(always)]
674 fn index(&self, i: usize) -> &Self::Output {
675 &self.simd.as_array_ref_mask8x16(self)[i]
676 }
677}
678impl<S: Simd> core::ops::IndexMut<usize> for mask8x16<S> {
679 #[inline(always)]
680 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
681 &mut self.simd.as_array_mut_mask8x16(self)[i]
682 }
683}
684impl<S: Simd> Select<mask8x16<S>> for mask8x16<S> {
685 #[inline(always)]
686 fn select(self, if_true: mask8x16<S>, if_false: mask8x16<S>) -> mask8x16<S> {
687 self.simd.select_mask8x16(self, if_true, if_false)
688 }
689}
690impl<S: Simd> Bytes for mask8x16<S> {
691 type Bytes = u8x16<S>;
692 #[inline(always)]
693 fn to_bytes(self) -> Self::Bytes {
694 self.simd.cvt_to_bytes_mask8x16(self)
695 }
696 #[inline(always)]
697 fn from_bytes(value: Self::Bytes) -> Self {
698 value.simd.cvt_from_bytes_mask8x16(value)
699 }
700}
701impl<S: Simd> SimdBase<S> for mask8x16<S> {
702 type Element = i8;
703 const N: usize = 16;
704 type Mask = mask8x16<S>;
705 type Block = mask8x16<S>;
706 type Array = [i8; 16];
707 #[inline(always)]
708 fn witness(&self) -> S {
709 self.simd
710 }
711 #[inline(always)]
712 fn as_slice(&self) -> &[i8] {
713 self.simd.as_array_ref_mask8x16(self).as_slice()
714 }
715 #[inline(always)]
716 fn as_mut_slice(&mut self) -> &mut [i8] {
717 self.simd.as_array_mut_mask8x16(self).as_mut_slice()
718 }
719 #[inline(always)]
720 fn from_slice(simd: S, slice: &[i8]) -> Self {
721 simd.load_array_ref_mask8x16(slice.try_into().unwrap())
722 }
723 #[inline(always)]
724 fn store_slice(&self, slice: &mut [i8]) {
725 self.simd
726 .store_array_mask8x16(*self, slice.try_into().unwrap());
727 }
728 #[inline(always)]
729 fn splat(simd: S, val: i8) -> Self {
730 simd.splat_mask8x16(val)
731 }
732 #[inline(always)]
733 fn block_splat(block: Self::Block) -> Self {
734 block
735 }
736 #[inline(always)]
737 fn from_fn(simd: S, f: impl FnMut(usize) -> i8) -> Self {
738 simd.load_array_mask8x16(core::array::from_fn(f))
739 }
740 #[inline(always)]
741 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
742 self.simd
743 .slide_mask8x16::<SHIFT>(self, rhs.simd_into(self.simd))
744 }
745 #[inline(always)]
746 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
747 self.simd
748 .slide_within_blocks_mask8x16::<SHIFT>(self, rhs.simd_into(self.simd))
749 }
750}
751impl<S: Simd> crate::SimdMask<S> for mask8x16<S> {
752 #[inline(always)]
753 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
754 self.simd.simd_eq_mask8x16(self, rhs.simd_into(self.simd))
755 }
756 #[inline(always)]
757 fn any_true(self) -> bool {
758 self.simd.any_true_mask8x16(self)
759 }
760 #[inline(always)]
761 fn all_true(self) -> bool {
762 self.simd.all_true_mask8x16(self)
763 }
764 #[inline(always)]
765 fn any_false(self) -> bool {
766 self.simd.any_false_mask8x16(self)
767 }
768 #[inline(always)]
769 fn all_false(self) -> bool {
770 self.simd.all_false_mask8x16(self)
771 }
772}
773impl<S: Simd> crate::SimdCombine<S> for mask8x16<S> {
774 type Combined = mask8x32<S>;
775 #[inline(always)]
776 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
777 self.simd.combine_mask8x16(self, rhs.simd_into(self.simd))
778 }
779}
780#[doc = "A SIMD vector of 8 [`i16`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, i16x8};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = i16x8::splat(simd, 1);\n let b = i16x8::simd_from(simd, 1);\n\n // From a slice:\n let c = i16x8::from_slice(simd, &[1, 2, 3, 4, 5, 6, 7, 8]);\n\n // From an array:\n let d = i16x8::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8]);\n\n // From an element-wise function:\n let e = i16x8::from_fn(simd, |i| i as i16);\n}\n```"]
781#[derive(Clone, Copy)]
782#[repr(C, align(16))]
783pub struct i16x8<S: Simd> {
784 pub(crate) val: S::i16x8,
785 pub simd: S,
786}
787impl<S: Simd> SimdFrom<[i16; 8], S> for i16x8<S> {
788 #[inline(always)]
789 fn simd_from(simd: S, val: [i16; 8]) -> Self {
790 simd.load_array_i16x8(val)
791 }
792}
793impl<S: Simd> From<i16x8<S>> for [i16; 8] {
794 #[inline(always)]
795 fn from(value: i16x8<S>) -> Self {
796 value.simd.as_array_i16x8(value)
797 }
798}
799impl<S: Simd> core::ops::Deref for i16x8<S> {
800 type Target = [i16; 8];
801 #[inline(always)]
802 fn deref(&self) -> &Self::Target {
803 self.simd.as_array_ref_i16x8(self)
804 }
805}
806impl<S: Simd> core::ops::DerefMut for i16x8<S> {
807 #[inline(always)]
808 fn deref_mut(&mut self) -> &mut Self::Target {
809 self.simd.as_array_mut_i16x8(self)
810 }
811}
812impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i16x8<S> {
813 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
814 crate::support::simd_debug_impl(f, "i16x8", &self.simd, self.simd.as_array_ref_i16x8(self))
815 }
816}
817impl<S: Simd> SimdFrom<i16, S> for i16x8<S> {
818 #[inline(always)]
819 fn simd_from(simd: S, value: i16) -> Self {
820 simd.splat_i16x8(value)
821 }
822}
823impl<S: Simd> core::ops::Index<usize> for i16x8<S> {
824 type Output = i16;
825 #[inline(always)]
826 fn index(&self, i: usize) -> &Self::Output {
827 &self.simd.as_array_ref_i16x8(self)[i]
828 }
829}
830impl<S: Simd> core::ops::IndexMut<usize> for i16x8<S> {
831 #[inline(always)]
832 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
833 &mut self.simd.as_array_mut_i16x8(self)[i]
834 }
835}
836impl<S: Simd> Select<i16x8<S>> for mask16x8<S> {
837 #[inline(always)]
838 fn select(self, if_true: i16x8<S>, if_false: i16x8<S>) -> i16x8<S> {
839 self.simd.select_i16x8(self, if_true, if_false)
840 }
841}
842impl<S: Simd> Bytes for i16x8<S> {
843 type Bytes = u8x16<S>;
844 #[inline(always)]
845 fn to_bytes(self) -> Self::Bytes {
846 self.simd.cvt_to_bytes_i16x8(self)
847 }
848 #[inline(always)]
849 fn from_bytes(value: Self::Bytes) -> Self {
850 value.simd.cvt_from_bytes_i16x8(value)
851 }
852}
853impl<S: Simd> SimdBase<S> for i16x8<S> {
854 type Element = i16;
855 const N: usize = 8;
856 type Mask = mask16x8<S>;
857 type Block = i16x8<S>;
858 type Array = [i16; 8];
859 #[inline(always)]
860 fn witness(&self) -> S {
861 self.simd
862 }
863 #[inline(always)]
864 fn as_slice(&self) -> &[i16] {
865 self.simd.as_array_ref_i16x8(self).as_slice()
866 }
867 #[inline(always)]
868 fn as_mut_slice(&mut self) -> &mut [i16] {
869 self.simd.as_array_mut_i16x8(self).as_mut_slice()
870 }
871 #[inline(always)]
872 fn from_slice(simd: S, slice: &[i16]) -> Self {
873 simd.load_array_ref_i16x8(slice.try_into().unwrap())
874 }
875 #[inline(always)]
876 fn store_slice(&self, slice: &mut [i16]) {
877 self.simd
878 .store_array_i16x8(*self, slice.try_into().unwrap());
879 }
880 #[inline(always)]
881 fn splat(simd: S, val: i16) -> Self {
882 simd.splat_i16x8(val)
883 }
884 #[inline(always)]
885 fn block_splat(block: Self::Block) -> Self {
886 block
887 }
888 #[inline(always)]
889 fn from_fn(simd: S, f: impl FnMut(usize) -> i16) -> Self {
890 simd.load_array_i16x8(core::array::from_fn(f))
891 }
892 #[inline(always)]
893 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
894 self.simd
895 .slide_i16x8::<SHIFT>(self, rhs.simd_into(self.simd))
896 }
897 #[inline(always)]
898 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
899 self.simd
900 .slide_within_blocks_i16x8::<SHIFT>(self, rhs.simd_into(self.simd))
901 }
902}
903impl<S: Simd> crate::SimdInt<S> for i16x8<S> {
904 #[inline(always)]
905 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
906 self.simd.simd_eq_i16x8(self, rhs.simd_into(self.simd))
907 }
908 #[inline(always)]
909 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
910 self.simd.simd_lt_i16x8(self, rhs.simd_into(self.simd))
911 }
912 #[inline(always)]
913 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
914 self.simd.simd_le_i16x8(self, rhs.simd_into(self.simd))
915 }
916 #[inline(always)]
917 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
918 self.simd.simd_ge_i16x8(self, rhs.simd_into(self.simd))
919 }
920 #[inline(always)]
921 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
922 self.simd.simd_gt_i16x8(self, rhs.simd_into(self.simd))
923 }
924 #[inline(always)]
925 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
926 self.simd.zip_low_i16x8(self, rhs.simd_into(self.simd))
927 }
928 #[inline(always)]
929 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
930 self.simd.zip_high_i16x8(self, rhs.simd_into(self.simd))
931 }
932 #[inline(always)]
933 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
934 self.simd.unzip_low_i16x8(self, rhs.simd_into(self.simd))
935 }
936 #[inline(always)]
937 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
938 self.simd.unzip_high_i16x8(self, rhs.simd_into(self.simd))
939 }
940 #[inline(always)]
941 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
942 self.simd.interleave_i16x8(self, rhs.simd_into(self.simd))
943 }
944 #[inline(always)]
945 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
946 self.simd.deinterleave_i16x8(self, rhs.simd_into(self.simd))
947 }
948 #[inline(always)]
949 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
950 self.simd.min_i16x8(self, rhs.simd_into(self.simd))
951 }
952 #[inline(always)]
953 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
954 self.simd.max_i16x8(self, rhs.simd_into(self.simd))
955 }
956}
957impl<S: Simd> crate::SimdCombine<S> for i16x8<S> {
958 type Combined = i16x16<S>;
959 #[inline(always)]
960 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
961 self.simd.combine_i16x8(self, rhs.simd_into(self.simd))
962 }
963}
964#[doc = "A SIMD vector of 8 [`u16`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, u16x8};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = u16x8::splat(simd, 1);\n let b = u16x8::simd_from(simd, 1);\n\n // From a slice:\n let c = u16x8::from_slice(simd, &[1, 2, 3, 4, 5, 6, 7, 8]);\n\n // From an array:\n let d = u16x8::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8]);\n\n // From an element-wise function:\n let e = u16x8::from_fn(simd, |i| i as u16);\n}\n```"]
965#[derive(Clone, Copy)]
966#[repr(C, align(16))]
967pub struct u16x8<S: Simd> {
968 pub(crate) val: S::u16x8,
969 pub simd: S,
970}
971impl<S: Simd> SimdFrom<[u16; 8], S> for u16x8<S> {
972 #[inline(always)]
973 fn simd_from(simd: S, val: [u16; 8]) -> Self {
974 simd.load_array_u16x8(val)
975 }
976}
977impl<S: Simd> From<u16x8<S>> for [u16; 8] {
978 #[inline(always)]
979 fn from(value: u16x8<S>) -> Self {
980 value.simd.as_array_u16x8(value)
981 }
982}
983impl<S: Simd> core::ops::Deref for u16x8<S> {
984 type Target = [u16; 8];
985 #[inline(always)]
986 fn deref(&self) -> &Self::Target {
987 self.simd.as_array_ref_u16x8(self)
988 }
989}
990impl<S: Simd> core::ops::DerefMut for u16x8<S> {
991 #[inline(always)]
992 fn deref_mut(&mut self) -> &mut Self::Target {
993 self.simd.as_array_mut_u16x8(self)
994 }
995}
996impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u16x8<S> {
997 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
998 crate::support::simd_debug_impl(f, "u16x8", &self.simd, self.simd.as_array_ref_u16x8(self))
999 }
1000}
1001impl<S: Simd> SimdFrom<u16, S> for u16x8<S> {
1002 #[inline(always)]
1003 fn simd_from(simd: S, value: u16) -> Self {
1004 simd.splat_u16x8(value)
1005 }
1006}
1007impl<S: Simd> core::ops::Index<usize> for u16x8<S> {
1008 type Output = u16;
1009 #[inline(always)]
1010 fn index(&self, i: usize) -> &Self::Output {
1011 &self.simd.as_array_ref_u16x8(self)[i]
1012 }
1013}
1014impl<S: Simd> core::ops::IndexMut<usize> for u16x8<S> {
1015 #[inline(always)]
1016 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
1017 &mut self.simd.as_array_mut_u16x8(self)[i]
1018 }
1019}
1020impl<S: Simd> Select<u16x8<S>> for mask16x8<S> {
1021 #[inline(always)]
1022 fn select(self, if_true: u16x8<S>, if_false: u16x8<S>) -> u16x8<S> {
1023 self.simd.select_u16x8(self, if_true, if_false)
1024 }
1025}
1026impl<S: Simd> Bytes for u16x8<S> {
1027 type Bytes = u8x16<S>;
1028 #[inline(always)]
1029 fn to_bytes(self) -> Self::Bytes {
1030 self.simd.cvt_to_bytes_u16x8(self)
1031 }
1032 #[inline(always)]
1033 fn from_bytes(value: Self::Bytes) -> Self {
1034 value.simd.cvt_from_bytes_u16x8(value)
1035 }
1036}
1037impl<S: Simd> SimdBase<S> for u16x8<S> {
1038 type Element = u16;
1039 const N: usize = 8;
1040 type Mask = mask16x8<S>;
1041 type Block = u16x8<S>;
1042 type Array = [u16; 8];
1043 #[inline(always)]
1044 fn witness(&self) -> S {
1045 self.simd
1046 }
1047 #[inline(always)]
1048 fn as_slice(&self) -> &[u16] {
1049 self.simd.as_array_ref_u16x8(self).as_slice()
1050 }
1051 #[inline(always)]
1052 fn as_mut_slice(&mut self) -> &mut [u16] {
1053 self.simd.as_array_mut_u16x8(self).as_mut_slice()
1054 }
1055 #[inline(always)]
1056 fn from_slice(simd: S, slice: &[u16]) -> Self {
1057 simd.load_array_ref_u16x8(slice.try_into().unwrap())
1058 }
1059 #[inline(always)]
1060 fn store_slice(&self, slice: &mut [u16]) {
1061 self.simd
1062 .store_array_u16x8(*self, slice.try_into().unwrap());
1063 }
1064 #[inline(always)]
1065 fn splat(simd: S, val: u16) -> Self {
1066 simd.splat_u16x8(val)
1067 }
1068 #[inline(always)]
1069 fn block_splat(block: Self::Block) -> Self {
1070 block
1071 }
1072 #[inline(always)]
1073 fn from_fn(simd: S, f: impl FnMut(usize) -> u16) -> Self {
1074 simd.load_array_u16x8(core::array::from_fn(f))
1075 }
1076 #[inline(always)]
1077 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
1078 self.simd
1079 .slide_u16x8::<SHIFT>(self, rhs.simd_into(self.simd))
1080 }
1081 #[inline(always)]
1082 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
1083 self.simd
1084 .slide_within_blocks_u16x8::<SHIFT>(self, rhs.simd_into(self.simd))
1085 }
1086}
1087impl<S: Simd> crate::SimdInt<S> for u16x8<S> {
1088 #[inline(always)]
1089 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1090 self.simd.simd_eq_u16x8(self, rhs.simd_into(self.simd))
1091 }
1092 #[inline(always)]
1093 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1094 self.simd.simd_lt_u16x8(self, rhs.simd_into(self.simd))
1095 }
1096 #[inline(always)]
1097 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1098 self.simd.simd_le_u16x8(self, rhs.simd_into(self.simd))
1099 }
1100 #[inline(always)]
1101 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1102 self.simd.simd_ge_u16x8(self, rhs.simd_into(self.simd))
1103 }
1104 #[inline(always)]
1105 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1106 self.simd.simd_gt_u16x8(self, rhs.simd_into(self.simd))
1107 }
1108 #[inline(always)]
1109 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
1110 self.simd.zip_low_u16x8(self, rhs.simd_into(self.simd))
1111 }
1112 #[inline(always)]
1113 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
1114 self.simd.zip_high_u16x8(self, rhs.simd_into(self.simd))
1115 }
1116 #[inline(always)]
1117 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
1118 self.simd.unzip_low_u16x8(self, rhs.simd_into(self.simd))
1119 }
1120 #[inline(always)]
1121 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
1122 self.simd.unzip_high_u16x8(self, rhs.simd_into(self.simd))
1123 }
1124 #[inline(always)]
1125 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
1126 self.simd.interleave_u16x8(self, rhs.simd_into(self.simd))
1127 }
1128 #[inline(always)]
1129 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
1130 self.simd.deinterleave_u16x8(self, rhs.simd_into(self.simd))
1131 }
1132 #[inline(always)]
1133 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
1134 self.simd.min_u16x8(self, rhs.simd_into(self.simd))
1135 }
1136 #[inline(always)]
1137 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
1138 self.simd.max_u16x8(self, rhs.simd_into(self.simd))
1139 }
1140}
1141impl<S: Simd> crate::SimdCombine<S> for u16x8<S> {
1142 type Combined = u16x16<S>;
1143 #[inline(always)]
1144 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
1145 self.simd.combine_u16x8(self, rhs.simd_into(self.simd))
1146 }
1147}
1148#[doc = "A SIMD mask of 8 16-bit elements.\n\nWhen created from a comparison operation, and as it should be used in a [`Self::select`] operation, each element will be all ones if it's \"true\", and all zeroes if it's \"false\"."]
1149#[derive(Clone, Copy)]
1150#[repr(C, align(16))]
1151pub struct mask16x8<S: Simd> {
1152 pub(crate) val: S::mask16x8,
1153 pub simd: S,
1154}
1155impl<S: Simd> SimdFrom<[i16; 8], S> for mask16x8<S> {
1156 #[inline(always)]
1157 fn simd_from(simd: S, val: [i16; 8]) -> Self {
1158 simd.load_array_mask16x8(val)
1159 }
1160}
1161impl<S: Simd> From<mask16x8<S>> for [i16; 8] {
1162 #[inline(always)]
1163 fn from(value: mask16x8<S>) -> Self {
1164 value.simd.as_array_mask16x8(value)
1165 }
1166}
1167impl<S: Simd> core::ops::Deref for mask16x8<S> {
1168 type Target = [i16; 8];
1169 #[inline(always)]
1170 fn deref(&self) -> &Self::Target {
1171 self.simd.as_array_ref_mask16x8(self)
1172 }
1173}
1174impl<S: Simd> core::ops::DerefMut for mask16x8<S> {
1175 #[inline(always)]
1176 fn deref_mut(&mut self) -> &mut Self::Target {
1177 self.simd.as_array_mut_mask16x8(self)
1178 }
1179}
1180impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask16x8<S> {
1181 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1182 crate::support::simd_debug_impl(
1183 f,
1184 "mask16x8",
1185 &self.simd,
1186 self.simd.as_array_ref_mask16x8(self),
1187 )
1188 }
1189}
1190impl<S: Simd> SimdFrom<i16, S> for mask16x8<S> {
1191 #[inline(always)]
1192 fn simd_from(simd: S, value: i16) -> Self {
1193 simd.splat_mask16x8(value)
1194 }
1195}
1196impl<S: Simd> core::ops::Index<usize> for mask16x8<S> {
1197 type Output = i16;
1198 #[inline(always)]
1199 fn index(&self, i: usize) -> &Self::Output {
1200 &self.simd.as_array_ref_mask16x8(self)[i]
1201 }
1202}
1203impl<S: Simd> core::ops::IndexMut<usize> for mask16x8<S> {
1204 #[inline(always)]
1205 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
1206 &mut self.simd.as_array_mut_mask16x8(self)[i]
1207 }
1208}
1209impl<S: Simd> Select<mask16x8<S>> for mask16x8<S> {
1210 #[inline(always)]
1211 fn select(self, if_true: mask16x8<S>, if_false: mask16x8<S>) -> mask16x8<S> {
1212 self.simd.select_mask16x8(self, if_true, if_false)
1213 }
1214}
1215impl<S: Simd> Bytes for mask16x8<S> {
1216 type Bytes = u8x16<S>;
1217 #[inline(always)]
1218 fn to_bytes(self) -> Self::Bytes {
1219 self.simd.cvt_to_bytes_mask16x8(self)
1220 }
1221 #[inline(always)]
1222 fn from_bytes(value: Self::Bytes) -> Self {
1223 value.simd.cvt_from_bytes_mask16x8(value)
1224 }
1225}
1226impl<S: Simd> SimdBase<S> for mask16x8<S> {
1227 type Element = i16;
1228 const N: usize = 8;
1229 type Mask = mask16x8<S>;
1230 type Block = mask16x8<S>;
1231 type Array = [i16; 8];
1232 #[inline(always)]
1233 fn witness(&self) -> S {
1234 self.simd
1235 }
1236 #[inline(always)]
1237 fn as_slice(&self) -> &[i16] {
1238 self.simd.as_array_ref_mask16x8(self).as_slice()
1239 }
1240 #[inline(always)]
1241 fn as_mut_slice(&mut self) -> &mut [i16] {
1242 self.simd.as_array_mut_mask16x8(self).as_mut_slice()
1243 }
1244 #[inline(always)]
1245 fn from_slice(simd: S, slice: &[i16]) -> Self {
1246 simd.load_array_ref_mask16x8(slice.try_into().unwrap())
1247 }
1248 #[inline(always)]
1249 fn store_slice(&self, slice: &mut [i16]) {
1250 self.simd
1251 .store_array_mask16x8(*self, slice.try_into().unwrap());
1252 }
1253 #[inline(always)]
1254 fn splat(simd: S, val: i16) -> Self {
1255 simd.splat_mask16x8(val)
1256 }
1257 #[inline(always)]
1258 fn block_splat(block: Self::Block) -> Self {
1259 block
1260 }
1261 #[inline(always)]
1262 fn from_fn(simd: S, f: impl FnMut(usize) -> i16) -> Self {
1263 simd.load_array_mask16x8(core::array::from_fn(f))
1264 }
1265 #[inline(always)]
1266 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
1267 self.simd
1268 .slide_mask16x8::<SHIFT>(self, rhs.simd_into(self.simd))
1269 }
1270 #[inline(always)]
1271 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
1272 self.simd
1273 .slide_within_blocks_mask16x8::<SHIFT>(self, rhs.simd_into(self.simd))
1274 }
1275}
1276impl<S: Simd> crate::SimdMask<S> for mask16x8<S> {
1277 #[inline(always)]
1278 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1279 self.simd.simd_eq_mask16x8(self, rhs.simd_into(self.simd))
1280 }
1281 #[inline(always)]
1282 fn any_true(self) -> bool {
1283 self.simd.any_true_mask16x8(self)
1284 }
1285 #[inline(always)]
1286 fn all_true(self) -> bool {
1287 self.simd.all_true_mask16x8(self)
1288 }
1289 #[inline(always)]
1290 fn any_false(self) -> bool {
1291 self.simd.any_false_mask16x8(self)
1292 }
1293 #[inline(always)]
1294 fn all_false(self) -> bool {
1295 self.simd.all_false_mask16x8(self)
1296 }
1297}
1298impl<S: Simd> crate::SimdCombine<S> for mask16x8<S> {
1299 type Combined = mask16x16<S>;
1300 #[inline(always)]
1301 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
1302 self.simd.combine_mask16x8(self, rhs.simd_into(self.simd))
1303 }
1304}
1305#[doc = "A SIMD vector of 4 [`i32`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, i32x4};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = i32x4::splat(simd, 1);\n let b = i32x4::simd_from(simd, 1);\n\n // From a slice:\n let c = i32x4::from_slice(simd, &[1, 2, 3, 4]);\n\n // From an array:\n let d = i32x4::simd_from(simd, [1, 2, 3, 4]);\n\n // From an element-wise function:\n let e = i32x4::from_fn(simd, |i| i as i32);\n}\n```"]
1306#[derive(Clone, Copy)]
1307#[repr(C, align(16))]
1308pub struct i32x4<S: Simd> {
1309 pub(crate) val: S::i32x4,
1310 pub simd: S,
1311}
1312impl<S: Simd> SimdFrom<[i32; 4], S> for i32x4<S> {
1313 #[inline(always)]
1314 fn simd_from(simd: S, val: [i32; 4]) -> Self {
1315 simd.load_array_i32x4(val)
1316 }
1317}
1318impl<S: Simd> From<i32x4<S>> for [i32; 4] {
1319 #[inline(always)]
1320 fn from(value: i32x4<S>) -> Self {
1321 value.simd.as_array_i32x4(value)
1322 }
1323}
1324impl<S: Simd> core::ops::Deref for i32x4<S> {
1325 type Target = [i32; 4];
1326 #[inline(always)]
1327 fn deref(&self) -> &Self::Target {
1328 self.simd.as_array_ref_i32x4(self)
1329 }
1330}
1331impl<S: Simd> core::ops::DerefMut for i32x4<S> {
1332 #[inline(always)]
1333 fn deref_mut(&mut self) -> &mut Self::Target {
1334 self.simd.as_array_mut_i32x4(self)
1335 }
1336}
1337impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i32x4<S> {
1338 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1339 crate::support::simd_debug_impl(f, "i32x4", &self.simd, self.simd.as_array_ref_i32x4(self))
1340 }
1341}
1342impl<S: Simd> SimdFrom<i32, S> for i32x4<S> {
1343 #[inline(always)]
1344 fn simd_from(simd: S, value: i32) -> Self {
1345 simd.splat_i32x4(value)
1346 }
1347}
1348impl<S: Simd> core::ops::Index<usize> for i32x4<S> {
1349 type Output = i32;
1350 #[inline(always)]
1351 fn index(&self, i: usize) -> &Self::Output {
1352 &self.simd.as_array_ref_i32x4(self)[i]
1353 }
1354}
1355impl<S: Simd> core::ops::IndexMut<usize> for i32x4<S> {
1356 #[inline(always)]
1357 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
1358 &mut self.simd.as_array_mut_i32x4(self)[i]
1359 }
1360}
1361impl<S: Simd> Select<i32x4<S>> for mask32x4<S> {
1362 #[inline(always)]
1363 fn select(self, if_true: i32x4<S>, if_false: i32x4<S>) -> i32x4<S> {
1364 self.simd.select_i32x4(self, if_true, if_false)
1365 }
1366}
1367impl<S: Simd> Bytes for i32x4<S> {
1368 type Bytes = u8x16<S>;
1369 #[inline(always)]
1370 fn to_bytes(self) -> Self::Bytes {
1371 self.simd.cvt_to_bytes_i32x4(self)
1372 }
1373 #[inline(always)]
1374 fn from_bytes(value: Self::Bytes) -> Self {
1375 value.simd.cvt_from_bytes_i32x4(value)
1376 }
1377}
1378impl<S: Simd> SimdBase<S> for i32x4<S> {
1379 type Element = i32;
1380 const N: usize = 4;
1381 type Mask = mask32x4<S>;
1382 type Block = i32x4<S>;
1383 type Array = [i32; 4];
1384 #[inline(always)]
1385 fn witness(&self) -> S {
1386 self.simd
1387 }
1388 #[inline(always)]
1389 fn as_slice(&self) -> &[i32] {
1390 self.simd.as_array_ref_i32x4(self).as_slice()
1391 }
1392 #[inline(always)]
1393 fn as_mut_slice(&mut self) -> &mut [i32] {
1394 self.simd.as_array_mut_i32x4(self).as_mut_slice()
1395 }
1396 #[inline(always)]
1397 fn from_slice(simd: S, slice: &[i32]) -> Self {
1398 simd.load_array_ref_i32x4(slice.try_into().unwrap())
1399 }
1400 #[inline(always)]
1401 fn store_slice(&self, slice: &mut [i32]) {
1402 self.simd
1403 .store_array_i32x4(*self, slice.try_into().unwrap());
1404 }
1405 #[inline(always)]
1406 fn splat(simd: S, val: i32) -> Self {
1407 simd.splat_i32x4(val)
1408 }
1409 #[inline(always)]
1410 fn block_splat(block: Self::Block) -> Self {
1411 block
1412 }
1413 #[inline(always)]
1414 fn from_fn(simd: S, f: impl FnMut(usize) -> i32) -> Self {
1415 simd.load_array_i32x4(core::array::from_fn(f))
1416 }
1417 #[inline(always)]
1418 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
1419 self.simd
1420 .slide_i32x4::<SHIFT>(self, rhs.simd_into(self.simd))
1421 }
1422 #[inline(always)]
1423 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
1424 self.simd
1425 .slide_within_blocks_i32x4::<SHIFT>(self, rhs.simd_into(self.simd))
1426 }
1427}
1428impl<S: Simd> crate::SimdInt<S> for i32x4<S> {
1429 #[inline(always)]
1430 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1431 self.simd.simd_eq_i32x4(self, rhs.simd_into(self.simd))
1432 }
1433 #[inline(always)]
1434 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1435 self.simd.simd_lt_i32x4(self, rhs.simd_into(self.simd))
1436 }
1437 #[inline(always)]
1438 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1439 self.simd.simd_le_i32x4(self, rhs.simd_into(self.simd))
1440 }
1441 #[inline(always)]
1442 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1443 self.simd.simd_ge_i32x4(self, rhs.simd_into(self.simd))
1444 }
1445 #[inline(always)]
1446 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1447 self.simd.simd_gt_i32x4(self, rhs.simd_into(self.simd))
1448 }
1449 #[inline(always)]
1450 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
1451 self.simd.zip_low_i32x4(self, rhs.simd_into(self.simd))
1452 }
1453 #[inline(always)]
1454 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
1455 self.simd.zip_high_i32x4(self, rhs.simd_into(self.simd))
1456 }
1457 #[inline(always)]
1458 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
1459 self.simd.unzip_low_i32x4(self, rhs.simd_into(self.simd))
1460 }
1461 #[inline(always)]
1462 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
1463 self.simd.unzip_high_i32x4(self, rhs.simd_into(self.simd))
1464 }
1465 #[inline(always)]
1466 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
1467 self.simd.interleave_i32x4(self, rhs.simd_into(self.simd))
1468 }
1469 #[inline(always)]
1470 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
1471 self.simd.deinterleave_i32x4(self, rhs.simd_into(self.simd))
1472 }
1473 #[inline(always)]
1474 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
1475 self.simd.min_i32x4(self, rhs.simd_into(self.simd))
1476 }
1477 #[inline(always)]
1478 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
1479 self.simd.max_i32x4(self, rhs.simd_into(self.simd))
1480 }
1481}
1482impl<S: Simd> SimdCvtTruncate<f32x4<S>> for i32x4<S> {
1483 #[doc = "Convert each floating-point element to a signed 32-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
1484 #[inline(always)]
1485 fn truncate_from(x: f32x4<S>) -> Self {
1486 x.simd.cvt_i32_f32x4(x)
1487 }
1488 #[doc = "Convert each floating-point element to a signed 32-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
1489 #[inline(always)]
1490 fn truncate_from_precise(x: f32x4<S>) -> Self {
1491 x.simd.cvt_i32_precise_f32x4(x)
1492 }
1493}
1494impl<S: Simd> crate::SimdCombine<S> for i32x4<S> {
1495 type Combined = i32x8<S>;
1496 #[inline(always)]
1497 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
1498 self.simd.combine_i32x4(self, rhs.simd_into(self.simd))
1499 }
1500}
1501#[doc = "A SIMD vector of 4 [`u32`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, u32x4};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = u32x4::splat(simd, 1);\n let b = u32x4::simd_from(simd, 1);\n\n // From a slice:\n let c = u32x4::from_slice(simd, &[1, 2, 3, 4]);\n\n // From an array:\n let d = u32x4::simd_from(simd, [1, 2, 3, 4]);\n\n // From an element-wise function:\n let e = u32x4::from_fn(simd, |i| i as u32);\n}\n```"]
1502#[derive(Clone, Copy)]
1503#[repr(C, align(16))]
1504pub struct u32x4<S: Simd> {
1505 pub(crate) val: S::u32x4,
1506 pub simd: S,
1507}
1508impl<S: Simd> SimdFrom<[u32; 4], S> for u32x4<S> {
1509 #[inline(always)]
1510 fn simd_from(simd: S, val: [u32; 4]) -> Self {
1511 simd.load_array_u32x4(val)
1512 }
1513}
1514impl<S: Simd> From<u32x4<S>> for [u32; 4] {
1515 #[inline(always)]
1516 fn from(value: u32x4<S>) -> Self {
1517 value.simd.as_array_u32x4(value)
1518 }
1519}
1520impl<S: Simd> core::ops::Deref for u32x4<S> {
1521 type Target = [u32; 4];
1522 #[inline(always)]
1523 fn deref(&self) -> &Self::Target {
1524 self.simd.as_array_ref_u32x4(self)
1525 }
1526}
1527impl<S: Simd> core::ops::DerefMut for u32x4<S> {
1528 #[inline(always)]
1529 fn deref_mut(&mut self) -> &mut Self::Target {
1530 self.simd.as_array_mut_u32x4(self)
1531 }
1532}
1533impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u32x4<S> {
1534 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1535 crate::support::simd_debug_impl(f, "u32x4", &self.simd, self.simd.as_array_ref_u32x4(self))
1536 }
1537}
1538impl<S: Simd> SimdFrom<u32, S> for u32x4<S> {
1539 #[inline(always)]
1540 fn simd_from(simd: S, value: u32) -> Self {
1541 simd.splat_u32x4(value)
1542 }
1543}
1544impl<S: Simd> core::ops::Index<usize> for u32x4<S> {
1545 type Output = u32;
1546 #[inline(always)]
1547 fn index(&self, i: usize) -> &Self::Output {
1548 &self.simd.as_array_ref_u32x4(self)[i]
1549 }
1550}
1551impl<S: Simd> core::ops::IndexMut<usize> for u32x4<S> {
1552 #[inline(always)]
1553 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
1554 &mut self.simd.as_array_mut_u32x4(self)[i]
1555 }
1556}
1557impl<S: Simd> Select<u32x4<S>> for mask32x4<S> {
1558 #[inline(always)]
1559 fn select(self, if_true: u32x4<S>, if_false: u32x4<S>) -> u32x4<S> {
1560 self.simd.select_u32x4(self, if_true, if_false)
1561 }
1562}
1563impl<S: Simd> Bytes for u32x4<S> {
1564 type Bytes = u8x16<S>;
1565 #[inline(always)]
1566 fn to_bytes(self) -> Self::Bytes {
1567 self.simd.cvt_to_bytes_u32x4(self)
1568 }
1569 #[inline(always)]
1570 fn from_bytes(value: Self::Bytes) -> Self {
1571 value.simd.cvt_from_bytes_u32x4(value)
1572 }
1573}
1574impl<S: Simd> SimdBase<S> for u32x4<S> {
1575 type Element = u32;
1576 const N: usize = 4;
1577 type Mask = mask32x4<S>;
1578 type Block = u32x4<S>;
1579 type Array = [u32; 4];
1580 #[inline(always)]
1581 fn witness(&self) -> S {
1582 self.simd
1583 }
1584 #[inline(always)]
1585 fn as_slice(&self) -> &[u32] {
1586 self.simd.as_array_ref_u32x4(self).as_slice()
1587 }
1588 #[inline(always)]
1589 fn as_mut_slice(&mut self) -> &mut [u32] {
1590 self.simd.as_array_mut_u32x4(self).as_mut_slice()
1591 }
1592 #[inline(always)]
1593 fn from_slice(simd: S, slice: &[u32]) -> Self {
1594 simd.load_array_ref_u32x4(slice.try_into().unwrap())
1595 }
1596 #[inline(always)]
1597 fn store_slice(&self, slice: &mut [u32]) {
1598 self.simd
1599 .store_array_u32x4(*self, slice.try_into().unwrap());
1600 }
1601 #[inline(always)]
1602 fn splat(simd: S, val: u32) -> Self {
1603 simd.splat_u32x4(val)
1604 }
1605 #[inline(always)]
1606 fn block_splat(block: Self::Block) -> Self {
1607 block
1608 }
1609 #[inline(always)]
1610 fn from_fn(simd: S, f: impl FnMut(usize) -> u32) -> Self {
1611 simd.load_array_u32x4(core::array::from_fn(f))
1612 }
1613 #[inline(always)]
1614 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
1615 self.simd
1616 .slide_u32x4::<SHIFT>(self, rhs.simd_into(self.simd))
1617 }
1618 #[inline(always)]
1619 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
1620 self.simd
1621 .slide_within_blocks_u32x4::<SHIFT>(self, rhs.simd_into(self.simd))
1622 }
1623}
1624impl<S: Simd> crate::SimdInt<S> for u32x4<S> {
1625 #[inline(always)]
1626 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1627 self.simd.simd_eq_u32x4(self, rhs.simd_into(self.simd))
1628 }
1629 #[inline(always)]
1630 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1631 self.simd.simd_lt_u32x4(self, rhs.simd_into(self.simd))
1632 }
1633 #[inline(always)]
1634 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1635 self.simd.simd_le_u32x4(self, rhs.simd_into(self.simd))
1636 }
1637 #[inline(always)]
1638 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1639 self.simd.simd_ge_u32x4(self, rhs.simd_into(self.simd))
1640 }
1641 #[inline(always)]
1642 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1643 self.simd.simd_gt_u32x4(self, rhs.simd_into(self.simd))
1644 }
1645 #[inline(always)]
1646 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
1647 self.simd.zip_low_u32x4(self, rhs.simd_into(self.simd))
1648 }
1649 #[inline(always)]
1650 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
1651 self.simd.zip_high_u32x4(self, rhs.simd_into(self.simd))
1652 }
1653 #[inline(always)]
1654 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
1655 self.simd.unzip_low_u32x4(self, rhs.simd_into(self.simd))
1656 }
1657 #[inline(always)]
1658 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
1659 self.simd.unzip_high_u32x4(self, rhs.simd_into(self.simd))
1660 }
1661 #[inline(always)]
1662 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
1663 self.simd.interleave_u32x4(self, rhs.simd_into(self.simd))
1664 }
1665 #[inline(always)]
1666 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
1667 self.simd.deinterleave_u32x4(self, rhs.simd_into(self.simd))
1668 }
1669 #[inline(always)]
1670 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
1671 self.simd.min_u32x4(self, rhs.simd_into(self.simd))
1672 }
1673 #[inline(always)]
1674 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
1675 self.simd.max_u32x4(self, rhs.simd_into(self.simd))
1676 }
1677}
1678impl<S: Simd> SimdCvtTruncate<f32x4<S>> for u32x4<S> {
1679 #[doc = "Convert each floating-point element to an unsigned 32-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results.\n\nOn x86 platforms, this operation will still be slower than converting to `i32`, because there is no native instruction for converting to `u32` (at least until AVX-512, which is currently not supported).\nIf you know your values fit within range of an `i32`, you should convert to an `i32` and cast to your desired datatype afterwards."]
1680 #[inline(always)]
1681 fn truncate_from(x: f32x4<S>) -> Self {
1682 x.simd.cvt_u32_f32x4(x)
1683 }
1684 #[doc = "Convert each floating-point element to an unsigned 32-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
1685 #[inline(always)]
1686 fn truncate_from_precise(x: f32x4<S>) -> Self {
1687 x.simd.cvt_u32_precise_f32x4(x)
1688 }
1689}
1690impl<S: Simd> crate::SimdCombine<S> for u32x4<S> {
1691 type Combined = u32x8<S>;
1692 #[inline(always)]
1693 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
1694 self.simd.combine_u32x4(self, rhs.simd_into(self.simd))
1695 }
1696}
1697#[doc = "A SIMD mask of 4 32-bit elements.\n\nWhen created from a comparison operation, and as it should be used in a [`Self::select`] operation, each element will be all ones if it's \"true\", and all zeroes if it's \"false\"."]
1698#[derive(Clone, Copy)]
1699#[repr(C, align(16))]
1700pub struct mask32x4<S: Simd> {
1701 pub(crate) val: S::mask32x4,
1702 pub simd: S,
1703}
1704impl<S: Simd> SimdFrom<[i32; 4], S> for mask32x4<S> {
1705 #[inline(always)]
1706 fn simd_from(simd: S, val: [i32; 4]) -> Self {
1707 simd.load_array_mask32x4(val)
1708 }
1709}
1710impl<S: Simd> From<mask32x4<S>> for [i32; 4] {
1711 #[inline(always)]
1712 fn from(value: mask32x4<S>) -> Self {
1713 value.simd.as_array_mask32x4(value)
1714 }
1715}
1716impl<S: Simd> core::ops::Deref for mask32x4<S> {
1717 type Target = [i32; 4];
1718 #[inline(always)]
1719 fn deref(&self) -> &Self::Target {
1720 self.simd.as_array_ref_mask32x4(self)
1721 }
1722}
1723impl<S: Simd> core::ops::DerefMut for mask32x4<S> {
1724 #[inline(always)]
1725 fn deref_mut(&mut self) -> &mut Self::Target {
1726 self.simd.as_array_mut_mask32x4(self)
1727 }
1728}
1729impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask32x4<S> {
1730 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1731 crate::support::simd_debug_impl(
1732 f,
1733 "mask32x4",
1734 &self.simd,
1735 self.simd.as_array_ref_mask32x4(self),
1736 )
1737 }
1738}
1739impl<S: Simd> SimdFrom<i32, S> for mask32x4<S> {
1740 #[inline(always)]
1741 fn simd_from(simd: S, value: i32) -> Self {
1742 simd.splat_mask32x4(value)
1743 }
1744}
1745impl<S: Simd> core::ops::Index<usize> for mask32x4<S> {
1746 type Output = i32;
1747 #[inline(always)]
1748 fn index(&self, i: usize) -> &Self::Output {
1749 &self.simd.as_array_ref_mask32x4(self)[i]
1750 }
1751}
1752impl<S: Simd> core::ops::IndexMut<usize> for mask32x4<S> {
1753 #[inline(always)]
1754 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
1755 &mut self.simd.as_array_mut_mask32x4(self)[i]
1756 }
1757}
1758impl<S: Simd> Select<mask32x4<S>> for mask32x4<S> {
1759 #[inline(always)]
1760 fn select(self, if_true: mask32x4<S>, if_false: mask32x4<S>) -> mask32x4<S> {
1761 self.simd.select_mask32x4(self, if_true, if_false)
1762 }
1763}
1764impl<S: Simd> Bytes for mask32x4<S> {
1765 type Bytes = u8x16<S>;
1766 #[inline(always)]
1767 fn to_bytes(self) -> Self::Bytes {
1768 self.simd.cvt_to_bytes_mask32x4(self)
1769 }
1770 #[inline(always)]
1771 fn from_bytes(value: Self::Bytes) -> Self {
1772 value.simd.cvt_from_bytes_mask32x4(value)
1773 }
1774}
1775impl<S: Simd> SimdBase<S> for mask32x4<S> {
1776 type Element = i32;
1777 const N: usize = 4;
1778 type Mask = mask32x4<S>;
1779 type Block = mask32x4<S>;
1780 type Array = [i32; 4];
1781 #[inline(always)]
1782 fn witness(&self) -> S {
1783 self.simd
1784 }
1785 #[inline(always)]
1786 fn as_slice(&self) -> &[i32] {
1787 self.simd.as_array_ref_mask32x4(self).as_slice()
1788 }
1789 #[inline(always)]
1790 fn as_mut_slice(&mut self) -> &mut [i32] {
1791 self.simd.as_array_mut_mask32x4(self).as_mut_slice()
1792 }
1793 #[inline(always)]
1794 fn from_slice(simd: S, slice: &[i32]) -> Self {
1795 simd.load_array_ref_mask32x4(slice.try_into().unwrap())
1796 }
1797 #[inline(always)]
1798 fn store_slice(&self, slice: &mut [i32]) {
1799 self.simd
1800 .store_array_mask32x4(*self, slice.try_into().unwrap());
1801 }
1802 #[inline(always)]
1803 fn splat(simd: S, val: i32) -> Self {
1804 simd.splat_mask32x4(val)
1805 }
1806 #[inline(always)]
1807 fn block_splat(block: Self::Block) -> Self {
1808 block
1809 }
1810 #[inline(always)]
1811 fn from_fn(simd: S, f: impl FnMut(usize) -> i32) -> Self {
1812 simd.load_array_mask32x4(core::array::from_fn(f))
1813 }
1814 #[inline(always)]
1815 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
1816 self.simd
1817 .slide_mask32x4::<SHIFT>(self, rhs.simd_into(self.simd))
1818 }
1819 #[inline(always)]
1820 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
1821 self.simd
1822 .slide_within_blocks_mask32x4::<SHIFT>(self, rhs.simd_into(self.simd))
1823 }
1824}
1825impl<S: Simd> crate::SimdMask<S> for mask32x4<S> {
1826 #[inline(always)]
1827 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1828 self.simd.simd_eq_mask32x4(self, rhs.simd_into(self.simd))
1829 }
1830 #[inline(always)]
1831 fn any_true(self) -> bool {
1832 self.simd.any_true_mask32x4(self)
1833 }
1834 #[inline(always)]
1835 fn all_true(self) -> bool {
1836 self.simd.all_true_mask32x4(self)
1837 }
1838 #[inline(always)]
1839 fn any_false(self) -> bool {
1840 self.simd.any_false_mask32x4(self)
1841 }
1842 #[inline(always)]
1843 fn all_false(self) -> bool {
1844 self.simd.all_false_mask32x4(self)
1845 }
1846}
1847impl<S: Simd> crate::SimdCombine<S> for mask32x4<S> {
1848 type Combined = mask32x8<S>;
1849 #[inline(always)]
1850 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
1851 self.simd.combine_mask32x4(self, rhs.simd_into(self.simd))
1852 }
1853}
1854#[doc = "A SIMD vector of 2 [`f64`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, f64x2};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = f64x2::splat(simd, 1.0);\n let b = f64x2::simd_from(simd, 1.0);\n\n // From a slice:\n let c = f64x2::from_slice(simd, &[1.0, 2.0]);\n\n // From an array:\n let d = f64x2::simd_from(simd, [1.0, 2.0]);\n\n // From an element-wise function:\n let e = f64x2::from_fn(simd, |i| i as f64);\n}\n```"]
1855#[derive(Clone, Copy)]
1856#[repr(C, align(16))]
1857pub struct f64x2<S: Simd> {
1858 pub(crate) val: S::f64x2,
1859 pub simd: S,
1860}
1861impl<S: Simd> SimdFrom<[f64; 2], S> for f64x2<S> {
1862 #[inline(always)]
1863 fn simd_from(simd: S, val: [f64; 2]) -> Self {
1864 simd.load_array_f64x2(val)
1865 }
1866}
1867impl<S: Simd> From<f64x2<S>> for [f64; 2] {
1868 #[inline(always)]
1869 fn from(value: f64x2<S>) -> Self {
1870 value.simd.as_array_f64x2(value)
1871 }
1872}
1873impl<S: Simd> core::ops::Deref for f64x2<S> {
1874 type Target = [f64; 2];
1875 #[inline(always)]
1876 fn deref(&self) -> &Self::Target {
1877 self.simd.as_array_ref_f64x2(self)
1878 }
1879}
1880impl<S: Simd> core::ops::DerefMut for f64x2<S> {
1881 #[inline(always)]
1882 fn deref_mut(&mut self) -> &mut Self::Target {
1883 self.simd.as_array_mut_f64x2(self)
1884 }
1885}
1886impl<S: Simd + core::fmt::Debug> core::fmt::Debug for f64x2<S> {
1887 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1888 crate::support::simd_debug_impl(f, "f64x2", &self.simd, self.simd.as_array_ref_f64x2(self))
1889 }
1890}
1891impl<S: Simd> SimdFrom<f64, S> for f64x2<S> {
1892 #[inline(always)]
1893 fn simd_from(simd: S, value: f64) -> Self {
1894 simd.splat_f64x2(value)
1895 }
1896}
1897impl<S: Simd> core::ops::Index<usize> for f64x2<S> {
1898 type Output = f64;
1899 #[inline(always)]
1900 fn index(&self, i: usize) -> &Self::Output {
1901 &self.simd.as_array_ref_f64x2(self)[i]
1902 }
1903}
1904impl<S: Simd> core::ops::IndexMut<usize> for f64x2<S> {
1905 #[inline(always)]
1906 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
1907 &mut self.simd.as_array_mut_f64x2(self)[i]
1908 }
1909}
1910impl<S: Simd> Select<f64x2<S>> for mask64x2<S> {
1911 #[inline(always)]
1912 fn select(self, if_true: f64x2<S>, if_false: f64x2<S>) -> f64x2<S> {
1913 self.simd.select_f64x2(self, if_true, if_false)
1914 }
1915}
1916impl<S: Simd> Bytes for f64x2<S> {
1917 type Bytes = u8x16<S>;
1918 #[inline(always)]
1919 fn to_bytes(self) -> Self::Bytes {
1920 self.simd.cvt_to_bytes_f64x2(self)
1921 }
1922 #[inline(always)]
1923 fn from_bytes(value: Self::Bytes) -> Self {
1924 value.simd.cvt_from_bytes_f64x2(value)
1925 }
1926}
1927impl<S: Simd> SimdBase<S> for f64x2<S> {
1928 type Element = f64;
1929 const N: usize = 2;
1930 type Mask = mask64x2<S>;
1931 type Block = f64x2<S>;
1932 type Array = [f64; 2];
1933 #[inline(always)]
1934 fn witness(&self) -> S {
1935 self.simd
1936 }
1937 #[inline(always)]
1938 fn as_slice(&self) -> &[f64] {
1939 self.simd.as_array_ref_f64x2(self).as_slice()
1940 }
1941 #[inline(always)]
1942 fn as_mut_slice(&mut self) -> &mut [f64] {
1943 self.simd.as_array_mut_f64x2(self).as_mut_slice()
1944 }
1945 #[inline(always)]
1946 fn from_slice(simd: S, slice: &[f64]) -> Self {
1947 simd.load_array_ref_f64x2(slice.try_into().unwrap())
1948 }
1949 #[inline(always)]
1950 fn store_slice(&self, slice: &mut [f64]) {
1951 self.simd
1952 .store_array_f64x2(*self, slice.try_into().unwrap());
1953 }
1954 #[inline(always)]
1955 fn splat(simd: S, val: f64) -> Self {
1956 simd.splat_f64x2(val)
1957 }
1958 #[inline(always)]
1959 fn block_splat(block: Self::Block) -> Self {
1960 block
1961 }
1962 #[inline(always)]
1963 fn from_fn(simd: S, f: impl FnMut(usize) -> f64) -> Self {
1964 simd.load_array_f64x2(core::array::from_fn(f))
1965 }
1966 #[inline(always)]
1967 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
1968 self.simd
1969 .slide_f64x2::<SHIFT>(self, rhs.simd_into(self.simd))
1970 }
1971 #[inline(always)]
1972 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
1973 self.simd
1974 .slide_within_blocks_f64x2::<SHIFT>(self, rhs.simd_into(self.simd))
1975 }
1976}
1977impl<S: Simd> crate::SimdFloat<S> for f64x2<S> {
1978 #[inline(always)]
1979 fn abs(self) -> Self {
1980 self.simd.abs_f64x2(self)
1981 }
1982 #[inline(always)]
1983 fn sqrt(self) -> Self {
1984 self.simd.sqrt_f64x2(self)
1985 }
1986 #[inline(always)]
1987 fn copysign(self, rhs: impl SimdInto<Self, S>) -> Self {
1988 self.simd.copysign_f64x2(self, rhs.simd_into(self.simd))
1989 }
1990 #[inline(always)]
1991 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1992 self.simd.simd_eq_f64x2(self, rhs.simd_into(self.simd))
1993 }
1994 #[inline(always)]
1995 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1996 self.simd.simd_lt_f64x2(self, rhs.simd_into(self.simd))
1997 }
1998 #[inline(always)]
1999 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2000 self.simd.simd_le_f64x2(self, rhs.simd_into(self.simd))
2001 }
2002 #[inline(always)]
2003 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2004 self.simd.simd_ge_f64x2(self, rhs.simd_into(self.simd))
2005 }
2006 #[inline(always)]
2007 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2008 self.simd.simd_gt_f64x2(self, rhs.simd_into(self.simd))
2009 }
2010 #[inline(always)]
2011 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
2012 self.simd.zip_low_f64x2(self, rhs.simd_into(self.simd))
2013 }
2014 #[inline(always)]
2015 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
2016 self.simd.zip_high_f64x2(self, rhs.simd_into(self.simd))
2017 }
2018 #[inline(always)]
2019 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
2020 self.simd.unzip_low_f64x2(self, rhs.simd_into(self.simd))
2021 }
2022 #[inline(always)]
2023 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
2024 self.simd.unzip_high_f64x2(self, rhs.simd_into(self.simd))
2025 }
2026 #[inline(always)]
2027 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
2028 self.simd.interleave_f64x2(self, rhs.simd_into(self.simd))
2029 }
2030 #[inline(always)]
2031 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
2032 self.simd.deinterleave_f64x2(self, rhs.simd_into(self.simd))
2033 }
2034 #[inline(always)]
2035 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
2036 self.simd.max_f64x2(self, rhs.simd_into(self.simd))
2037 }
2038 #[inline(always)]
2039 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
2040 self.simd.min_f64x2(self, rhs.simd_into(self.simd))
2041 }
2042 #[inline(always)]
2043 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
2044 self.simd.max_precise_f64x2(self, rhs.simd_into(self.simd))
2045 }
2046 #[inline(always)]
2047 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
2048 self.simd.min_precise_f64x2(self, rhs.simd_into(self.simd))
2049 }
2050 #[inline(always)]
2051 fn mul_add(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
2052 self.simd
2053 .mul_add_f64x2(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
2054 }
2055 #[inline(always)]
2056 fn mul_sub(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
2057 self.simd
2058 .mul_sub_f64x2(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
2059 }
2060 #[inline(always)]
2061 fn floor(self) -> Self {
2062 self.simd.floor_f64x2(self)
2063 }
2064 #[inline(always)]
2065 fn ceil(self) -> Self {
2066 self.simd.ceil_f64x2(self)
2067 }
2068 #[inline(always)]
2069 fn round_ties_even(self) -> Self {
2070 self.simd.round_ties_even_f64x2(self)
2071 }
2072 #[inline(always)]
2073 fn fract(self) -> Self {
2074 self.simd.fract_f64x2(self)
2075 }
2076 #[inline(always)]
2077 fn trunc(self) -> Self {
2078 self.simd.trunc_f64x2(self)
2079 }
2080}
2081impl<S: Simd> crate::SimdCombine<S> for f64x2<S> {
2082 type Combined = f64x4<S>;
2083 #[inline(always)]
2084 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
2085 self.simd.combine_f64x2(self, rhs.simd_into(self.simd))
2086 }
2087}
2088#[doc = "A SIMD mask of 2 64-bit elements.\n\nWhen created from a comparison operation, and as it should be used in a [`Self::select`] operation, each element will be all ones if it's \"true\", and all zeroes if it's \"false\"."]
2089#[derive(Clone, Copy)]
2090#[repr(C, align(16))]
2091pub struct mask64x2<S: Simd> {
2092 pub(crate) val: S::mask64x2,
2093 pub simd: S,
2094}
2095impl<S: Simd> SimdFrom<[i64; 2], S> for mask64x2<S> {
2096 #[inline(always)]
2097 fn simd_from(simd: S, val: [i64; 2]) -> Self {
2098 simd.load_array_mask64x2(val)
2099 }
2100}
2101impl<S: Simd> From<mask64x2<S>> for [i64; 2] {
2102 #[inline(always)]
2103 fn from(value: mask64x2<S>) -> Self {
2104 value.simd.as_array_mask64x2(value)
2105 }
2106}
2107impl<S: Simd> core::ops::Deref for mask64x2<S> {
2108 type Target = [i64; 2];
2109 #[inline(always)]
2110 fn deref(&self) -> &Self::Target {
2111 self.simd.as_array_ref_mask64x2(self)
2112 }
2113}
2114impl<S: Simd> core::ops::DerefMut for mask64x2<S> {
2115 #[inline(always)]
2116 fn deref_mut(&mut self) -> &mut Self::Target {
2117 self.simd.as_array_mut_mask64x2(self)
2118 }
2119}
2120impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask64x2<S> {
2121 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2122 crate::support::simd_debug_impl(
2123 f,
2124 "mask64x2",
2125 &self.simd,
2126 self.simd.as_array_ref_mask64x2(self),
2127 )
2128 }
2129}
2130impl<S: Simd> SimdFrom<i64, S> for mask64x2<S> {
2131 #[inline(always)]
2132 fn simd_from(simd: S, value: i64) -> Self {
2133 simd.splat_mask64x2(value)
2134 }
2135}
2136impl<S: Simd> core::ops::Index<usize> for mask64x2<S> {
2137 type Output = i64;
2138 #[inline(always)]
2139 fn index(&self, i: usize) -> &Self::Output {
2140 &self.simd.as_array_ref_mask64x2(self)[i]
2141 }
2142}
2143impl<S: Simd> core::ops::IndexMut<usize> for mask64x2<S> {
2144 #[inline(always)]
2145 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
2146 &mut self.simd.as_array_mut_mask64x2(self)[i]
2147 }
2148}
2149impl<S: Simd> Select<mask64x2<S>> for mask64x2<S> {
2150 #[inline(always)]
2151 fn select(self, if_true: mask64x2<S>, if_false: mask64x2<S>) -> mask64x2<S> {
2152 self.simd.select_mask64x2(self, if_true, if_false)
2153 }
2154}
2155impl<S: Simd> Bytes for mask64x2<S> {
2156 type Bytes = u8x16<S>;
2157 #[inline(always)]
2158 fn to_bytes(self) -> Self::Bytes {
2159 self.simd.cvt_to_bytes_mask64x2(self)
2160 }
2161 #[inline(always)]
2162 fn from_bytes(value: Self::Bytes) -> Self {
2163 value.simd.cvt_from_bytes_mask64x2(value)
2164 }
2165}
2166impl<S: Simd> SimdBase<S> for mask64x2<S> {
2167 type Element = i64;
2168 const N: usize = 2;
2169 type Mask = mask64x2<S>;
2170 type Block = mask64x2<S>;
2171 type Array = [i64; 2];
2172 #[inline(always)]
2173 fn witness(&self) -> S {
2174 self.simd
2175 }
2176 #[inline(always)]
2177 fn as_slice(&self) -> &[i64] {
2178 self.simd.as_array_ref_mask64x2(self).as_slice()
2179 }
2180 #[inline(always)]
2181 fn as_mut_slice(&mut self) -> &mut [i64] {
2182 self.simd.as_array_mut_mask64x2(self).as_mut_slice()
2183 }
2184 #[inline(always)]
2185 fn from_slice(simd: S, slice: &[i64]) -> Self {
2186 simd.load_array_ref_mask64x2(slice.try_into().unwrap())
2187 }
2188 #[inline(always)]
2189 fn store_slice(&self, slice: &mut [i64]) {
2190 self.simd
2191 .store_array_mask64x2(*self, slice.try_into().unwrap());
2192 }
2193 #[inline(always)]
2194 fn splat(simd: S, val: i64) -> Self {
2195 simd.splat_mask64x2(val)
2196 }
2197 #[inline(always)]
2198 fn block_splat(block: Self::Block) -> Self {
2199 block
2200 }
2201 #[inline(always)]
2202 fn from_fn(simd: S, f: impl FnMut(usize) -> i64) -> Self {
2203 simd.load_array_mask64x2(core::array::from_fn(f))
2204 }
2205 #[inline(always)]
2206 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
2207 self.simd
2208 .slide_mask64x2::<SHIFT>(self, rhs.simd_into(self.simd))
2209 }
2210 #[inline(always)]
2211 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
2212 self.simd
2213 .slide_within_blocks_mask64x2::<SHIFT>(self, rhs.simd_into(self.simd))
2214 }
2215}
2216impl<S: Simd> crate::SimdMask<S> for mask64x2<S> {
2217 #[inline(always)]
2218 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2219 self.simd.simd_eq_mask64x2(self, rhs.simd_into(self.simd))
2220 }
2221 #[inline(always)]
2222 fn any_true(self) -> bool {
2223 self.simd.any_true_mask64x2(self)
2224 }
2225 #[inline(always)]
2226 fn all_true(self) -> bool {
2227 self.simd.all_true_mask64x2(self)
2228 }
2229 #[inline(always)]
2230 fn any_false(self) -> bool {
2231 self.simd.any_false_mask64x2(self)
2232 }
2233 #[inline(always)]
2234 fn all_false(self) -> bool {
2235 self.simd.all_false_mask64x2(self)
2236 }
2237}
2238impl<S: Simd> crate::SimdCombine<S> for mask64x2<S> {
2239 type Combined = mask64x4<S>;
2240 #[inline(always)]
2241 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
2242 self.simd.combine_mask64x2(self, rhs.simd_into(self.simd))
2243 }
2244}
2245#[doc = "A SIMD vector of 8 [`f32`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, f32x8};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = f32x8::splat(simd, 1.0);\n let b = f32x8::simd_from(simd, 1.0);\n\n // From a slice:\n let c = f32x8::from_slice(simd, &[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]);\n\n // From an array:\n let d = f32x8::simd_from(simd, [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]);\n\n // From an element-wise function:\n let e = f32x8::from_fn(simd, |i| i as f32);\n # use fearless_simd::f32x4;\n // From `Self::Block`:\n let f = f32x8::block_splat(f32x4::simd_from(simd, [1.0, 2.0, 3.0, 4.0]));\n}\n```"]
2246#[derive(Clone, Copy)]
2247#[repr(C, align(32))]
2248pub struct f32x8<S: Simd> {
2249 pub(crate) val: S::f32x8,
2250 pub simd: S,
2251}
2252impl<S: Simd> SimdFrom<[f32; 8], S> for f32x8<S> {
2253 #[inline(always)]
2254 fn simd_from(simd: S, val: [f32; 8]) -> Self {
2255 simd.load_array_f32x8(val)
2256 }
2257}
2258impl<S: Simd> From<f32x8<S>> for [f32; 8] {
2259 #[inline(always)]
2260 fn from(value: f32x8<S>) -> Self {
2261 value.simd.as_array_f32x8(value)
2262 }
2263}
2264impl<S: Simd> core::ops::Deref for f32x8<S> {
2265 type Target = [f32; 8];
2266 #[inline(always)]
2267 fn deref(&self) -> &Self::Target {
2268 self.simd.as_array_ref_f32x8(self)
2269 }
2270}
2271impl<S: Simd> core::ops::DerefMut for f32x8<S> {
2272 #[inline(always)]
2273 fn deref_mut(&mut self) -> &mut Self::Target {
2274 self.simd.as_array_mut_f32x8(self)
2275 }
2276}
2277impl<S: Simd + core::fmt::Debug> core::fmt::Debug for f32x8<S> {
2278 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2279 crate::support::simd_debug_impl(f, "f32x8", &self.simd, self.simd.as_array_ref_f32x8(self))
2280 }
2281}
2282impl<S: Simd> SimdFrom<f32, S> for f32x8<S> {
2283 #[inline(always)]
2284 fn simd_from(simd: S, value: f32) -> Self {
2285 simd.splat_f32x8(value)
2286 }
2287}
2288impl<S: Simd> core::ops::Index<usize> for f32x8<S> {
2289 type Output = f32;
2290 #[inline(always)]
2291 fn index(&self, i: usize) -> &Self::Output {
2292 &self.simd.as_array_ref_f32x8(self)[i]
2293 }
2294}
2295impl<S: Simd> core::ops::IndexMut<usize> for f32x8<S> {
2296 #[inline(always)]
2297 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
2298 &mut self.simd.as_array_mut_f32x8(self)[i]
2299 }
2300}
2301impl<S: Simd> Select<f32x8<S>> for mask32x8<S> {
2302 #[inline(always)]
2303 fn select(self, if_true: f32x8<S>, if_false: f32x8<S>) -> f32x8<S> {
2304 self.simd.select_f32x8(self, if_true, if_false)
2305 }
2306}
2307impl<S: Simd> Bytes for f32x8<S> {
2308 type Bytes = u8x32<S>;
2309 #[inline(always)]
2310 fn to_bytes(self) -> Self::Bytes {
2311 self.simd.cvt_to_bytes_f32x8(self)
2312 }
2313 #[inline(always)]
2314 fn from_bytes(value: Self::Bytes) -> Self {
2315 value.simd.cvt_from_bytes_f32x8(value)
2316 }
2317}
2318impl<S: Simd> SimdBase<S> for f32x8<S> {
2319 type Element = f32;
2320 const N: usize = 8;
2321 type Mask = mask32x8<S>;
2322 type Block = f32x4<S>;
2323 type Array = [f32; 8];
2324 #[inline(always)]
2325 fn witness(&self) -> S {
2326 self.simd
2327 }
2328 #[inline(always)]
2329 fn as_slice(&self) -> &[f32] {
2330 self.simd.as_array_ref_f32x8(self).as_slice()
2331 }
2332 #[inline(always)]
2333 fn as_mut_slice(&mut self) -> &mut [f32] {
2334 self.simd.as_array_mut_f32x8(self).as_mut_slice()
2335 }
2336 #[inline(always)]
2337 fn from_slice(simd: S, slice: &[f32]) -> Self {
2338 simd.load_array_ref_f32x8(slice.try_into().unwrap())
2339 }
2340 #[inline(always)]
2341 fn store_slice(&self, slice: &mut [f32]) {
2342 self.simd
2343 .store_array_f32x8(*self, slice.try_into().unwrap());
2344 }
2345 #[inline(always)]
2346 fn splat(simd: S, val: f32) -> Self {
2347 simd.splat_f32x8(val)
2348 }
2349 #[inline(always)]
2350 fn block_splat(block: Self::Block) -> Self {
2351 block.simd.combine_f32x4(block, block)
2352 }
2353 #[inline(always)]
2354 fn from_fn(simd: S, f: impl FnMut(usize) -> f32) -> Self {
2355 simd.load_array_f32x8(core::array::from_fn(f))
2356 }
2357 #[inline(always)]
2358 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
2359 self.simd
2360 .slide_f32x8::<SHIFT>(self, rhs.simd_into(self.simd))
2361 }
2362 #[inline(always)]
2363 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
2364 self.simd
2365 .slide_within_blocks_f32x8::<SHIFT>(self, rhs.simd_into(self.simd))
2366 }
2367}
2368impl<S: Simd> crate::SimdFloat<S> for f32x8<S> {
2369 #[inline(always)]
2370 fn abs(self) -> Self {
2371 self.simd.abs_f32x8(self)
2372 }
2373 #[inline(always)]
2374 fn sqrt(self) -> Self {
2375 self.simd.sqrt_f32x8(self)
2376 }
2377 #[inline(always)]
2378 fn copysign(self, rhs: impl SimdInto<Self, S>) -> Self {
2379 self.simd.copysign_f32x8(self, rhs.simd_into(self.simd))
2380 }
2381 #[inline(always)]
2382 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2383 self.simd.simd_eq_f32x8(self, rhs.simd_into(self.simd))
2384 }
2385 #[inline(always)]
2386 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2387 self.simd.simd_lt_f32x8(self, rhs.simd_into(self.simd))
2388 }
2389 #[inline(always)]
2390 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2391 self.simd.simd_le_f32x8(self, rhs.simd_into(self.simd))
2392 }
2393 #[inline(always)]
2394 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2395 self.simd.simd_ge_f32x8(self, rhs.simd_into(self.simd))
2396 }
2397 #[inline(always)]
2398 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2399 self.simd.simd_gt_f32x8(self, rhs.simd_into(self.simd))
2400 }
2401 #[inline(always)]
2402 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
2403 self.simd.zip_low_f32x8(self, rhs.simd_into(self.simd))
2404 }
2405 #[inline(always)]
2406 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
2407 self.simd.zip_high_f32x8(self, rhs.simd_into(self.simd))
2408 }
2409 #[inline(always)]
2410 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
2411 self.simd.unzip_low_f32x8(self, rhs.simd_into(self.simd))
2412 }
2413 #[inline(always)]
2414 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
2415 self.simd.unzip_high_f32x8(self, rhs.simd_into(self.simd))
2416 }
2417 #[inline(always)]
2418 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
2419 self.simd.interleave_f32x8(self, rhs.simd_into(self.simd))
2420 }
2421 #[inline(always)]
2422 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
2423 self.simd.deinterleave_f32x8(self, rhs.simd_into(self.simd))
2424 }
2425 #[inline(always)]
2426 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
2427 self.simd.max_f32x8(self, rhs.simd_into(self.simd))
2428 }
2429 #[inline(always)]
2430 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
2431 self.simd.min_f32x8(self, rhs.simd_into(self.simd))
2432 }
2433 #[inline(always)]
2434 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
2435 self.simd.max_precise_f32x8(self, rhs.simd_into(self.simd))
2436 }
2437 #[inline(always)]
2438 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
2439 self.simd.min_precise_f32x8(self, rhs.simd_into(self.simd))
2440 }
2441 #[inline(always)]
2442 fn mul_add(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
2443 self.simd
2444 .mul_add_f32x8(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
2445 }
2446 #[inline(always)]
2447 fn mul_sub(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
2448 self.simd
2449 .mul_sub_f32x8(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
2450 }
2451 #[inline(always)]
2452 fn floor(self) -> Self {
2453 self.simd.floor_f32x8(self)
2454 }
2455 #[inline(always)]
2456 fn ceil(self) -> Self {
2457 self.simd.ceil_f32x8(self)
2458 }
2459 #[inline(always)]
2460 fn round_ties_even(self) -> Self {
2461 self.simd.round_ties_even_f32x8(self)
2462 }
2463 #[inline(always)]
2464 fn fract(self) -> Self {
2465 self.simd.fract_f32x8(self)
2466 }
2467 #[inline(always)]
2468 fn trunc(self) -> Self {
2469 self.simd.trunc_f32x8(self)
2470 }
2471}
2472impl<S: Simd> SimdCvtFloat<u32x8<S>> for f32x8<S> {
2473 #[doc = "Convert each unsigned 32-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
2474 #[inline(always)]
2475 fn float_from(x: u32x8<S>) -> Self {
2476 x.simd.cvt_f32_u32x8(x)
2477 }
2478}
2479impl<S: Simd> SimdCvtFloat<i32x8<S>> for f32x8<S> {
2480 #[doc = "Convert each signed 32-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
2481 #[inline(always)]
2482 fn float_from(x: i32x8<S>) -> Self {
2483 x.simd.cvt_f32_i32x8(x)
2484 }
2485}
2486impl<S: Simd> crate::SimdSplit<S> for f32x8<S> {
2487 type Split = f32x4<S>;
2488 #[inline(always)]
2489 fn split(self) -> (Self::Split, Self::Split) {
2490 self.simd.split_f32x8(self)
2491 }
2492}
2493impl<S: Simd> crate::SimdCombine<S> for f32x8<S> {
2494 type Combined = f32x16<S>;
2495 #[inline(always)]
2496 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
2497 self.simd.combine_f32x8(self, rhs.simd_into(self.simd))
2498 }
2499}
2500#[doc = "A SIMD vector of 32 [`i8`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, i8x32};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = i8x32::splat(simd, 1);\n let b = i8x32::simd_from(simd, 1);\n\n // From a slice:\n let c = i8x32::from_slice(simd, &[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, 26, 27, 28, 29, 30, 31, 32]);\n\n // From an array:\n let d = i8x32::simd_from(simd, [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, 26, 27, 28, 29, 30, 31, 32]);\n\n // From an element-wise function:\n let e = i8x32::from_fn(simd, |i| i as i8);\n # use fearless_simd::i8x16;\n // From `Self::Block`:\n let f = i8x32::block_splat(i8x16::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]));\n}\n```"]
2501#[derive(Clone, Copy)]
2502#[repr(C, align(32))]
2503pub struct i8x32<S: Simd> {
2504 pub(crate) val: S::i8x32,
2505 pub simd: S,
2506}
2507impl<S: Simd> SimdFrom<[i8; 32], S> for i8x32<S> {
2508 #[inline(always)]
2509 fn simd_from(simd: S, val: [i8; 32]) -> Self {
2510 simd.load_array_i8x32(val)
2511 }
2512}
2513impl<S: Simd> From<i8x32<S>> for [i8; 32] {
2514 #[inline(always)]
2515 fn from(value: i8x32<S>) -> Self {
2516 value.simd.as_array_i8x32(value)
2517 }
2518}
2519impl<S: Simd> core::ops::Deref for i8x32<S> {
2520 type Target = [i8; 32];
2521 #[inline(always)]
2522 fn deref(&self) -> &Self::Target {
2523 self.simd.as_array_ref_i8x32(self)
2524 }
2525}
2526impl<S: Simd> core::ops::DerefMut for i8x32<S> {
2527 #[inline(always)]
2528 fn deref_mut(&mut self) -> &mut Self::Target {
2529 self.simd.as_array_mut_i8x32(self)
2530 }
2531}
2532impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i8x32<S> {
2533 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2534 crate::support::simd_debug_impl(f, "i8x32", &self.simd, self.simd.as_array_ref_i8x32(self))
2535 }
2536}
2537impl<S: Simd> SimdFrom<i8, S> for i8x32<S> {
2538 #[inline(always)]
2539 fn simd_from(simd: S, value: i8) -> Self {
2540 simd.splat_i8x32(value)
2541 }
2542}
2543impl<S: Simd> core::ops::Index<usize> for i8x32<S> {
2544 type Output = i8;
2545 #[inline(always)]
2546 fn index(&self, i: usize) -> &Self::Output {
2547 &self.simd.as_array_ref_i8x32(self)[i]
2548 }
2549}
2550impl<S: Simd> core::ops::IndexMut<usize> for i8x32<S> {
2551 #[inline(always)]
2552 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
2553 &mut self.simd.as_array_mut_i8x32(self)[i]
2554 }
2555}
2556impl<S: Simd> Select<i8x32<S>> for mask8x32<S> {
2557 #[inline(always)]
2558 fn select(self, if_true: i8x32<S>, if_false: i8x32<S>) -> i8x32<S> {
2559 self.simd.select_i8x32(self, if_true, if_false)
2560 }
2561}
2562impl<S: Simd> Bytes for i8x32<S> {
2563 type Bytes = u8x32<S>;
2564 #[inline(always)]
2565 fn to_bytes(self) -> Self::Bytes {
2566 self.simd.cvt_to_bytes_i8x32(self)
2567 }
2568 #[inline(always)]
2569 fn from_bytes(value: Self::Bytes) -> Self {
2570 value.simd.cvt_from_bytes_i8x32(value)
2571 }
2572}
2573impl<S: Simd> SimdBase<S> for i8x32<S> {
2574 type Element = i8;
2575 const N: usize = 32;
2576 type Mask = mask8x32<S>;
2577 type Block = i8x16<S>;
2578 type Array = [i8; 32];
2579 #[inline(always)]
2580 fn witness(&self) -> S {
2581 self.simd
2582 }
2583 #[inline(always)]
2584 fn as_slice(&self) -> &[i8] {
2585 self.simd.as_array_ref_i8x32(self).as_slice()
2586 }
2587 #[inline(always)]
2588 fn as_mut_slice(&mut self) -> &mut [i8] {
2589 self.simd.as_array_mut_i8x32(self).as_mut_slice()
2590 }
2591 #[inline(always)]
2592 fn from_slice(simd: S, slice: &[i8]) -> Self {
2593 simd.load_array_ref_i8x32(slice.try_into().unwrap())
2594 }
2595 #[inline(always)]
2596 fn store_slice(&self, slice: &mut [i8]) {
2597 self.simd
2598 .store_array_i8x32(*self, slice.try_into().unwrap());
2599 }
2600 #[inline(always)]
2601 fn splat(simd: S, val: i8) -> Self {
2602 simd.splat_i8x32(val)
2603 }
2604 #[inline(always)]
2605 fn block_splat(block: Self::Block) -> Self {
2606 block.simd.combine_i8x16(block, block)
2607 }
2608 #[inline(always)]
2609 fn from_fn(simd: S, f: impl FnMut(usize) -> i8) -> Self {
2610 simd.load_array_i8x32(core::array::from_fn(f))
2611 }
2612 #[inline(always)]
2613 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
2614 self.simd
2615 .slide_i8x32::<SHIFT>(self, rhs.simd_into(self.simd))
2616 }
2617 #[inline(always)]
2618 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
2619 self.simd
2620 .slide_within_blocks_i8x32::<SHIFT>(self, rhs.simd_into(self.simd))
2621 }
2622}
2623impl<S: Simd> crate::SimdInt<S> for i8x32<S> {
2624 #[inline(always)]
2625 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2626 self.simd.simd_eq_i8x32(self, rhs.simd_into(self.simd))
2627 }
2628 #[inline(always)]
2629 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2630 self.simd.simd_lt_i8x32(self, rhs.simd_into(self.simd))
2631 }
2632 #[inline(always)]
2633 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2634 self.simd.simd_le_i8x32(self, rhs.simd_into(self.simd))
2635 }
2636 #[inline(always)]
2637 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2638 self.simd.simd_ge_i8x32(self, rhs.simd_into(self.simd))
2639 }
2640 #[inline(always)]
2641 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2642 self.simd.simd_gt_i8x32(self, rhs.simd_into(self.simd))
2643 }
2644 #[inline(always)]
2645 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
2646 self.simd.zip_low_i8x32(self, rhs.simd_into(self.simd))
2647 }
2648 #[inline(always)]
2649 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
2650 self.simd.zip_high_i8x32(self, rhs.simd_into(self.simd))
2651 }
2652 #[inline(always)]
2653 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
2654 self.simd.unzip_low_i8x32(self, rhs.simd_into(self.simd))
2655 }
2656 #[inline(always)]
2657 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
2658 self.simd.unzip_high_i8x32(self, rhs.simd_into(self.simd))
2659 }
2660 #[inline(always)]
2661 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
2662 self.simd.interleave_i8x32(self, rhs.simd_into(self.simd))
2663 }
2664 #[inline(always)]
2665 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
2666 self.simd.deinterleave_i8x32(self, rhs.simd_into(self.simd))
2667 }
2668 #[inline(always)]
2669 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
2670 self.simd.min_i8x32(self, rhs.simd_into(self.simd))
2671 }
2672 #[inline(always)]
2673 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
2674 self.simd.max_i8x32(self, rhs.simd_into(self.simd))
2675 }
2676}
2677impl<S: Simd> crate::SimdSplit<S> for i8x32<S> {
2678 type Split = i8x16<S>;
2679 #[inline(always)]
2680 fn split(self) -> (Self::Split, Self::Split) {
2681 self.simd.split_i8x32(self)
2682 }
2683}
2684impl<S: Simd> crate::SimdCombine<S> for i8x32<S> {
2685 type Combined = i8x64<S>;
2686 #[inline(always)]
2687 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
2688 self.simd.combine_i8x32(self, rhs.simd_into(self.simd))
2689 }
2690}
2691#[doc = "A SIMD vector of 32 [`u8`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, u8x32};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = u8x32::splat(simd, 1);\n let b = u8x32::simd_from(simd, 1);\n\n // From a slice:\n let c = u8x32::from_slice(simd, &[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, 26, 27, 28, 29, 30, 31, 32]);\n\n // From an array:\n let d = u8x32::simd_from(simd, [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, 26, 27, 28, 29, 30, 31, 32]);\n\n // From an element-wise function:\n let e = u8x32::from_fn(simd, |i| i as u8);\n # use fearless_simd::u8x16;\n // From `Self::Block`:\n let f = u8x32::block_splat(u8x16::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]));\n}\n```"]
2692#[derive(Clone, Copy)]
2693#[repr(C, align(32))]
2694pub struct u8x32<S: Simd> {
2695 pub(crate) val: S::u8x32,
2696 pub simd: S,
2697}
2698impl<S: Simd> SimdFrom<[u8; 32], S> for u8x32<S> {
2699 #[inline(always)]
2700 fn simd_from(simd: S, val: [u8; 32]) -> Self {
2701 simd.load_array_u8x32(val)
2702 }
2703}
2704impl<S: Simd> From<u8x32<S>> for [u8; 32] {
2705 #[inline(always)]
2706 fn from(value: u8x32<S>) -> Self {
2707 value.simd.as_array_u8x32(value)
2708 }
2709}
2710impl<S: Simd> core::ops::Deref for u8x32<S> {
2711 type Target = [u8; 32];
2712 #[inline(always)]
2713 fn deref(&self) -> &Self::Target {
2714 self.simd.as_array_ref_u8x32(self)
2715 }
2716}
2717impl<S: Simd> core::ops::DerefMut for u8x32<S> {
2718 #[inline(always)]
2719 fn deref_mut(&mut self) -> &mut Self::Target {
2720 self.simd.as_array_mut_u8x32(self)
2721 }
2722}
2723impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u8x32<S> {
2724 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2725 crate::support::simd_debug_impl(f, "u8x32", &self.simd, self.simd.as_array_ref_u8x32(self))
2726 }
2727}
2728impl<S: Simd> SimdFrom<u8, S> for u8x32<S> {
2729 #[inline(always)]
2730 fn simd_from(simd: S, value: u8) -> Self {
2731 simd.splat_u8x32(value)
2732 }
2733}
2734impl<S: Simd> core::ops::Index<usize> for u8x32<S> {
2735 type Output = u8;
2736 #[inline(always)]
2737 fn index(&self, i: usize) -> &Self::Output {
2738 &self.simd.as_array_ref_u8x32(self)[i]
2739 }
2740}
2741impl<S: Simd> core::ops::IndexMut<usize> for u8x32<S> {
2742 #[inline(always)]
2743 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
2744 &mut self.simd.as_array_mut_u8x32(self)[i]
2745 }
2746}
2747impl<S: Simd> Select<u8x32<S>> for mask8x32<S> {
2748 #[inline(always)]
2749 fn select(self, if_true: u8x32<S>, if_false: u8x32<S>) -> u8x32<S> {
2750 self.simd.select_u8x32(self, if_true, if_false)
2751 }
2752}
2753impl<S: Simd> Bytes for u8x32<S> {
2754 type Bytes = u8x32<S>;
2755 #[inline(always)]
2756 fn to_bytes(self) -> Self::Bytes {
2757 self.simd.cvt_to_bytes_u8x32(self)
2758 }
2759 #[inline(always)]
2760 fn from_bytes(value: Self::Bytes) -> Self {
2761 value.simd.cvt_from_bytes_u8x32(value)
2762 }
2763}
2764impl<S: Simd> SimdBase<S> for u8x32<S> {
2765 type Element = u8;
2766 const N: usize = 32;
2767 type Mask = mask8x32<S>;
2768 type Block = u8x16<S>;
2769 type Array = [u8; 32];
2770 #[inline(always)]
2771 fn witness(&self) -> S {
2772 self.simd
2773 }
2774 #[inline(always)]
2775 fn as_slice(&self) -> &[u8] {
2776 self.simd.as_array_ref_u8x32(self).as_slice()
2777 }
2778 #[inline(always)]
2779 fn as_mut_slice(&mut self) -> &mut [u8] {
2780 self.simd.as_array_mut_u8x32(self).as_mut_slice()
2781 }
2782 #[inline(always)]
2783 fn from_slice(simd: S, slice: &[u8]) -> Self {
2784 simd.load_array_ref_u8x32(slice.try_into().unwrap())
2785 }
2786 #[inline(always)]
2787 fn store_slice(&self, slice: &mut [u8]) {
2788 self.simd
2789 .store_array_u8x32(*self, slice.try_into().unwrap());
2790 }
2791 #[inline(always)]
2792 fn splat(simd: S, val: u8) -> Self {
2793 simd.splat_u8x32(val)
2794 }
2795 #[inline(always)]
2796 fn block_splat(block: Self::Block) -> Self {
2797 block.simd.combine_u8x16(block, block)
2798 }
2799 #[inline(always)]
2800 fn from_fn(simd: S, f: impl FnMut(usize) -> u8) -> Self {
2801 simd.load_array_u8x32(core::array::from_fn(f))
2802 }
2803 #[inline(always)]
2804 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
2805 self.simd
2806 .slide_u8x32::<SHIFT>(self, rhs.simd_into(self.simd))
2807 }
2808 #[inline(always)]
2809 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
2810 self.simd
2811 .slide_within_blocks_u8x32::<SHIFT>(self, rhs.simd_into(self.simd))
2812 }
2813}
2814impl<S: Simd> crate::SimdInt<S> for u8x32<S> {
2815 #[inline(always)]
2816 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2817 self.simd.simd_eq_u8x32(self, rhs.simd_into(self.simd))
2818 }
2819 #[inline(always)]
2820 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2821 self.simd.simd_lt_u8x32(self, rhs.simd_into(self.simd))
2822 }
2823 #[inline(always)]
2824 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2825 self.simd.simd_le_u8x32(self, rhs.simd_into(self.simd))
2826 }
2827 #[inline(always)]
2828 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2829 self.simd.simd_ge_u8x32(self, rhs.simd_into(self.simd))
2830 }
2831 #[inline(always)]
2832 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2833 self.simd.simd_gt_u8x32(self, rhs.simd_into(self.simd))
2834 }
2835 #[inline(always)]
2836 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
2837 self.simd.zip_low_u8x32(self, rhs.simd_into(self.simd))
2838 }
2839 #[inline(always)]
2840 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
2841 self.simd.zip_high_u8x32(self, rhs.simd_into(self.simd))
2842 }
2843 #[inline(always)]
2844 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
2845 self.simd.unzip_low_u8x32(self, rhs.simd_into(self.simd))
2846 }
2847 #[inline(always)]
2848 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
2849 self.simd.unzip_high_u8x32(self, rhs.simd_into(self.simd))
2850 }
2851 #[inline(always)]
2852 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
2853 self.simd.interleave_u8x32(self, rhs.simd_into(self.simd))
2854 }
2855 #[inline(always)]
2856 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
2857 self.simd.deinterleave_u8x32(self, rhs.simd_into(self.simd))
2858 }
2859 #[inline(always)]
2860 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
2861 self.simd.min_u8x32(self, rhs.simd_into(self.simd))
2862 }
2863 #[inline(always)]
2864 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
2865 self.simd.max_u8x32(self, rhs.simd_into(self.simd))
2866 }
2867}
2868impl<S: Simd> crate::SimdSplit<S> for u8x32<S> {
2869 type Split = u8x16<S>;
2870 #[inline(always)]
2871 fn split(self) -> (Self::Split, Self::Split) {
2872 self.simd.split_u8x32(self)
2873 }
2874}
2875impl<S: Simd> crate::SimdCombine<S> for u8x32<S> {
2876 type Combined = u8x64<S>;
2877 #[inline(always)]
2878 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
2879 self.simd.combine_u8x32(self, rhs.simd_into(self.simd))
2880 }
2881}
2882#[doc = "A SIMD mask of 32 8-bit elements.\n\nWhen created from a comparison operation, and as it should be used in a [`Self::select`] operation, each element will be all ones if it's \"true\", and all zeroes if it's \"false\"."]
2883#[derive(Clone, Copy)]
2884#[repr(C, align(32))]
2885pub struct mask8x32<S: Simd> {
2886 pub(crate) val: S::mask8x32,
2887 pub simd: S,
2888}
2889impl<S: Simd> SimdFrom<[i8; 32], S> for mask8x32<S> {
2890 #[inline(always)]
2891 fn simd_from(simd: S, val: [i8; 32]) -> Self {
2892 simd.load_array_mask8x32(val)
2893 }
2894}
2895impl<S: Simd> From<mask8x32<S>> for [i8; 32] {
2896 #[inline(always)]
2897 fn from(value: mask8x32<S>) -> Self {
2898 value.simd.as_array_mask8x32(value)
2899 }
2900}
2901impl<S: Simd> core::ops::Deref for mask8x32<S> {
2902 type Target = [i8; 32];
2903 #[inline(always)]
2904 fn deref(&self) -> &Self::Target {
2905 self.simd.as_array_ref_mask8x32(self)
2906 }
2907}
2908impl<S: Simd> core::ops::DerefMut for mask8x32<S> {
2909 #[inline(always)]
2910 fn deref_mut(&mut self) -> &mut Self::Target {
2911 self.simd.as_array_mut_mask8x32(self)
2912 }
2913}
2914impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask8x32<S> {
2915 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2916 crate::support::simd_debug_impl(
2917 f,
2918 "mask8x32",
2919 &self.simd,
2920 self.simd.as_array_ref_mask8x32(self),
2921 )
2922 }
2923}
2924impl<S: Simd> SimdFrom<i8, S> for mask8x32<S> {
2925 #[inline(always)]
2926 fn simd_from(simd: S, value: i8) -> Self {
2927 simd.splat_mask8x32(value)
2928 }
2929}
2930impl<S: Simd> core::ops::Index<usize> for mask8x32<S> {
2931 type Output = i8;
2932 #[inline(always)]
2933 fn index(&self, i: usize) -> &Self::Output {
2934 &self.simd.as_array_ref_mask8x32(self)[i]
2935 }
2936}
2937impl<S: Simd> core::ops::IndexMut<usize> for mask8x32<S> {
2938 #[inline(always)]
2939 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
2940 &mut self.simd.as_array_mut_mask8x32(self)[i]
2941 }
2942}
2943impl<S: Simd> Select<mask8x32<S>> for mask8x32<S> {
2944 #[inline(always)]
2945 fn select(self, if_true: mask8x32<S>, if_false: mask8x32<S>) -> mask8x32<S> {
2946 self.simd.select_mask8x32(self, if_true, if_false)
2947 }
2948}
2949impl<S: Simd> Bytes for mask8x32<S> {
2950 type Bytes = u8x32<S>;
2951 #[inline(always)]
2952 fn to_bytes(self) -> Self::Bytes {
2953 self.simd.cvt_to_bytes_mask8x32(self)
2954 }
2955 #[inline(always)]
2956 fn from_bytes(value: Self::Bytes) -> Self {
2957 value.simd.cvt_from_bytes_mask8x32(value)
2958 }
2959}
2960impl<S: Simd> SimdBase<S> for mask8x32<S> {
2961 type Element = i8;
2962 const N: usize = 32;
2963 type Mask = mask8x32<S>;
2964 type Block = mask8x16<S>;
2965 type Array = [i8; 32];
2966 #[inline(always)]
2967 fn witness(&self) -> S {
2968 self.simd
2969 }
2970 #[inline(always)]
2971 fn as_slice(&self) -> &[i8] {
2972 self.simd.as_array_ref_mask8x32(self).as_slice()
2973 }
2974 #[inline(always)]
2975 fn as_mut_slice(&mut self) -> &mut [i8] {
2976 self.simd.as_array_mut_mask8x32(self).as_mut_slice()
2977 }
2978 #[inline(always)]
2979 fn from_slice(simd: S, slice: &[i8]) -> Self {
2980 simd.load_array_ref_mask8x32(slice.try_into().unwrap())
2981 }
2982 #[inline(always)]
2983 fn store_slice(&self, slice: &mut [i8]) {
2984 self.simd
2985 .store_array_mask8x32(*self, slice.try_into().unwrap());
2986 }
2987 #[inline(always)]
2988 fn splat(simd: S, val: i8) -> Self {
2989 simd.splat_mask8x32(val)
2990 }
2991 #[inline(always)]
2992 fn block_splat(block: Self::Block) -> Self {
2993 block.simd.combine_mask8x16(block, block)
2994 }
2995 #[inline(always)]
2996 fn from_fn(simd: S, f: impl FnMut(usize) -> i8) -> Self {
2997 simd.load_array_mask8x32(core::array::from_fn(f))
2998 }
2999 #[inline(always)]
3000 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
3001 self.simd
3002 .slide_mask8x32::<SHIFT>(self, rhs.simd_into(self.simd))
3003 }
3004 #[inline(always)]
3005 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
3006 self.simd
3007 .slide_within_blocks_mask8x32::<SHIFT>(self, rhs.simd_into(self.simd))
3008 }
3009}
3010impl<S: Simd> crate::SimdMask<S> for mask8x32<S> {
3011 #[inline(always)]
3012 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3013 self.simd.simd_eq_mask8x32(self, rhs.simd_into(self.simd))
3014 }
3015 #[inline(always)]
3016 fn any_true(self) -> bool {
3017 self.simd.any_true_mask8x32(self)
3018 }
3019 #[inline(always)]
3020 fn all_true(self) -> bool {
3021 self.simd.all_true_mask8x32(self)
3022 }
3023 #[inline(always)]
3024 fn any_false(self) -> bool {
3025 self.simd.any_false_mask8x32(self)
3026 }
3027 #[inline(always)]
3028 fn all_false(self) -> bool {
3029 self.simd.all_false_mask8x32(self)
3030 }
3031}
3032impl<S: Simd> crate::SimdSplit<S> for mask8x32<S> {
3033 type Split = mask8x16<S>;
3034 #[inline(always)]
3035 fn split(self) -> (Self::Split, Self::Split) {
3036 self.simd.split_mask8x32(self)
3037 }
3038}
3039impl<S: Simd> crate::SimdCombine<S> for mask8x32<S> {
3040 type Combined = mask8x64<S>;
3041 #[inline(always)]
3042 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
3043 self.simd.combine_mask8x32(self, rhs.simd_into(self.simd))
3044 }
3045}
3046#[doc = "A SIMD vector of 16 [`i16`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, i16x16};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = i16x16::splat(simd, 1);\n let b = i16x16::simd_from(simd, 1);\n\n // From a slice:\n let c = i16x16::from_slice(simd, &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);\n\n // From an array:\n let d = i16x16::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);\n\n // From an element-wise function:\n let e = i16x16::from_fn(simd, |i| i as i16);\n # use fearless_simd::i16x8;\n // From `Self::Block`:\n let f = i16x16::block_splat(i16x8::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8]));\n}\n```"]
3047#[derive(Clone, Copy)]
3048#[repr(C, align(32))]
3049pub struct i16x16<S: Simd> {
3050 pub(crate) val: S::i16x16,
3051 pub simd: S,
3052}
3053impl<S: Simd> SimdFrom<[i16; 16], S> for i16x16<S> {
3054 #[inline(always)]
3055 fn simd_from(simd: S, val: [i16; 16]) -> Self {
3056 simd.load_array_i16x16(val)
3057 }
3058}
3059impl<S: Simd> From<i16x16<S>> for [i16; 16] {
3060 #[inline(always)]
3061 fn from(value: i16x16<S>) -> Self {
3062 value.simd.as_array_i16x16(value)
3063 }
3064}
3065impl<S: Simd> core::ops::Deref for i16x16<S> {
3066 type Target = [i16; 16];
3067 #[inline(always)]
3068 fn deref(&self) -> &Self::Target {
3069 self.simd.as_array_ref_i16x16(self)
3070 }
3071}
3072impl<S: Simd> core::ops::DerefMut for i16x16<S> {
3073 #[inline(always)]
3074 fn deref_mut(&mut self) -> &mut Self::Target {
3075 self.simd.as_array_mut_i16x16(self)
3076 }
3077}
3078impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i16x16<S> {
3079 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3080 crate::support::simd_debug_impl(
3081 f,
3082 "i16x16",
3083 &self.simd,
3084 self.simd.as_array_ref_i16x16(self),
3085 )
3086 }
3087}
3088impl<S: Simd> SimdFrom<i16, S> for i16x16<S> {
3089 #[inline(always)]
3090 fn simd_from(simd: S, value: i16) -> Self {
3091 simd.splat_i16x16(value)
3092 }
3093}
3094impl<S: Simd> core::ops::Index<usize> for i16x16<S> {
3095 type Output = i16;
3096 #[inline(always)]
3097 fn index(&self, i: usize) -> &Self::Output {
3098 &self.simd.as_array_ref_i16x16(self)[i]
3099 }
3100}
3101impl<S: Simd> core::ops::IndexMut<usize> for i16x16<S> {
3102 #[inline(always)]
3103 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
3104 &mut self.simd.as_array_mut_i16x16(self)[i]
3105 }
3106}
3107impl<S: Simd> Select<i16x16<S>> for mask16x16<S> {
3108 #[inline(always)]
3109 fn select(self, if_true: i16x16<S>, if_false: i16x16<S>) -> i16x16<S> {
3110 self.simd.select_i16x16(self, if_true, if_false)
3111 }
3112}
3113impl<S: Simd> Bytes for i16x16<S> {
3114 type Bytes = u8x32<S>;
3115 #[inline(always)]
3116 fn to_bytes(self) -> Self::Bytes {
3117 self.simd.cvt_to_bytes_i16x16(self)
3118 }
3119 #[inline(always)]
3120 fn from_bytes(value: Self::Bytes) -> Self {
3121 value.simd.cvt_from_bytes_i16x16(value)
3122 }
3123}
3124impl<S: Simd> SimdBase<S> for i16x16<S> {
3125 type Element = i16;
3126 const N: usize = 16;
3127 type Mask = mask16x16<S>;
3128 type Block = i16x8<S>;
3129 type Array = [i16; 16];
3130 #[inline(always)]
3131 fn witness(&self) -> S {
3132 self.simd
3133 }
3134 #[inline(always)]
3135 fn as_slice(&self) -> &[i16] {
3136 self.simd.as_array_ref_i16x16(self).as_slice()
3137 }
3138 #[inline(always)]
3139 fn as_mut_slice(&mut self) -> &mut [i16] {
3140 self.simd.as_array_mut_i16x16(self).as_mut_slice()
3141 }
3142 #[inline(always)]
3143 fn from_slice(simd: S, slice: &[i16]) -> Self {
3144 simd.load_array_ref_i16x16(slice.try_into().unwrap())
3145 }
3146 #[inline(always)]
3147 fn store_slice(&self, slice: &mut [i16]) {
3148 self.simd
3149 .store_array_i16x16(*self, slice.try_into().unwrap());
3150 }
3151 #[inline(always)]
3152 fn splat(simd: S, val: i16) -> Self {
3153 simd.splat_i16x16(val)
3154 }
3155 #[inline(always)]
3156 fn block_splat(block: Self::Block) -> Self {
3157 block.simd.combine_i16x8(block, block)
3158 }
3159 #[inline(always)]
3160 fn from_fn(simd: S, f: impl FnMut(usize) -> i16) -> Self {
3161 simd.load_array_i16x16(core::array::from_fn(f))
3162 }
3163 #[inline(always)]
3164 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
3165 self.simd
3166 .slide_i16x16::<SHIFT>(self, rhs.simd_into(self.simd))
3167 }
3168 #[inline(always)]
3169 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
3170 self.simd
3171 .slide_within_blocks_i16x16::<SHIFT>(self, rhs.simd_into(self.simd))
3172 }
3173}
3174impl<S: Simd> crate::SimdInt<S> for i16x16<S> {
3175 #[inline(always)]
3176 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3177 self.simd.simd_eq_i16x16(self, rhs.simd_into(self.simd))
3178 }
3179 #[inline(always)]
3180 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3181 self.simd.simd_lt_i16x16(self, rhs.simd_into(self.simd))
3182 }
3183 #[inline(always)]
3184 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3185 self.simd.simd_le_i16x16(self, rhs.simd_into(self.simd))
3186 }
3187 #[inline(always)]
3188 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3189 self.simd.simd_ge_i16x16(self, rhs.simd_into(self.simd))
3190 }
3191 #[inline(always)]
3192 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3193 self.simd.simd_gt_i16x16(self, rhs.simd_into(self.simd))
3194 }
3195 #[inline(always)]
3196 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
3197 self.simd.zip_low_i16x16(self, rhs.simd_into(self.simd))
3198 }
3199 #[inline(always)]
3200 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
3201 self.simd.zip_high_i16x16(self, rhs.simd_into(self.simd))
3202 }
3203 #[inline(always)]
3204 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
3205 self.simd.unzip_low_i16x16(self, rhs.simd_into(self.simd))
3206 }
3207 #[inline(always)]
3208 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
3209 self.simd.unzip_high_i16x16(self, rhs.simd_into(self.simd))
3210 }
3211 #[inline(always)]
3212 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
3213 self.simd.interleave_i16x16(self, rhs.simd_into(self.simd))
3214 }
3215 #[inline(always)]
3216 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
3217 self.simd
3218 .deinterleave_i16x16(self, rhs.simd_into(self.simd))
3219 }
3220 #[inline(always)]
3221 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
3222 self.simd.min_i16x16(self, rhs.simd_into(self.simd))
3223 }
3224 #[inline(always)]
3225 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
3226 self.simd.max_i16x16(self, rhs.simd_into(self.simd))
3227 }
3228}
3229impl<S: Simd> crate::SimdSplit<S> for i16x16<S> {
3230 type Split = i16x8<S>;
3231 #[inline(always)]
3232 fn split(self) -> (Self::Split, Self::Split) {
3233 self.simd.split_i16x16(self)
3234 }
3235}
3236impl<S: Simd> crate::SimdCombine<S> for i16x16<S> {
3237 type Combined = i16x32<S>;
3238 #[inline(always)]
3239 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
3240 self.simd.combine_i16x16(self, rhs.simd_into(self.simd))
3241 }
3242}
3243#[doc = "A SIMD vector of 16 [`u16`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, u16x16};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = u16x16::splat(simd, 1);\n let b = u16x16::simd_from(simd, 1);\n\n // From a slice:\n let c = u16x16::from_slice(simd, &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);\n\n // From an array:\n let d = u16x16::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);\n\n // From an element-wise function:\n let e = u16x16::from_fn(simd, |i| i as u16);\n # use fearless_simd::u16x8;\n // From `Self::Block`:\n let f = u16x16::block_splat(u16x8::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8]));\n}\n```"]
3244#[derive(Clone, Copy)]
3245#[repr(C, align(32))]
3246pub struct u16x16<S: Simd> {
3247 pub(crate) val: S::u16x16,
3248 pub simd: S,
3249}
3250impl<S: Simd> SimdFrom<[u16; 16], S> for u16x16<S> {
3251 #[inline(always)]
3252 fn simd_from(simd: S, val: [u16; 16]) -> Self {
3253 simd.load_array_u16x16(val)
3254 }
3255}
3256impl<S: Simd> From<u16x16<S>> for [u16; 16] {
3257 #[inline(always)]
3258 fn from(value: u16x16<S>) -> Self {
3259 value.simd.as_array_u16x16(value)
3260 }
3261}
3262impl<S: Simd> core::ops::Deref for u16x16<S> {
3263 type Target = [u16; 16];
3264 #[inline(always)]
3265 fn deref(&self) -> &Self::Target {
3266 self.simd.as_array_ref_u16x16(self)
3267 }
3268}
3269impl<S: Simd> core::ops::DerefMut for u16x16<S> {
3270 #[inline(always)]
3271 fn deref_mut(&mut self) -> &mut Self::Target {
3272 self.simd.as_array_mut_u16x16(self)
3273 }
3274}
3275impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u16x16<S> {
3276 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3277 crate::support::simd_debug_impl(
3278 f,
3279 "u16x16",
3280 &self.simd,
3281 self.simd.as_array_ref_u16x16(self),
3282 )
3283 }
3284}
3285impl<S: Simd> SimdFrom<u16, S> for u16x16<S> {
3286 #[inline(always)]
3287 fn simd_from(simd: S, value: u16) -> Self {
3288 simd.splat_u16x16(value)
3289 }
3290}
3291impl<S: Simd> core::ops::Index<usize> for u16x16<S> {
3292 type Output = u16;
3293 #[inline(always)]
3294 fn index(&self, i: usize) -> &Self::Output {
3295 &self.simd.as_array_ref_u16x16(self)[i]
3296 }
3297}
3298impl<S: Simd> core::ops::IndexMut<usize> for u16x16<S> {
3299 #[inline(always)]
3300 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
3301 &mut self.simd.as_array_mut_u16x16(self)[i]
3302 }
3303}
3304impl<S: Simd> Select<u16x16<S>> for mask16x16<S> {
3305 #[inline(always)]
3306 fn select(self, if_true: u16x16<S>, if_false: u16x16<S>) -> u16x16<S> {
3307 self.simd.select_u16x16(self, if_true, if_false)
3308 }
3309}
3310impl<S: Simd> Bytes for u16x16<S> {
3311 type Bytes = u8x32<S>;
3312 #[inline(always)]
3313 fn to_bytes(self) -> Self::Bytes {
3314 self.simd.cvt_to_bytes_u16x16(self)
3315 }
3316 #[inline(always)]
3317 fn from_bytes(value: Self::Bytes) -> Self {
3318 value.simd.cvt_from_bytes_u16x16(value)
3319 }
3320}
3321impl<S: Simd> SimdBase<S> for u16x16<S> {
3322 type Element = u16;
3323 const N: usize = 16;
3324 type Mask = mask16x16<S>;
3325 type Block = u16x8<S>;
3326 type Array = [u16; 16];
3327 #[inline(always)]
3328 fn witness(&self) -> S {
3329 self.simd
3330 }
3331 #[inline(always)]
3332 fn as_slice(&self) -> &[u16] {
3333 self.simd.as_array_ref_u16x16(self).as_slice()
3334 }
3335 #[inline(always)]
3336 fn as_mut_slice(&mut self) -> &mut [u16] {
3337 self.simd.as_array_mut_u16x16(self).as_mut_slice()
3338 }
3339 #[inline(always)]
3340 fn from_slice(simd: S, slice: &[u16]) -> Self {
3341 simd.load_array_ref_u16x16(slice.try_into().unwrap())
3342 }
3343 #[inline(always)]
3344 fn store_slice(&self, slice: &mut [u16]) {
3345 self.simd
3346 .store_array_u16x16(*self, slice.try_into().unwrap());
3347 }
3348 #[inline(always)]
3349 fn splat(simd: S, val: u16) -> Self {
3350 simd.splat_u16x16(val)
3351 }
3352 #[inline(always)]
3353 fn block_splat(block: Self::Block) -> Self {
3354 block.simd.combine_u16x8(block, block)
3355 }
3356 #[inline(always)]
3357 fn from_fn(simd: S, f: impl FnMut(usize) -> u16) -> Self {
3358 simd.load_array_u16x16(core::array::from_fn(f))
3359 }
3360 #[inline(always)]
3361 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
3362 self.simd
3363 .slide_u16x16::<SHIFT>(self, rhs.simd_into(self.simd))
3364 }
3365 #[inline(always)]
3366 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
3367 self.simd
3368 .slide_within_blocks_u16x16::<SHIFT>(self, rhs.simd_into(self.simd))
3369 }
3370}
3371impl<S: Simd> crate::SimdInt<S> for u16x16<S> {
3372 #[inline(always)]
3373 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3374 self.simd.simd_eq_u16x16(self, rhs.simd_into(self.simd))
3375 }
3376 #[inline(always)]
3377 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3378 self.simd.simd_lt_u16x16(self, rhs.simd_into(self.simd))
3379 }
3380 #[inline(always)]
3381 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3382 self.simd.simd_le_u16x16(self, rhs.simd_into(self.simd))
3383 }
3384 #[inline(always)]
3385 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3386 self.simd.simd_ge_u16x16(self, rhs.simd_into(self.simd))
3387 }
3388 #[inline(always)]
3389 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3390 self.simd.simd_gt_u16x16(self, rhs.simd_into(self.simd))
3391 }
3392 #[inline(always)]
3393 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
3394 self.simd.zip_low_u16x16(self, rhs.simd_into(self.simd))
3395 }
3396 #[inline(always)]
3397 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
3398 self.simd.zip_high_u16x16(self, rhs.simd_into(self.simd))
3399 }
3400 #[inline(always)]
3401 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
3402 self.simd.unzip_low_u16x16(self, rhs.simd_into(self.simd))
3403 }
3404 #[inline(always)]
3405 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
3406 self.simd.unzip_high_u16x16(self, rhs.simd_into(self.simd))
3407 }
3408 #[inline(always)]
3409 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
3410 self.simd.interleave_u16x16(self, rhs.simd_into(self.simd))
3411 }
3412 #[inline(always)]
3413 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
3414 self.simd
3415 .deinterleave_u16x16(self, rhs.simd_into(self.simd))
3416 }
3417 #[inline(always)]
3418 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
3419 self.simd.min_u16x16(self, rhs.simd_into(self.simd))
3420 }
3421 #[inline(always)]
3422 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
3423 self.simd.max_u16x16(self, rhs.simd_into(self.simd))
3424 }
3425}
3426impl<S: Simd> crate::SimdSplit<S> for u16x16<S> {
3427 type Split = u16x8<S>;
3428 #[inline(always)]
3429 fn split(self) -> (Self::Split, Self::Split) {
3430 self.simd.split_u16x16(self)
3431 }
3432}
3433impl<S: Simd> crate::SimdCombine<S> for u16x16<S> {
3434 type Combined = u16x32<S>;
3435 #[inline(always)]
3436 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
3437 self.simd.combine_u16x16(self, rhs.simd_into(self.simd))
3438 }
3439}
3440#[doc = "A SIMD mask of 16 16-bit elements.\n\nWhen created from a comparison operation, and as it should be used in a [`Self::select`] operation, each element will be all ones if it's \"true\", and all zeroes if it's \"false\"."]
3441#[derive(Clone, Copy)]
3442#[repr(C, align(32))]
3443pub struct mask16x16<S: Simd> {
3444 pub(crate) val: S::mask16x16,
3445 pub simd: S,
3446}
3447impl<S: Simd> SimdFrom<[i16; 16], S> for mask16x16<S> {
3448 #[inline(always)]
3449 fn simd_from(simd: S, val: [i16; 16]) -> Self {
3450 simd.load_array_mask16x16(val)
3451 }
3452}
3453impl<S: Simd> From<mask16x16<S>> for [i16; 16] {
3454 #[inline(always)]
3455 fn from(value: mask16x16<S>) -> Self {
3456 value.simd.as_array_mask16x16(value)
3457 }
3458}
3459impl<S: Simd> core::ops::Deref for mask16x16<S> {
3460 type Target = [i16; 16];
3461 #[inline(always)]
3462 fn deref(&self) -> &Self::Target {
3463 self.simd.as_array_ref_mask16x16(self)
3464 }
3465}
3466impl<S: Simd> core::ops::DerefMut for mask16x16<S> {
3467 #[inline(always)]
3468 fn deref_mut(&mut self) -> &mut Self::Target {
3469 self.simd.as_array_mut_mask16x16(self)
3470 }
3471}
3472impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask16x16<S> {
3473 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3474 crate::support::simd_debug_impl(
3475 f,
3476 "mask16x16",
3477 &self.simd,
3478 self.simd.as_array_ref_mask16x16(self),
3479 )
3480 }
3481}
3482impl<S: Simd> SimdFrom<i16, S> for mask16x16<S> {
3483 #[inline(always)]
3484 fn simd_from(simd: S, value: i16) -> Self {
3485 simd.splat_mask16x16(value)
3486 }
3487}
3488impl<S: Simd> core::ops::Index<usize> for mask16x16<S> {
3489 type Output = i16;
3490 #[inline(always)]
3491 fn index(&self, i: usize) -> &Self::Output {
3492 &self.simd.as_array_ref_mask16x16(self)[i]
3493 }
3494}
3495impl<S: Simd> core::ops::IndexMut<usize> for mask16x16<S> {
3496 #[inline(always)]
3497 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
3498 &mut self.simd.as_array_mut_mask16x16(self)[i]
3499 }
3500}
3501impl<S: Simd> Select<mask16x16<S>> for mask16x16<S> {
3502 #[inline(always)]
3503 fn select(self, if_true: mask16x16<S>, if_false: mask16x16<S>) -> mask16x16<S> {
3504 self.simd.select_mask16x16(self, if_true, if_false)
3505 }
3506}
3507impl<S: Simd> Bytes for mask16x16<S> {
3508 type Bytes = u8x32<S>;
3509 #[inline(always)]
3510 fn to_bytes(self) -> Self::Bytes {
3511 self.simd.cvt_to_bytes_mask16x16(self)
3512 }
3513 #[inline(always)]
3514 fn from_bytes(value: Self::Bytes) -> Self {
3515 value.simd.cvt_from_bytes_mask16x16(value)
3516 }
3517}
3518impl<S: Simd> SimdBase<S> for mask16x16<S> {
3519 type Element = i16;
3520 const N: usize = 16;
3521 type Mask = mask16x16<S>;
3522 type Block = mask16x8<S>;
3523 type Array = [i16; 16];
3524 #[inline(always)]
3525 fn witness(&self) -> S {
3526 self.simd
3527 }
3528 #[inline(always)]
3529 fn as_slice(&self) -> &[i16] {
3530 self.simd.as_array_ref_mask16x16(self).as_slice()
3531 }
3532 #[inline(always)]
3533 fn as_mut_slice(&mut self) -> &mut [i16] {
3534 self.simd.as_array_mut_mask16x16(self).as_mut_slice()
3535 }
3536 #[inline(always)]
3537 fn from_slice(simd: S, slice: &[i16]) -> Self {
3538 simd.load_array_ref_mask16x16(slice.try_into().unwrap())
3539 }
3540 #[inline(always)]
3541 fn store_slice(&self, slice: &mut [i16]) {
3542 self.simd
3543 .store_array_mask16x16(*self, slice.try_into().unwrap());
3544 }
3545 #[inline(always)]
3546 fn splat(simd: S, val: i16) -> Self {
3547 simd.splat_mask16x16(val)
3548 }
3549 #[inline(always)]
3550 fn block_splat(block: Self::Block) -> Self {
3551 block.simd.combine_mask16x8(block, block)
3552 }
3553 #[inline(always)]
3554 fn from_fn(simd: S, f: impl FnMut(usize) -> i16) -> Self {
3555 simd.load_array_mask16x16(core::array::from_fn(f))
3556 }
3557 #[inline(always)]
3558 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
3559 self.simd
3560 .slide_mask16x16::<SHIFT>(self, rhs.simd_into(self.simd))
3561 }
3562 #[inline(always)]
3563 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
3564 self.simd
3565 .slide_within_blocks_mask16x16::<SHIFT>(self, rhs.simd_into(self.simd))
3566 }
3567}
3568impl<S: Simd> crate::SimdMask<S> for mask16x16<S> {
3569 #[inline(always)]
3570 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3571 self.simd.simd_eq_mask16x16(self, rhs.simd_into(self.simd))
3572 }
3573 #[inline(always)]
3574 fn any_true(self) -> bool {
3575 self.simd.any_true_mask16x16(self)
3576 }
3577 #[inline(always)]
3578 fn all_true(self) -> bool {
3579 self.simd.all_true_mask16x16(self)
3580 }
3581 #[inline(always)]
3582 fn any_false(self) -> bool {
3583 self.simd.any_false_mask16x16(self)
3584 }
3585 #[inline(always)]
3586 fn all_false(self) -> bool {
3587 self.simd.all_false_mask16x16(self)
3588 }
3589}
3590impl<S: Simd> crate::SimdSplit<S> for mask16x16<S> {
3591 type Split = mask16x8<S>;
3592 #[inline(always)]
3593 fn split(self) -> (Self::Split, Self::Split) {
3594 self.simd.split_mask16x16(self)
3595 }
3596}
3597impl<S: Simd> crate::SimdCombine<S> for mask16x16<S> {
3598 type Combined = mask16x32<S>;
3599 #[inline(always)]
3600 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
3601 self.simd.combine_mask16x16(self, rhs.simd_into(self.simd))
3602 }
3603}
3604#[doc = "A SIMD vector of 8 [`i32`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, i32x8};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = i32x8::splat(simd, 1);\n let b = i32x8::simd_from(simd, 1);\n\n // From a slice:\n let c = i32x8::from_slice(simd, &[1, 2, 3, 4, 5, 6, 7, 8]);\n\n // From an array:\n let d = i32x8::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8]);\n\n // From an element-wise function:\n let e = i32x8::from_fn(simd, |i| i as i32);\n # use fearless_simd::i32x4;\n // From `Self::Block`:\n let f = i32x8::block_splat(i32x4::simd_from(simd, [1, 2, 3, 4]));\n}\n```"]
3605#[derive(Clone, Copy)]
3606#[repr(C, align(32))]
3607pub struct i32x8<S: Simd> {
3608 pub(crate) val: S::i32x8,
3609 pub simd: S,
3610}
3611impl<S: Simd> SimdFrom<[i32; 8], S> for i32x8<S> {
3612 #[inline(always)]
3613 fn simd_from(simd: S, val: [i32; 8]) -> Self {
3614 simd.load_array_i32x8(val)
3615 }
3616}
3617impl<S: Simd> From<i32x8<S>> for [i32; 8] {
3618 #[inline(always)]
3619 fn from(value: i32x8<S>) -> Self {
3620 value.simd.as_array_i32x8(value)
3621 }
3622}
3623impl<S: Simd> core::ops::Deref for i32x8<S> {
3624 type Target = [i32; 8];
3625 #[inline(always)]
3626 fn deref(&self) -> &Self::Target {
3627 self.simd.as_array_ref_i32x8(self)
3628 }
3629}
3630impl<S: Simd> core::ops::DerefMut for i32x8<S> {
3631 #[inline(always)]
3632 fn deref_mut(&mut self) -> &mut Self::Target {
3633 self.simd.as_array_mut_i32x8(self)
3634 }
3635}
3636impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i32x8<S> {
3637 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3638 crate::support::simd_debug_impl(f, "i32x8", &self.simd, self.simd.as_array_ref_i32x8(self))
3639 }
3640}
3641impl<S: Simd> SimdFrom<i32, S> for i32x8<S> {
3642 #[inline(always)]
3643 fn simd_from(simd: S, value: i32) -> Self {
3644 simd.splat_i32x8(value)
3645 }
3646}
3647impl<S: Simd> core::ops::Index<usize> for i32x8<S> {
3648 type Output = i32;
3649 #[inline(always)]
3650 fn index(&self, i: usize) -> &Self::Output {
3651 &self.simd.as_array_ref_i32x8(self)[i]
3652 }
3653}
3654impl<S: Simd> core::ops::IndexMut<usize> for i32x8<S> {
3655 #[inline(always)]
3656 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
3657 &mut self.simd.as_array_mut_i32x8(self)[i]
3658 }
3659}
3660impl<S: Simd> Select<i32x8<S>> for mask32x8<S> {
3661 #[inline(always)]
3662 fn select(self, if_true: i32x8<S>, if_false: i32x8<S>) -> i32x8<S> {
3663 self.simd.select_i32x8(self, if_true, if_false)
3664 }
3665}
3666impl<S: Simd> Bytes for i32x8<S> {
3667 type Bytes = u8x32<S>;
3668 #[inline(always)]
3669 fn to_bytes(self) -> Self::Bytes {
3670 self.simd.cvt_to_bytes_i32x8(self)
3671 }
3672 #[inline(always)]
3673 fn from_bytes(value: Self::Bytes) -> Self {
3674 value.simd.cvt_from_bytes_i32x8(value)
3675 }
3676}
3677impl<S: Simd> SimdBase<S> for i32x8<S> {
3678 type Element = i32;
3679 const N: usize = 8;
3680 type Mask = mask32x8<S>;
3681 type Block = i32x4<S>;
3682 type Array = [i32; 8];
3683 #[inline(always)]
3684 fn witness(&self) -> S {
3685 self.simd
3686 }
3687 #[inline(always)]
3688 fn as_slice(&self) -> &[i32] {
3689 self.simd.as_array_ref_i32x8(self).as_slice()
3690 }
3691 #[inline(always)]
3692 fn as_mut_slice(&mut self) -> &mut [i32] {
3693 self.simd.as_array_mut_i32x8(self).as_mut_slice()
3694 }
3695 #[inline(always)]
3696 fn from_slice(simd: S, slice: &[i32]) -> Self {
3697 simd.load_array_ref_i32x8(slice.try_into().unwrap())
3698 }
3699 #[inline(always)]
3700 fn store_slice(&self, slice: &mut [i32]) {
3701 self.simd
3702 .store_array_i32x8(*self, slice.try_into().unwrap());
3703 }
3704 #[inline(always)]
3705 fn splat(simd: S, val: i32) -> Self {
3706 simd.splat_i32x8(val)
3707 }
3708 #[inline(always)]
3709 fn block_splat(block: Self::Block) -> Self {
3710 block.simd.combine_i32x4(block, block)
3711 }
3712 #[inline(always)]
3713 fn from_fn(simd: S, f: impl FnMut(usize) -> i32) -> Self {
3714 simd.load_array_i32x8(core::array::from_fn(f))
3715 }
3716 #[inline(always)]
3717 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
3718 self.simd
3719 .slide_i32x8::<SHIFT>(self, rhs.simd_into(self.simd))
3720 }
3721 #[inline(always)]
3722 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
3723 self.simd
3724 .slide_within_blocks_i32x8::<SHIFT>(self, rhs.simd_into(self.simd))
3725 }
3726}
3727impl<S: Simd> crate::SimdInt<S> for i32x8<S> {
3728 #[inline(always)]
3729 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3730 self.simd.simd_eq_i32x8(self, rhs.simd_into(self.simd))
3731 }
3732 #[inline(always)]
3733 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3734 self.simd.simd_lt_i32x8(self, rhs.simd_into(self.simd))
3735 }
3736 #[inline(always)]
3737 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3738 self.simd.simd_le_i32x8(self, rhs.simd_into(self.simd))
3739 }
3740 #[inline(always)]
3741 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3742 self.simd.simd_ge_i32x8(self, rhs.simd_into(self.simd))
3743 }
3744 #[inline(always)]
3745 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3746 self.simd.simd_gt_i32x8(self, rhs.simd_into(self.simd))
3747 }
3748 #[inline(always)]
3749 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
3750 self.simd.zip_low_i32x8(self, rhs.simd_into(self.simd))
3751 }
3752 #[inline(always)]
3753 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
3754 self.simd.zip_high_i32x8(self, rhs.simd_into(self.simd))
3755 }
3756 #[inline(always)]
3757 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
3758 self.simd.unzip_low_i32x8(self, rhs.simd_into(self.simd))
3759 }
3760 #[inline(always)]
3761 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
3762 self.simd.unzip_high_i32x8(self, rhs.simd_into(self.simd))
3763 }
3764 #[inline(always)]
3765 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
3766 self.simd.interleave_i32x8(self, rhs.simd_into(self.simd))
3767 }
3768 #[inline(always)]
3769 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
3770 self.simd.deinterleave_i32x8(self, rhs.simd_into(self.simd))
3771 }
3772 #[inline(always)]
3773 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
3774 self.simd.min_i32x8(self, rhs.simd_into(self.simd))
3775 }
3776 #[inline(always)]
3777 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
3778 self.simd.max_i32x8(self, rhs.simd_into(self.simd))
3779 }
3780}
3781impl<S: Simd> SimdCvtTruncate<f32x8<S>> for i32x8<S> {
3782 #[doc = "Convert each floating-point element to a signed 32-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
3783 #[inline(always)]
3784 fn truncate_from(x: f32x8<S>) -> Self {
3785 x.simd.cvt_i32_f32x8(x)
3786 }
3787 #[doc = "Convert each floating-point element to a signed 32-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
3788 #[inline(always)]
3789 fn truncate_from_precise(x: f32x8<S>) -> Self {
3790 x.simd.cvt_i32_precise_f32x8(x)
3791 }
3792}
3793impl<S: Simd> crate::SimdSplit<S> for i32x8<S> {
3794 type Split = i32x4<S>;
3795 #[inline(always)]
3796 fn split(self) -> (Self::Split, Self::Split) {
3797 self.simd.split_i32x8(self)
3798 }
3799}
3800impl<S: Simd> crate::SimdCombine<S> for i32x8<S> {
3801 type Combined = i32x16<S>;
3802 #[inline(always)]
3803 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
3804 self.simd.combine_i32x8(self, rhs.simd_into(self.simd))
3805 }
3806}
3807#[doc = "A SIMD vector of 8 [`u32`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, u32x8};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = u32x8::splat(simd, 1);\n let b = u32x8::simd_from(simd, 1);\n\n // From a slice:\n let c = u32x8::from_slice(simd, &[1, 2, 3, 4, 5, 6, 7, 8]);\n\n // From an array:\n let d = u32x8::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8]);\n\n // From an element-wise function:\n let e = u32x8::from_fn(simd, |i| i as u32);\n # use fearless_simd::u32x4;\n // From `Self::Block`:\n let f = u32x8::block_splat(u32x4::simd_from(simd, [1, 2, 3, 4]));\n}\n```"]
3808#[derive(Clone, Copy)]
3809#[repr(C, align(32))]
3810pub struct u32x8<S: Simd> {
3811 pub(crate) val: S::u32x8,
3812 pub simd: S,
3813}
3814impl<S: Simd> SimdFrom<[u32; 8], S> for u32x8<S> {
3815 #[inline(always)]
3816 fn simd_from(simd: S, val: [u32; 8]) -> Self {
3817 simd.load_array_u32x8(val)
3818 }
3819}
3820impl<S: Simd> From<u32x8<S>> for [u32; 8] {
3821 #[inline(always)]
3822 fn from(value: u32x8<S>) -> Self {
3823 value.simd.as_array_u32x8(value)
3824 }
3825}
3826impl<S: Simd> core::ops::Deref for u32x8<S> {
3827 type Target = [u32; 8];
3828 #[inline(always)]
3829 fn deref(&self) -> &Self::Target {
3830 self.simd.as_array_ref_u32x8(self)
3831 }
3832}
3833impl<S: Simd> core::ops::DerefMut for u32x8<S> {
3834 #[inline(always)]
3835 fn deref_mut(&mut self) -> &mut Self::Target {
3836 self.simd.as_array_mut_u32x8(self)
3837 }
3838}
3839impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u32x8<S> {
3840 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3841 crate::support::simd_debug_impl(f, "u32x8", &self.simd, self.simd.as_array_ref_u32x8(self))
3842 }
3843}
3844impl<S: Simd> SimdFrom<u32, S> for u32x8<S> {
3845 #[inline(always)]
3846 fn simd_from(simd: S, value: u32) -> Self {
3847 simd.splat_u32x8(value)
3848 }
3849}
3850impl<S: Simd> core::ops::Index<usize> for u32x8<S> {
3851 type Output = u32;
3852 #[inline(always)]
3853 fn index(&self, i: usize) -> &Self::Output {
3854 &self.simd.as_array_ref_u32x8(self)[i]
3855 }
3856}
3857impl<S: Simd> core::ops::IndexMut<usize> for u32x8<S> {
3858 #[inline(always)]
3859 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
3860 &mut self.simd.as_array_mut_u32x8(self)[i]
3861 }
3862}
3863impl<S: Simd> Select<u32x8<S>> for mask32x8<S> {
3864 #[inline(always)]
3865 fn select(self, if_true: u32x8<S>, if_false: u32x8<S>) -> u32x8<S> {
3866 self.simd.select_u32x8(self, if_true, if_false)
3867 }
3868}
3869impl<S: Simd> Bytes for u32x8<S> {
3870 type Bytes = u8x32<S>;
3871 #[inline(always)]
3872 fn to_bytes(self) -> Self::Bytes {
3873 self.simd.cvt_to_bytes_u32x8(self)
3874 }
3875 #[inline(always)]
3876 fn from_bytes(value: Self::Bytes) -> Self {
3877 value.simd.cvt_from_bytes_u32x8(value)
3878 }
3879}
3880impl<S: Simd> SimdBase<S> for u32x8<S> {
3881 type Element = u32;
3882 const N: usize = 8;
3883 type Mask = mask32x8<S>;
3884 type Block = u32x4<S>;
3885 type Array = [u32; 8];
3886 #[inline(always)]
3887 fn witness(&self) -> S {
3888 self.simd
3889 }
3890 #[inline(always)]
3891 fn as_slice(&self) -> &[u32] {
3892 self.simd.as_array_ref_u32x8(self).as_slice()
3893 }
3894 #[inline(always)]
3895 fn as_mut_slice(&mut self) -> &mut [u32] {
3896 self.simd.as_array_mut_u32x8(self).as_mut_slice()
3897 }
3898 #[inline(always)]
3899 fn from_slice(simd: S, slice: &[u32]) -> Self {
3900 simd.load_array_ref_u32x8(slice.try_into().unwrap())
3901 }
3902 #[inline(always)]
3903 fn store_slice(&self, slice: &mut [u32]) {
3904 self.simd
3905 .store_array_u32x8(*self, slice.try_into().unwrap());
3906 }
3907 #[inline(always)]
3908 fn splat(simd: S, val: u32) -> Self {
3909 simd.splat_u32x8(val)
3910 }
3911 #[inline(always)]
3912 fn block_splat(block: Self::Block) -> Self {
3913 block.simd.combine_u32x4(block, block)
3914 }
3915 #[inline(always)]
3916 fn from_fn(simd: S, f: impl FnMut(usize) -> u32) -> Self {
3917 simd.load_array_u32x8(core::array::from_fn(f))
3918 }
3919 #[inline(always)]
3920 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
3921 self.simd
3922 .slide_u32x8::<SHIFT>(self, rhs.simd_into(self.simd))
3923 }
3924 #[inline(always)]
3925 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
3926 self.simd
3927 .slide_within_blocks_u32x8::<SHIFT>(self, rhs.simd_into(self.simd))
3928 }
3929}
3930impl<S: Simd> crate::SimdInt<S> for u32x8<S> {
3931 #[inline(always)]
3932 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3933 self.simd.simd_eq_u32x8(self, rhs.simd_into(self.simd))
3934 }
3935 #[inline(always)]
3936 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3937 self.simd.simd_lt_u32x8(self, rhs.simd_into(self.simd))
3938 }
3939 #[inline(always)]
3940 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3941 self.simd.simd_le_u32x8(self, rhs.simd_into(self.simd))
3942 }
3943 #[inline(always)]
3944 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3945 self.simd.simd_ge_u32x8(self, rhs.simd_into(self.simd))
3946 }
3947 #[inline(always)]
3948 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3949 self.simd.simd_gt_u32x8(self, rhs.simd_into(self.simd))
3950 }
3951 #[inline(always)]
3952 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
3953 self.simd.zip_low_u32x8(self, rhs.simd_into(self.simd))
3954 }
3955 #[inline(always)]
3956 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
3957 self.simd.zip_high_u32x8(self, rhs.simd_into(self.simd))
3958 }
3959 #[inline(always)]
3960 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
3961 self.simd.unzip_low_u32x8(self, rhs.simd_into(self.simd))
3962 }
3963 #[inline(always)]
3964 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
3965 self.simd.unzip_high_u32x8(self, rhs.simd_into(self.simd))
3966 }
3967 #[inline(always)]
3968 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
3969 self.simd.interleave_u32x8(self, rhs.simd_into(self.simd))
3970 }
3971 #[inline(always)]
3972 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
3973 self.simd.deinterleave_u32x8(self, rhs.simd_into(self.simd))
3974 }
3975 #[inline(always)]
3976 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
3977 self.simd.min_u32x8(self, rhs.simd_into(self.simd))
3978 }
3979 #[inline(always)]
3980 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
3981 self.simd.max_u32x8(self, rhs.simd_into(self.simd))
3982 }
3983}
3984impl<S: Simd> SimdCvtTruncate<f32x8<S>> for u32x8<S> {
3985 #[doc = "Convert each floating-point element to an unsigned 32-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results.\n\nOn x86 platforms, this operation will still be slower than converting to `i32`, because there is no native instruction for converting to `u32` (at least until AVX-512, which is currently not supported).\nIf you know your values fit within range of an `i32`, you should convert to an `i32` and cast to your desired datatype afterwards."]
3986 #[inline(always)]
3987 fn truncate_from(x: f32x8<S>) -> Self {
3988 x.simd.cvt_u32_f32x8(x)
3989 }
3990 #[doc = "Convert each floating-point element to an unsigned 32-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
3991 #[inline(always)]
3992 fn truncate_from_precise(x: f32x8<S>) -> Self {
3993 x.simd.cvt_u32_precise_f32x8(x)
3994 }
3995}
3996impl<S: Simd> crate::SimdSplit<S> for u32x8<S> {
3997 type Split = u32x4<S>;
3998 #[inline(always)]
3999 fn split(self) -> (Self::Split, Self::Split) {
4000 self.simd.split_u32x8(self)
4001 }
4002}
4003impl<S: Simd> crate::SimdCombine<S> for u32x8<S> {
4004 type Combined = u32x16<S>;
4005 #[inline(always)]
4006 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
4007 self.simd.combine_u32x8(self, rhs.simd_into(self.simd))
4008 }
4009}
4010#[doc = "A SIMD mask of 8 32-bit elements.\n\nWhen created from a comparison operation, and as it should be used in a [`Self::select`] operation, each element will be all ones if it's \"true\", and all zeroes if it's \"false\"."]
4011#[derive(Clone, Copy)]
4012#[repr(C, align(32))]
4013pub struct mask32x8<S: Simd> {
4014 pub(crate) val: S::mask32x8,
4015 pub simd: S,
4016}
4017impl<S: Simd> SimdFrom<[i32; 8], S> for mask32x8<S> {
4018 #[inline(always)]
4019 fn simd_from(simd: S, val: [i32; 8]) -> Self {
4020 simd.load_array_mask32x8(val)
4021 }
4022}
4023impl<S: Simd> From<mask32x8<S>> for [i32; 8] {
4024 #[inline(always)]
4025 fn from(value: mask32x8<S>) -> Self {
4026 value.simd.as_array_mask32x8(value)
4027 }
4028}
4029impl<S: Simd> core::ops::Deref for mask32x8<S> {
4030 type Target = [i32; 8];
4031 #[inline(always)]
4032 fn deref(&self) -> &Self::Target {
4033 self.simd.as_array_ref_mask32x8(self)
4034 }
4035}
4036impl<S: Simd> core::ops::DerefMut for mask32x8<S> {
4037 #[inline(always)]
4038 fn deref_mut(&mut self) -> &mut Self::Target {
4039 self.simd.as_array_mut_mask32x8(self)
4040 }
4041}
4042impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask32x8<S> {
4043 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4044 crate::support::simd_debug_impl(
4045 f,
4046 "mask32x8",
4047 &self.simd,
4048 self.simd.as_array_ref_mask32x8(self),
4049 )
4050 }
4051}
4052impl<S: Simd> SimdFrom<i32, S> for mask32x8<S> {
4053 #[inline(always)]
4054 fn simd_from(simd: S, value: i32) -> Self {
4055 simd.splat_mask32x8(value)
4056 }
4057}
4058impl<S: Simd> core::ops::Index<usize> for mask32x8<S> {
4059 type Output = i32;
4060 #[inline(always)]
4061 fn index(&self, i: usize) -> &Self::Output {
4062 &self.simd.as_array_ref_mask32x8(self)[i]
4063 }
4064}
4065impl<S: Simd> core::ops::IndexMut<usize> for mask32x8<S> {
4066 #[inline(always)]
4067 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
4068 &mut self.simd.as_array_mut_mask32x8(self)[i]
4069 }
4070}
4071impl<S: Simd> Select<mask32x8<S>> for mask32x8<S> {
4072 #[inline(always)]
4073 fn select(self, if_true: mask32x8<S>, if_false: mask32x8<S>) -> mask32x8<S> {
4074 self.simd.select_mask32x8(self, if_true, if_false)
4075 }
4076}
4077impl<S: Simd> Bytes for mask32x8<S> {
4078 type Bytes = u8x32<S>;
4079 #[inline(always)]
4080 fn to_bytes(self) -> Self::Bytes {
4081 self.simd.cvt_to_bytes_mask32x8(self)
4082 }
4083 #[inline(always)]
4084 fn from_bytes(value: Self::Bytes) -> Self {
4085 value.simd.cvt_from_bytes_mask32x8(value)
4086 }
4087}
4088impl<S: Simd> SimdBase<S> for mask32x8<S> {
4089 type Element = i32;
4090 const N: usize = 8;
4091 type Mask = mask32x8<S>;
4092 type Block = mask32x4<S>;
4093 type Array = [i32; 8];
4094 #[inline(always)]
4095 fn witness(&self) -> S {
4096 self.simd
4097 }
4098 #[inline(always)]
4099 fn as_slice(&self) -> &[i32] {
4100 self.simd.as_array_ref_mask32x8(self).as_slice()
4101 }
4102 #[inline(always)]
4103 fn as_mut_slice(&mut self) -> &mut [i32] {
4104 self.simd.as_array_mut_mask32x8(self).as_mut_slice()
4105 }
4106 #[inline(always)]
4107 fn from_slice(simd: S, slice: &[i32]) -> Self {
4108 simd.load_array_ref_mask32x8(slice.try_into().unwrap())
4109 }
4110 #[inline(always)]
4111 fn store_slice(&self, slice: &mut [i32]) {
4112 self.simd
4113 .store_array_mask32x8(*self, slice.try_into().unwrap());
4114 }
4115 #[inline(always)]
4116 fn splat(simd: S, val: i32) -> Self {
4117 simd.splat_mask32x8(val)
4118 }
4119 #[inline(always)]
4120 fn block_splat(block: Self::Block) -> Self {
4121 block.simd.combine_mask32x4(block, block)
4122 }
4123 #[inline(always)]
4124 fn from_fn(simd: S, f: impl FnMut(usize) -> i32) -> Self {
4125 simd.load_array_mask32x8(core::array::from_fn(f))
4126 }
4127 #[inline(always)]
4128 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
4129 self.simd
4130 .slide_mask32x8::<SHIFT>(self, rhs.simd_into(self.simd))
4131 }
4132 #[inline(always)]
4133 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
4134 self.simd
4135 .slide_within_blocks_mask32x8::<SHIFT>(self, rhs.simd_into(self.simd))
4136 }
4137}
4138impl<S: Simd> crate::SimdMask<S> for mask32x8<S> {
4139 #[inline(always)]
4140 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4141 self.simd.simd_eq_mask32x8(self, rhs.simd_into(self.simd))
4142 }
4143 #[inline(always)]
4144 fn any_true(self) -> bool {
4145 self.simd.any_true_mask32x8(self)
4146 }
4147 #[inline(always)]
4148 fn all_true(self) -> bool {
4149 self.simd.all_true_mask32x8(self)
4150 }
4151 #[inline(always)]
4152 fn any_false(self) -> bool {
4153 self.simd.any_false_mask32x8(self)
4154 }
4155 #[inline(always)]
4156 fn all_false(self) -> bool {
4157 self.simd.all_false_mask32x8(self)
4158 }
4159}
4160impl<S: Simd> crate::SimdSplit<S> for mask32x8<S> {
4161 type Split = mask32x4<S>;
4162 #[inline(always)]
4163 fn split(self) -> (Self::Split, Self::Split) {
4164 self.simd.split_mask32x8(self)
4165 }
4166}
4167impl<S: Simd> crate::SimdCombine<S> for mask32x8<S> {
4168 type Combined = mask32x16<S>;
4169 #[inline(always)]
4170 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
4171 self.simd.combine_mask32x8(self, rhs.simd_into(self.simd))
4172 }
4173}
4174#[doc = "A SIMD vector of 4 [`f64`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, f64x4};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = f64x4::splat(simd, 1.0);\n let b = f64x4::simd_from(simd, 1.0);\n\n // From a slice:\n let c = f64x4::from_slice(simd, &[1.0, 2.0, 3.0, 4.0]);\n\n // From an array:\n let d = f64x4::simd_from(simd, [1.0, 2.0, 3.0, 4.0]);\n\n // From an element-wise function:\n let e = f64x4::from_fn(simd, |i| i as f64);\n # use fearless_simd::f64x2;\n // From `Self::Block`:\n let f = f64x4::block_splat(f64x2::simd_from(simd, [1.0, 2.0]));\n}\n```"]
4175#[derive(Clone, Copy)]
4176#[repr(C, align(32))]
4177pub struct f64x4<S: Simd> {
4178 pub(crate) val: S::f64x4,
4179 pub simd: S,
4180}
4181impl<S: Simd> SimdFrom<[f64; 4], S> for f64x4<S> {
4182 #[inline(always)]
4183 fn simd_from(simd: S, val: [f64; 4]) -> Self {
4184 simd.load_array_f64x4(val)
4185 }
4186}
4187impl<S: Simd> From<f64x4<S>> for [f64; 4] {
4188 #[inline(always)]
4189 fn from(value: f64x4<S>) -> Self {
4190 value.simd.as_array_f64x4(value)
4191 }
4192}
4193impl<S: Simd> core::ops::Deref for f64x4<S> {
4194 type Target = [f64; 4];
4195 #[inline(always)]
4196 fn deref(&self) -> &Self::Target {
4197 self.simd.as_array_ref_f64x4(self)
4198 }
4199}
4200impl<S: Simd> core::ops::DerefMut for f64x4<S> {
4201 #[inline(always)]
4202 fn deref_mut(&mut self) -> &mut Self::Target {
4203 self.simd.as_array_mut_f64x4(self)
4204 }
4205}
4206impl<S: Simd + core::fmt::Debug> core::fmt::Debug for f64x4<S> {
4207 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4208 crate::support::simd_debug_impl(f, "f64x4", &self.simd, self.simd.as_array_ref_f64x4(self))
4209 }
4210}
4211impl<S: Simd> SimdFrom<f64, S> for f64x4<S> {
4212 #[inline(always)]
4213 fn simd_from(simd: S, value: f64) -> Self {
4214 simd.splat_f64x4(value)
4215 }
4216}
4217impl<S: Simd> core::ops::Index<usize> for f64x4<S> {
4218 type Output = f64;
4219 #[inline(always)]
4220 fn index(&self, i: usize) -> &Self::Output {
4221 &self.simd.as_array_ref_f64x4(self)[i]
4222 }
4223}
4224impl<S: Simd> core::ops::IndexMut<usize> for f64x4<S> {
4225 #[inline(always)]
4226 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
4227 &mut self.simd.as_array_mut_f64x4(self)[i]
4228 }
4229}
4230impl<S: Simd> Select<f64x4<S>> for mask64x4<S> {
4231 #[inline(always)]
4232 fn select(self, if_true: f64x4<S>, if_false: f64x4<S>) -> f64x4<S> {
4233 self.simd.select_f64x4(self, if_true, if_false)
4234 }
4235}
4236impl<S: Simd> Bytes for f64x4<S> {
4237 type Bytes = u8x32<S>;
4238 #[inline(always)]
4239 fn to_bytes(self) -> Self::Bytes {
4240 self.simd.cvt_to_bytes_f64x4(self)
4241 }
4242 #[inline(always)]
4243 fn from_bytes(value: Self::Bytes) -> Self {
4244 value.simd.cvt_from_bytes_f64x4(value)
4245 }
4246}
4247impl<S: Simd> SimdBase<S> for f64x4<S> {
4248 type Element = f64;
4249 const N: usize = 4;
4250 type Mask = mask64x4<S>;
4251 type Block = f64x2<S>;
4252 type Array = [f64; 4];
4253 #[inline(always)]
4254 fn witness(&self) -> S {
4255 self.simd
4256 }
4257 #[inline(always)]
4258 fn as_slice(&self) -> &[f64] {
4259 self.simd.as_array_ref_f64x4(self).as_slice()
4260 }
4261 #[inline(always)]
4262 fn as_mut_slice(&mut self) -> &mut [f64] {
4263 self.simd.as_array_mut_f64x4(self).as_mut_slice()
4264 }
4265 #[inline(always)]
4266 fn from_slice(simd: S, slice: &[f64]) -> Self {
4267 simd.load_array_ref_f64x4(slice.try_into().unwrap())
4268 }
4269 #[inline(always)]
4270 fn store_slice(&self, slice: &mut [f64]) {
4271 self.simd
4272 .store_array_f64x4(*self, slice.try_into().unwrap());
4273 }
4274 #[inline(always)]
4275 fn splat(simd: S, val: f64) -> Self {
4276 simd.splat_f64x4(val)
4277 }
4278 #[inline(always)]
4279 fn block_splat(block: Self::Block) -> Self {
4280 block.simd.combine_f64x2(block, block)
4281 }
4282 #[inline(always)]
4283 fn from_fn(simd: S, f: impl FnMut(usize) -> f64) -> Self {
4284 simd.load_array_f64x4(core::array::from_fn(f))
4285 }
4286 #[inline(always)]
4287 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
4288 self.simd
4289 .slide_f64x4::<SHIFT>(self, rhs.simd_into(self.simd))
4290 }
4291 #[inline(always)]
4292 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
4293 self.simd
4294 .slide_within_blocks_f64x4::<SHIFT>(self, rhs.simd_into(self.simd))
4295 }
4296}
4297impl<S: Simd> crate::SimdFloat<S> for f64x4<S> {
4298 #[inline(always)]
4299 fn abs(self) -> Self {
4300 self.simd.abs_f64x4(self)
4301 }
4302 #[inline(always)]
4303 fn sqrt(self) -> Self {
4304 self.simd.sqrt_f64x4(self)
4305 }
4306 #[inline(always)]
4307 fn copysign(self, rhs: impl SimdInto<Self, S>) -> Self {
4308 self.simd.copysign_f64x4(self, rhs.simd_into(self.simd))
4309 }
4310 #[inline(always)]
4311 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4312 self.simd.simd_eq_f64x4(self, rhs.simd_into(self.simd))
4313 }
4314 #[inline(always)]
4315 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4316 self.simd.simd_lt_f64x4(self, rhs.simd_into(self.simd))
4317 }
4318 #[inline(always)]
4319 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4320 self.simd.simd_le_f64x4(self, rhs.simd_into(self.simd))
4321 }
4322 #[inline(always)]
4323 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4324 self.simd.simd_ge_f64x4(self, rhs.simd_into(self.simd))
4325 }
4326 #[inline(always)]
4327 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4328 self.simd.simd_gt_f64x4(self, rhs.simd_into(self.simd))
4329 }
4330 #[inline(always)]
4331 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
4332 self.simd.zip_low_f64x4(self, rhs.simd_into(self.simd))
4333 }
4334 #[inline(always)]
4335 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
4336 self.simd.zip_high_f64x4(self, rhs.simd_into(self.simd))
4337 }
4338 #[inline(always)]
4339 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
4340 self.simd.unzip_low_f64x4(self, rhs.simd_into(self.simd))
4341 }
4342 #[inline(always)]
4343 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
4344 self.simd.unzip_high_f64x4(self, rhs.simd_into(self.simd))
4345 }
4346 #[inline(always)]
4347 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
4348 self.simd.interleave_f64x4(self, rhs.simd_into(self.simd))
4349 }
4350 #[inline(always)]
4351 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
4352 self.simd.deinterleave_f64x4(self, rhs.simd_into(self.simd))
4353 }
4354 #[inline(always)]
4355 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
4356 self.simd.max_f64x4(self, rhs.simd_into(self.simd))
4357 }
4358 #[inline(always)]
4359 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
4360 self.simd.min_f64x4(self, rhs.simd_into(self.simd))
4361 }
4362 #[inline(always)]
4363 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
4364 self.simd.max_precise_f64x4(self, rhs.simd_into(self.simd))
4365 }
4366 #[inline(always)]
4367 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
4368 self.simd.min_precise_f64x4(self, rhs.simd_into(self.simd))
4369 }
4370 #[inline(always)]
4371 fn mul_add(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
4372 self.simd
4373 .mul_add_f64x4(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
4374 }
4375 #[inline(always)]
4376 fn mul_sub(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
4377 self.simd
4378 .mul_sub_f64x4(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
4379 }
4380 #[inline(always)]
4381 fn floor(self) -> Self {
4382 self.simd.floor_f64x4(self)
4383 }
4384 #[inline(always)]
4385 fn ceil(self) -> Self {
4386 self.simd.ceil_f64x4(self)
4387 }
4388 #[inline(always)]
4389 fn round_ties_even(self) -> Self {
4390 self.simd.round_ties_even_f64x4(self)
4391 }
4392 #[inline(always)]
4393 fn fract(self) -> Self {
4394 self.simd.fract_f64x4(self)
4395 }
4396 #[inline(always)]
4397 fn trunc(self) -> Self {
4398 self.simd.trunc_f64x4(self)
4399 }
4400}
4401impl<S: Simd> crate::SimdSplit<S> for f64x4<S> {
4402 type Split = f64x2<S>;
4403 #[inline(always)]
4404 fn split(self) -> (Self::Split, Self::Split) {
4405 self.simd.split_f64x4(self)
4406 }
4407}
4408impl<S: Simd> crate::SimdCombine<S> for f64x4<S> {
4409 type Combined = f64x8<S>;
4410 #[inline(always)]
4411 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
4412 self.simd.combine_f64x4(self, rhs.simd_into(self.simd))
4413 }
4414}
4415#[doc = "A SIMD mask of 4 64-bit elements.\n\nWhen created from a comparison operation, and as it should be used in a [`Self::select`] operation, each element will be all ones if it's \"true\", and all zeroes if it's \"false\"."]
4416#[derive(Clone, Copy)]
4417#[repr(C, align(32))]
4418pub struct mask64x4<S: Simd> {
4419 pub(crate) val: S::mask64x4,
4420 pub simd: S,
4421}
4422impl<S: Simd> SimdFrom<[i64; 4], S> for mask64x4<S> {
4423 #[inline(always)]
4424 fn simd_from(simd: S, val: [i64; 4]) -> Self {
4425 simd.load_array_mask64x4(val)
4426 }
4427}
4428impl<S: Simd> From<mask64x4<S>> for [i64; 4] {
4429 #[inline(always)]
4430 fn from(value: mask64x4<S>) -> Self {
4431 value.simd.as_array_mask64x4(value)
4432 }
4433}
4434impl<S: Simd> core::ops::Deref for mask64x4<S> {
4435 type Target = [i64; 4];
4436 #[inline(always)]
4437 fn deref(&self) -> &Self::Target {
4438 self.simd.as_array_ref_mask64x4(self)
4439 }
4440}
4441impl<S: Simd> core::ops::DerefMut for mask64x4<S> {
4442 #[inline(always)]
4443 fn deref_mut(&mut self) -> &mut Self::Target {
4444 self.simd.as_array_mut_mask64x4(self)
4445 }
4446}
4447impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask64x4<S> {
4448 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4449 crate::support::simd_debug_impl(
4450 f,
4451 "mask64x4",
4452 &self.simd,
4453 self.simd.as_array_ref_mask64x4(self),
4454 )
4455 }
4456}
4457impl<S: Simd> SimdFrom<i64, S> for mask64x4<S> {
4458 #[inline(always)]
4459 fn simd_from(simd: S, value: i64) -> Self {
4460 simd.splat_mask64x4(value)
4461 }
4462}
4463impl<S: Simd> core::ops::Index<usize> for mask64x4<S> {
4464 type Output = i64;
4465 #[inline(always)]
4466 fn index(&self, i: usize) -> &Self::Output {
4467 &self.simd.as_array_ref_mask64x4(self)[i]
4468 }
4469}
4470impl<S: Simd> core::ops::IndexMut<usize> for mask64x4<S> {
4471 #[inline(always)]
4472 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
4473 &mut self.simd.as_array_mut_mask64x4(self)[i]
4474 }
4475}
4476impl<S: Simd> Select<mask64x4<S>> for mask64x4<S> {
4477 #[inline(always)]
4478 fn select(self, if_true: mask64x4<S>, if_false: mask64x4<S>) -> mask64x4<S> {
4479 self.simd.select_mask64x4(self, if_true, if_false)
4480 }
4481}
4482impl<S: Simd> Bytes for mask64x4<S> {
4483 type Bytes = u8x32<S>;
4484 #[inline(always)]
4485 fn to_bytes(self) -> Self::Bytes {
4486 self.simd.cvt_to_bytes_mask64x4(self)
4487 }
4488 #[inline(always)]
4489 fn from_bytes(value: Self::Bytes) -> Self {
4490 value.simd.cvt_from_bytes_mask64x4(value)
4491 }
4492}
4493impl<S: Simd> SimdBase<S> for mask64x4<S> {
4494 type Element = i64;
4495 const N: usize = 4;
4496 type Mask = mask64x4<S>;
4497 type Block = mask64x2<S>;
4498 type Array = [i64; 4];
4499 #[inline(always)]
4500 fn witness(&self) -> S {
4501 self.simd
4502 }
4503 #[inline(always)]
4504 fn as_slice(&self) -> &[i64] {
4505 self.simd.as_array_ref_mask64x4(self).as_slice()
4506 }
4507 #[inline(always)]
4508 fn as_mut_slice(&mut self) -> &mut [i64] {
4509 self.simd.as_array_mut_mask64x4(self).as_mut_slice()
4510 }
4511 #[inline(always)]
4512 fn from_slice(simd: S, slice: &[i64]) -> Self {
4513 simd.load_array_ref_mask64x4(slice.try_into().unwrap())
4514 }
4515 #[inline(always)]
4516 fn store_slice(&self, slice: &mut [i64]) {
4517 self.simd
4518 .store_array_mask64x4(*self, slice.try_into().unwrap());
4519 }
4520 #[inline(always)]
4521 fn splat(simd: S, val: i64) -> Self {
4522 simd.splat_mask64x4(val)
4523 }
4524 #[inline(always)]
4525 fn block_splat(block: Self::Block) -> Self {
4526 block.simd.combine_mask64x2(block, block)
4527 }
4528 #[inline(always)]
4529 fn from_fn(simd: S, f: impl FnMut(usize) -> i64) -> Self {
4530 simd.load_array_mask64x4(core::array::from_fn(f))
4531 }
4532 #[inline(always)]
4533 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
4534 self.simd
4535 .slide_mask64x4::<SHIFT>(self, rhs.simd_into(self.simd))
4536 }
4537 #[inline(always)]
4538 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
4539 self.simd
4540 .slide_within_blocks_mask64x4::<SHIFT>(self, rhs.simd_into(self.simd))
4541 }
4542}
4543impl<S: Simd> crate::SimdMask<S> for mask64x4<S> {
4544 #[inline(always)]
4545 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4546 self.simd.simd_eq_mask64x4(self, rhs.simd_into(self.simd))
4547 }
4548 #[inline(always)]
4549 fn any_true(self) -> bool {
4550 self.simd.any_true_mask64x4(self)
4551 }
4552 #[inline(always)]
4553 fn all_true(self) -> bool {
4554 self.simd.all_true_mask64x4(self)
4555 }
4556 #[inline(always)]
4557 fn any_false(self) -> bool {
4558 self.simd.any_false_mask64x4(self)
4559 }
4560 #[inline(always)]
4561 fn all_false(self) -> bool {
4562 self.simd.all_false_mask64x4(self)
4563 }
4564}
4565impl<S: Simd> crate::SimdSplit<S> for mask64x4<S> {
4566 type Split = mask64x2<S>;
4567 #[inline(always)]
4568 fn split(self) -> (Self::Split, Self::Split) {
4569 self.simd.split_mask64x4(self)
4570 }
4571}
4572impl<S: Simd> crate::SimdCombine<S> for mask64x4<S> {
4573 type Combined = mask64x8<S>;
4574 #[inline(always)]
4575 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
4576 self.simd.combine_mask64x4(self, rhs.simd_into(self.simd))
4577 }
4578}
4579#[doc = "A SIMD vector of 16 [`f32`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, f32x16};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = f32x16::splat(simd, 1.0);\n let b = f32x16::simd_from(simd, 1.0);\n\n // From a slice:\n let c = f32x16::from_slice(simd, &[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0]);\n\n // From an array:\n let d = f32x16::simd_from(simd, [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0]);\n\n // From an element-wise function:\n let e = f32x16::from_fn(simd, |i| i as f32);\n # use fearless_simd::f32x4;\n // From `Self::Block`:\n let f = f32x16::block_splat(f32x4::simd_from(simd, [1.0, 2.0, 3.0, 4.0]));\n}\n```"]
4580#[derive(Clone, Copy)]
4581#[repr(C, align(64))]
4582pub struct f32x16<S: Simd> {
4583 pub(crate) val: S::f32x16,
4584 pub simd: S,
4585}
4586impl<S: Simd> SimdFrom<[f32; 16], S> for f32x16<S> {
4587 #[inline(always)]
4588 fn simd_from(simd: S, val: [f32; 16]) -> Self {
4589 simd.load_array_f32x16(val)
4590 }
4591}
4592impl<S: Simd> From<f32x16<S>> for [f32; 16] {
4593 #[inline(always)]
4594 fn from(value: f32x16<S>) -> Self {
4595 value.simd.as_array_f32x16(value)
4596 }
4597}
4598impl<S: Simd> core::ops::Deref for f32x16<S> {
4599 type Target = [f32; 16];
4600 #[inline(always)]
4601 fn deref(&self) -> &Self::Target {
4602 self.simd.as_array_ref_f32x16(self)
4603 }
4604}
4605impl<S: Simd> core::ops::DerefMut for f32x16<S> {
4606 #[inline(always)]
4607 fn deref_mut(&mut self) -> &mut Self::Target {
4608 self.simd.as_array_mut_f32x16(self)
4609 }
4610}
4611impl<S: Simd + core::fmt::Debug> core::fmt::Debug for f32x16<S> {
4612 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4613 crate::support::simd_debug_impl(
4614 f,
4615 "f32x16",
4616 &self.simd,
4617 self.simd.as_array_ref_f32x16(self),
4618 )
4619 }
4620}
4621impl<S: Simd> SimdFrom<f32, S> for f32x16<S> {
4622 #[inline(always)]
4623 fn simd_from(simd: S, value: f32) -> Self {
4624 simd.splat_f32x16(value)
4625 }
4626}
4627impl<S: Simd> core::ops::Index<usize> for f32x16<S> {
4628 type Output = f32;
4629 #[inline(always)]
4630 fn index(&self, i: usize) -> &Self::Output {
4631 &self.simd.as_array_ref_f32x16(self)[i]
4632 }
4633}
4634impl<S: Simd> core::ops::IndexMut<usize> for f32x16<S> {
4635 #[inline(always)]
4636 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
4637 &mut self.simd.as_array_mut_f32x16(self)[i]
4638 }
4639}
4640impl<S: Simd> Select<f32x16<S>> for mask32x16<S> {
4641 #[inline(always)]
4642 fn select(self, if_true: f32x16<S>, if_false: f32x16<S>) -> f32x16<S> {
4643 self.simd.select_f32x16(self, if_true, if_false)
4644 }
4645}
4646impl<S: Simd> Bytes for f32x16<S> {
4647 type Bytes = u8x64<S>;
4648 #[inline(always)]
4649 fn to_bytes(self) -> Self::Bytes {
4650 self.simd.cvt_to_bytes_f32x16(self)
4651 }
4652 #[inline(always)]
4653 fn from_bytes(value: Self::Bytes) -> Self {
4654 value.simd.cvt_from_bytes_f32x16(value)
4655 }
4656}
4657impl<S: Simd> SimdBase<S> for f32x16<S> {
4658 type Element = f32;
4659 const N: usize = 16;
4660 type Mask = mask32x16<S>;
4661 type Block = f32x4<S>;
4662 type Array = [f32; 16];
4663 #[inline(always)]
4664 fn witness(&self) -> S {
4665 self.simd
4666 }
4667 #[inline(always)]
4668 fn as_slice(&self) -> &[f32] {
4669 self.simd.as_array_ref_f32x16(self).as_slice()
4670 }
4671 #[inline(always)]
4672 fn as_mut_slice(&mut self) -> &mut [f32] {
4673 self.simd.as_array_mut_f32x16(self).as_mut_slice()
4674 }
4675 #[inline(always)]
4676 fn from_slice(simd: S, slice: &[f32]) -> Self {
4677 simd.load_array_ref_f32x16(slice.try_into().unwrap())
4678 }
4679 #[inline(always)]
4680 fn store_slice(&self, slice: &mut [f32]) {
4681 self.simd
4682 .store_array_f32x16(*self, slice.try_into().unwrap());
4683 }
4684 #[inline(always)]
4685 fn splat(simd: S, val: f32) -> Self {
4686 simd.splat_f32x16(val)
4687 }
4688 #[inline(always)]
4689 fn block_splat(block: Self::Block) -> Self {
4690 let block2 = block.simd.combine_f32x4(block, block);
4691 block2.simd.combine_f32x8(block2, block2)
4692 }
4693 #[inline(always)]
4694 fn from_fn(simd: S, f: impl FnMut(usize) -> f32) -> Self {
4695 simd.load_array_f32x16(core::array::from_fn(f))
4696 }
4697 #[inline(always)]
4698 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
4699 self.simd
4700 .slide_f32x16::<SHIFT>(self, rhs.simd_into(self.simd))
4701 }
4702 #[inline(always)]
4703 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
4704 self.simd
4705 .slide_within_blocks_f32x16::<SHIFT>(self, rhs.simd_into(self.simd))
4706 }
4707}
4708impl<S: Simd> crate::SimdFloat<S> for f32x16<S> {
4709 #[inline(always)]
4710 fn abs(self) -> Self {
4711 self.simd.abs_f32x16(self)
4712 }
4713 #[inline(always)]
4714 fn sqrt(self) -> Self {
4715 self.simd.sqrt_f32x16(self)
4716 }
4717 #[inline(always)]
4718 fn copysign(self, rhs: impl SimdInto<Self, S>) -> Self {
4719 self.simd.copysign_f32x16(self, rhs.simd_into(self.simd))
4720 }
4721 #[inline(always)]
4722 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4723 self.simd.simd_eq_f32x16(self, rhs.simd_into(self.simd))
4724 }
4725 #[inline(always)]
4726 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4727 self.simd.simd_lt_f32x16(self, rhs.simd_into(self.simd))
4728 }
4729 #[inline(always)]
4730 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4731 self.simd.simd_le_f32x16(self, rhs.simd_into(self.simd))
4732 }
4733 #[inline(always)]
4734 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4735 self.simd.simd_ge_f32x16(self, rhs.simd_into(self.simd))
4736 }
4737 #[inline(always)]
4738 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4739 self.simd.simd_gt_f32x16(self, rhs.simd_into(self.simd))
4740 }
4741 #[inline(always)]
4742 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
4743 self.simd.zip_low_f32x16(self, rhs.simd_into(self.simd))
4744 }
4745 #[inline(always)]
4746 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
4747 self.simd.zip_high_f32x16(self, rhs.simd_into(self.simd))
4748 }
4749 #[inline(always)]
4750 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
4751 self.simd.unzip_low_f32x16(self, rhs.simd_into(self.simd))
4752 }
4753 #[inline(always)]
4754 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
4755 self.simd.unzip_high_f32x16(self, rhs.simd_into(self.simd))
4756 }
4757 #[inline(always)]
4758 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
4759 self.simd.interleave_f32x16(self, rhs.simd_into(self.simd))
4760 }
4761 #[inline(always)]
4762 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
4763 self.simd
4764 .deinterleave_f32x16(self, rhs.simd_into(self.simd))
4765 }
4766 #[inline(always)]
4767 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
4768 self.simd.max_f32x16(self, rhs.simd_into(self.simd))
4769 }
4770 #[inline(always)]
4771 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
4772 self.simd.min_f32x16(self, rhs.simd_into(self.simd))
4773 }
4774 #[inline(always)]
4775 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
4776 self.simd.max_precise_f32x16(self, rhs.simd_into(self.simd))
4777 }
4778 #[inline(always)]
4779 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
4780 self.simd.min_precise_f32x16(self, rhs.simd_into(self.simd))
4781 }
4782 #[inline(always)]
4783 fn mul_add(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
4784 self.simd
4785 .mul_add_f32x16(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
4786 }
4787 #[inline(always)]
4788 fn mul_sub(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
4789 self.simd
4790 .mul_sub_f32x16(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
4791 }
4792 #[inline(always)]
4793 fn floor(self) -> Self {
4794 self.simd.floor_f32x16(self)
4795 }
4796 #[inline(always)]
4797 fn ceil(self) -> Self {
4798 self.simd.ceil_f32x16(self)
4799 }
4800 #[inline(always)]
4801 fn round_ties_even(self) -> Self {
4802 self.simd.round_ties_even_f32x16(self)
4803 }
4804 #[inline(always)]
4805 fn fract(self) -> Self {
4806 self.simd.fract_f32x16(self)
4807 }
4808 #[inline(always)]
4809 fn trunc(self) -> Self {
4810 self.simd.trunc_f32x16(self)
4811 }
4812}
4813impl<S: Simd> SimdCvtFloat<u32x16<S>> for f32x16<S> {
4814 #[doc = "Convert each unsigned 32-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
4815 #[inline(always)]
4816 fn float_from(x: u32x16<S>) -> Self {
4817 x.simd.cvt_f32_u32x16(x)
4818 }
4819}
4820impl<S: Simd> SimdCvtFloat<i32x16<S>> for f32x16<S> {
4821 #[doc = "Convert each signed 32-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
4822 #[inline(always)]
4823 fn float_from(x: i32x16<S>) -> Self {
4824 x.simd.cvt_f32_i32x16(x)
4825 }
4826}
4827impl<S: Simd> crate::SimdSplit<S> for f32x16<S> {
4828 type Split = f32x8<S>;
4829 #[inline(always)]
4830 fn split(self) -> (Self::Split, Self::Split) {
4831 self.simd.split_f32x16(self)
4832 }
4833}
4834#[doc = "A SIMD vector of 64 [`i8`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, i8x64};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = i8x64::splat(simd, 1);\n let b = i8x64::simd_from(simd, 1);\n\n // From a slice:\n let c = i8x64::from_slice(simd, &[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, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64]);\n\n // From an array:\n let d = i8x64::simd_from(simd, [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, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64]);\n\n // From an element-wise function:\n let e = i8x64::from_fn(simd, |i| i as i8);\n # use fearless_simd::i8x16;\n // From `Self::Block`:\n let f = i8x64::block_splat(i8x16::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]));\n}\n```"]
4835#[derive(Clone, Copy)]
4836#[repr(C, align(64))]
4837pub struct i8x64<S: Simd> {
4838 pub(crate) val: S::i8x64,
4839 pub simd: S,
4840}
4841impl<S: Simd> SimdFrom<[i8; 64], S> for i8x64<S> {
4842 #[inline(always)]
4843 fn simd_from(simd: S, val: [i8; 64]) -> Self {
4844 simd.load_array_i8x64(val)
4845 }
4846}
4847impl<S: Simd> From<i8x64<S>> for [i8; 64] {
4848 #[inline(always)]
4849 fn from(value: i8x64<S>) -> Self {
4850 value.simd.as_array_i8x64(value)
4851 }
4852}
4853impl<S: Simd> core::ops::Deref for i8x64<S> {
4854 type Target = [i8; 64];
4855 #[inline(always)]
4856 fn deref(&self) -> &Self::Target {
4857 self.simd.as_array_ref_i8x64(self)
4858 }
4859}
4860impl<S: Simd> core::ops::DerefMut for i8x64<S> {
4861 #[inline(always)]
4862 fn deref_mut(&mut self) -> &mut Self::Target {
4863 self.simd.as_array_mut_i8x64(self)
4864 }
4865}
4866impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i8x64<S> {
4867 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4868 crate::support::simd_debug_impl(f, "i8x64", &self.simd, self.simd.as_array_ref_i8x64(self))
4869 }
4870}
4871impl<S: Simd> SimdFrom<i8, S> for i8x64<S> {
4872 #[inline(always)]
4873 fn simd_from(simd: S, value: i8) -> Self {
4874 simd.splat_i8x64(value)
4875 }
4876}
4877impl<S: Simd> core::ops::Index<usize> for i8x64<S> {
4878 type Output = i8;
4879 #[inline(always)]
4880 fn index(&self, i: usize) -> &Self::Output {
4881 &self.simd.as_array_ref_i8x64(self)[i]
4882 }
4883}
4884impl<S: Simd> core::ops::IndexMut<usize> for i8x64<S> {
4885 #[inline(always)]
4886 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
4887 &mut self.simd.as_array_mut_i8x64(self)[i]
4888 }
4889}
4890impl<S: Simd> Select<i8x64<S>> for mask8x64<S> {
4891 #[inline(always)]
4892 fn select(self, if_true: i8x64<S>, if_false: i8x64<S>) -> i8x64<S> {
4893 self.simd.select_i8x64(self, if_true, if_false)
4894 }
4895}
4896impl<S: Simd> Bytes for i8x64<S> {
4897 type Bytes = u8x64<S>;
4898 #[inline(always)]
4899 fn to_bytes(self) -> Self::Bytes {
4900 self.simd.cvt_to_bytes_i8x64(self)
4901 }
4902 #[inline(always)]
4903 fn from_bytes(value: Self::Bytes) -> Self {
4904 value.simd.cvt_from_bytes_i8x64(value)
4905 }
4906}
4907impl<S: Simd> SimdBase<S> for i8x64<S> {
4908 type Element = i8;
4909 const N: usize = 64;
4910 type Mask = mask8x64<S>;
4911 type Block = i8x16<S>;
4912 type Array = [i8; 64];
4913 #[inline(always)]
4914 fn witness(&self) -> S {
4915 self.simd
4916 }
4917 #[inline(always)]
4918 fn as_slice(&self) -> &[i8] {
4919 self.simd.as_array_ref_i8x64(self).as_slice()
4920 }
4921 #[inline(always)]
4922 fn as_mut_slice(&mut self) -> &mut [i8] {
4923 self.simd.as_array_mut_i8x64(self).as_mut_slice()
4924 }
4925 #[inline(always)]
4926 fn from_slice(simd: S, slice: &[i8]) -> Self {
4927 simd.load_array_ref_i8x64(slice.try_into().unwrap())
4928 }
4929 #[inline(always)]
4930 fn store_slice(&self, slice: &mut [i8]) {
4931 self.simd
4932 .store_array_i8x64(*self, slice.try_into().unwrap());
4933 }
4934 #[inline(always)]
4935 fn splat(simd: S, val: i8) -> Self {
4936 simd.splat_i8x64(val)
4937 }
4938 #[inline(always)]
4939 fn block_splat(block: Self::Block) -> Self {
4940 let block2 = block.simd.combine_i8x16(block, block);
4941 block2.simd.combine_i8x32(block2, block2)
4942 }
4943 #[inline(always)]
4944 fn from_fn(simd: S, f: impl FnMut(usize) -> i8) -> Self {
4945 simd.load_array_i8x64(core::array::from_fn(f))
4946 }
4947 #[inline(always)]
4948 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
4949 self.simd
4950 .slide_i8x64::<SHIFT>(self, rhs.simd_into(self.simd))
4951 }
4952 #[inline(always)]
4953 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
4954 self.simd
4955 .slide_within_blocks_i8x64::<SHIFT>(self, rhs.simd_into(self.simd))
4956 }
4957}
4958impl<S: Simd> crate::SimdInt<S> for i8x64<S> {
4959 #[inline(always)]
4960 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4961 self.simd.simd_eq_i8x64(self, rhs.simd_into(self.simd))
4962 }
4963 #[inline(always)]
4964 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4965 self.simd.simd_lt_i8x64(self, rhs.simd_into(self.simd))
4966 }
4967 #[inline(always)]
4968 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4969 self.simd.simd_le_i8x64(self, rhs.simd_into(self.simd))
4970 }
4971 #[inline(always)]
4972 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4973 self.simd.simd_ge_i8x64(self, rhs.simd_into(self.simd))
4974 }
4975 #[inline(always)]
4976 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4977 self.simd.simd_gt_i8x64(self, rhs.simd_into(self.simd))
4978 }
4979 #[inline(always)]
4980 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
4981 self.simd.zip_low_i8x64(self, rhs.simd_into(self.simd))
4982 }
4983 #[inline(always)]
4984 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
4985 self.simd.zip_high_i8x64(self, rhs.simd_into(self.simd))
4986 }
4987 #[inline(always)]
4988 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
4989 self.simd.unzip_low_i8x64(self, rhs.simd_into(self.simd))
4990 }
4991 #[inline(always)]
4992 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
4993 self.simd.unzip_high_i8x64(self, rhs.simd_into(self.simd))
4994 }
4995 #[inline(always)]
4996 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
4997 self.simd.interleave_i8x64(self, rhs.simd_into(self.simd))
4998 }
4999 #[inline(always)]
5000 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
5001 self.simd.deinterleave_i8x64(self, rhs.simd_into(self.simd))
5002 }
5003 #[inline(always)]
5004 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
5005 self.simd.min_i8x64(self, rhs.simd_into(self.simd))
5006 }
5007 #[inline(always)]
5008 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
5009 self.simd.max_i8x64(self, rhs.simd_into(self.simd))
5010 }
5011}
5012impl<S: Simd> crate::SimdSplit<S> for i8x64<S> {
5013 type Split = i8x32<S>;
5014 #[inline(always)]
5015 fn split(self) -> (Self::Split, Self::Split) {
5016 self.simd.split_i8x64(self)
5017 }
5018}
5019#[doc = "A SIMD vector of 64 [`u8`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, u8x64};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = u8x64::splat(simd, 1);\n let b = u8x64::simd_from(simd, 1);\n\n // From a slice:\n let c = u8x64::from_slice(simd, &[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, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64]);\n\n // From an array:\n let d = u8x64::simd_from(simd, [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, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64]);\n\n // From an element-wise function:\n let e = u8x64::from_fn(simd, |i| i as u8);\n # use fearless_simd::u8x16;\n // From `Self::Block`:\n let f = u8x64::block_splat(u8x16::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]));\n}\n```"]
5020#[derive(Clone, Copy)]
5021#[repr(C, align(64))]
5022pub struct u8x64<S: Simd> {
5023 pub(crate) val: S::u8x64,
5024 pub simd: S,
5025}
5026impl<S: Simd> SimdFrom<[u8; 64], S> for u8x64<S> {
5027 #[inline(always)]
5028 fn simd_from(simd: S, val: [u8; 64]) -> Self {
5029 simd.load_array_u8x64(val)
5030 }
5031}
5032impl<S: Simd> From<u8x64<S>> for [u8; 64] {
5033 #[inline(always)]
5034 fn from(value: u8x64<S>) -> Self {
5035 value.simd.as_array_u8x64(value)
5036 }
5037}
5038impl<S: Simd> core::ops::Deref for u8x64<S> {
5039 type Target = [u8; 64];
5040 #[inline(always)]
5041 fn deref(&self) -> &Self::Target {
5042 self.simd.as_array_ref_u8x64(self)
5043 }
5044}
5045impl<S: Simd> core::ops::DerefMut for u8x64<S> {
5046 #[inline(always)]
5047 fn deref_mut(&mut self) -> &mut Self::Target {
5048 self.simd.as_array_mut_u8x64(self)
5049 }
5050}
5051impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u8x64<S> {
5052 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5053 crate::support::simd_debug_impl(f, "u8x64", &self.simd, self.simd.as_array_ref_u8x64(self))
5054 }
5055}
5056impl<S: Simd> SimdFrom<u8, S> for u8x64<S> {
5057 #[inline(always)]
5058 fn simd_from(simd: S, value: u8) -> Self {
5059 simd.splat_u8x64(value)
5060 }
5061}
5062impl<S: Simd> core::ops::Index<usize> for u8x64<S> {
5063 type Output = u8;
5064 #[inline(always)]
5065 fn index(&self, i: usize) -> &Self::Output {
5066 &self.simd.as_array_ref_u8x64(self)[i]
5067 }
5068}
5069impl<S: Simd> core::ops::IndexMut<usize> for u8x64<S> {
5070 #[inline(always)]
5071 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
5072 &mut self.simd.as_array_mut_u8x64(self)[i]
5073 }
5074}
5075impl<S: Simd> Select<u8x64<S>> for mask8x64<S> {
5076 #[inline(always)]
5077 fn select(self, if_true: u8x64<S>, if_false: u8x64<S>) -> u8x64<S> {
5078 self.simd.select_u8x64(self, if_true, if_false)
5079 }
5080}
5081impl<S: Simd> Bytes for u8x64<S> {
5082 type Bytes = u8x64<S>;
5083 #[inline(always)]
5084 fn to_bytes(self) -> Self::Bytes {
5085 self.simd.cvt_to_bytes_u8x64(self)
5086 }
5087 #[inline(always)]
5088 fn from_bytes(value: Self::Bytes) -> Self {
5089 value.simd.cvt_from_bytes_u8x64(value)
5090 }
5091}
5092impl<S: Simd> SimdBase<S> for u8x64<S> {
5093 type Element = u8;
5094 const N: usize = 64;
5095 type Mask = mask8x64<S>;
5096 type Block = u8x16<S>;
5097 type Array = [u8; 64];
5098 #[inline(always)]
5099 fn witness(&self) -> S {
5100 self.simd
5101 }
5102 #[inline(always)]
5103 fn as_slice(&self) -> &[u8] {
5104 self.simd.as_array_ref_u8x64(self).as_slice()
5105 }
5106 #[inline(always)]
5107 fn as_mut_slice(&mut self) -> &mut [u8] {
5108 self.simd.as_array_mut_u8x64(self).as_mut_slice()
5109 }
5110 #[inline(always)]
5111 fn from_slice(simd: S, slice: &[u8]) -> Self {
5112 simd.load_array_ref_u8x64(slice.try_into().unwrap())
5113 }
5114 #[inline(always)]
5115 fn store_slice(&self, slice: &mut [u8]) {
5116 self.simd
5117 .store_array_u8x64(*self, slice.try_into().unwrap());
5118 }
5119 #[inline(always)]
5120 fn splat(simd: S, val: u8) -> Self {
5121 simd.splat_u8x64(val)
5122 }
5123 #[inline(always)]
5124 fn block_splat(block: Self::Block) -> Self {
5125 let block2 = block.simd.combine_u8x16(block, block);
5126 block2.simd.combine_u8x32(block2, block2)
5127 }
5128 #[inline(always)]
5129 fn from_fn(simd: S, f: impl FnMut(usize) -> u8) -> Self {
5130 simd.load_array_u8x64(core::array::from_fn(f))
5131 }
5132 #[inline(always)]
5133 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
5134 self.simd
5135 .slide_u8x64::<SHIFT>(self, rhs.simd_into(self.simd))
5136 }
5137 #[inline(always)]
5138 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
5139 self.simd
5140 .slide_within_blocks_u8x64::<SHIFT>(self, rhs.simd_into(self.simd))
5141 }
5142}
5143impl<S: Simd> crate::SimdInt<S> for u8x64<S> {
5144 #[inline(always)]
5145 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5146 self.simd.simd_eq_u8x64(self, rhs.simd_into(self.simd))
5147 }
5148 #[inline(always)]
5149 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5150 self.simd.simd_lt_u8x64(self, rhs.simd_into(self.simd))
5151 }
5152 #[inline(always)]
5153 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5154 self.simd.simd_le_u8x64(self, rhs.simd_into(self.simd))
5155 }
5156 #[inline(always)]
5157 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5158 self.simd.simd_ge_u8x64(self, rhs.simd_into(self.simd))
5159 }
5160 #[inline(always)]
5161 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5162 self.simd.simd_gt_u8x64(self, rhs.simd_into(self.simd))
5163 }
5164 #[inline(always)]
5165 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
5166 self.simd.zip_low_u8x64(self, rhs.simd_into(self.simd))
5167 }
5168 #[inline(always)]
5169 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
5170 self.simd.zip_high_u8x64(self, rhs.simd_into(self.simd))
5171 }
5172 #[inline(always)]
5173 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
5174 self.simd.unzip_low_u8x64(self, rhs.simd_into(self.simd))
5175 }
5176 #[inline(always)]
5177 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
5178 self.simd.unzip_high_u8x64(self, rhs.simd_into(self.simd))
5179 }
5180 #[inline(always)]
5181 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
5182 self.simd.interleave_u8x64(self, rhs.simd_into(self.simd))
5183 }
5184 #[inline(always)]
5185 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
5186 self.simd.deinterleave_u8x64(self, rhs.simd_into(self.simd))
5187 }
5188 #[inline(always)]
5189 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
5190 self.simd.min_u8x64(self, rhs.simd_into(self.simd))
5191 }
5192 #[inline(always)]
5193 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
5194 self.simd.max_u8x64(self, rhs.simd_into(self.simd))
5195 }
5196}
5197impl<S: Simd> crate::SimdSplit<S> for u8x64<S> {
5198 type Split = u8x32<S>;
5199 #[inline(always)]
5200 fn split(self) -> (Self::Split, Self::Split) {
5201 self.simd.split_u8x64(self)
5202 }
5203}
5204#[doc = "A SIMD mask of 64 8-bit elements.\n\nWhen created from a comparison operation, and as it should be used in a [`Self::select`] operation, each element will be all ones if it's \"true\", and all zeroes if it's \"false\"."]
5205#[derive(Clone, Copy)]
5206#[repr(C, align(64))]
5207pub struct mask8x64<S: Simd> {
5208 pub(crate) val: S::mask8x64,
5209 pub simd: S,
5210}
5211impl<S: Simd> SimdFrom<[i8; 64], S> for mask8x64<S> {
5212 #[inline(always)]
5213 fn simd_from(simd: S, val: [i8; 64]) -> Self {
5214 simd.load_array_mask8x64(val)
5215 }
5216}
5217impl<S: Simd> From<mask8x64<S>> for [i8; 64] {
5218 #[inline(always)]
5219 fn from(value: mask8x64<S>) -> Self {
5220 value.simd.as_array_mask8x64(value)
5221 }
5222}
5223impl<S: Simd> core::ops::Deref for mask8x64<S> {
5224 type Target = [i8; 64];
5225 #[inline(always)]
5226 fn deref(&self) -> &Self::Target {
5227 self.simd.as_array_ref_mask8x64(self)
5228 }
5229}
5230impl<S: Simd> core::ops::DerefMut for mask8x64<S> {
5231 #[inline(always)]
5232 fn deref_mut(&mut self) -> &mut Self::Target {
5233 self.simd.as_array_mut_mask8x64(self)
5234 }
5235}
5236impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask8x64<S> {
5237 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5238 crate::support::simd_debug_impl(
5239 f,
5240 "mask8x64",
5241 &self.simd,
5242 self.simd.as_array_ref_mask8x64(self),
5243 )
5244 }
5245}
5246impl<S: Simd> SimdFrom<i8, S> for mask8x64<S> {
5247 #[inline(always)]
5248 fn simd_from(simd: S, value: i8) -> Self {
5249 simd.splat_mask8x64(value)
5250 }
5251}
5252impl<S: Simd> core::ops::Index<usize> for mask8x64<S> {
5253 type Output = i8;
5254 #[inline(always)]
5255 fn index(&self, i: usize) -> &Self::Output {
5256 &self.simd.as_array_ref_mask8x64(self)[i]
5257 }
5258}
5259impl<S: Simd> core::ops::IndexMut<usize> for mask8x64<S> {
5260 #[inline(always)]
5261 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
5262 &mut self.simd.as_array_mut_mask8x64(self)[i]
5263 }
5264}
5265impl<S: Simd> Select<mask8x64<S>> for mask8x64<S> {
5266 #[inline(always)]
5267 fn select(self, if_true: mask8x64<S>, if_false: mask8x64<S>) -> mask8x64<S> {
5268 self.simd.select_mask8x64(self, if_true, if_false)
5269 }
5270}
5271impl<S: Simd> Bytes for mask8x64<S> {
5272 type Bytes = u8x64<S>;
5273 #[inline(always)]
5274 fn to_bytes(self) -> Self::Bytes {
5275 self.simd.cvt_to_bytes_mask8x64(self)
5276 }
5277 #[inline(always)]
5278 fn from_bytes(value: Self::Bytes) -> Self {
5279 value.simd.cvt_from_bytes_mask8x64(value)
5280 }
5281}
5282impl<S: Simd> SimdBase<S> for mask8x64<S> {
5283 type Element = i8;
5284 const N: usize = 64;
5285 type Mask = mask8x64<S>;
5286 type Block = mask8x16<S>;
5287 type Array = [i8; 64];
5288 #[inline(always)]
5289 fn witness(&self) -> S {
5290 self.simd
5291 }
5292 #[inline(always)]
5293 fn as_slice(&self) -> &[i8] {
5294 self.simd.as_array_ref_mask8x64(self).as_slice()
5295 }
5296 #[inline(always)]
5297 fn as_mut_slice(&mut self) -> &mut [i8] {
5298 self.simd.as_array_mut_mask8x64(self).as_mut_slice()
5299 }
5300 #[inline(always)]
5301 fn from_slice(simd: S, slice: &[i8]) -> Self {
5302 simd.load_array_ref_mask8x64(slice.try_into().unwrap())
5303 }
5304 #[inline(always)]
5305 fn store_slice(&self, slice: &mut [i8]) {
5306 self.simd
5307 .store_array_mask8x64(*self, slice.try_into().unwrap());
5308 }
5309 #[inline(always)]
5310 fn splat(simd: S, val: i8) -> Self {
5311 simd.splat_mask8x64(val)
5312 }
5313 #[inline(always)]
5314 fn block_splat(block: Self::Block) -> Self {
5315 let block2 = block.simd.combine_mask8x16(block, block);
5316 block2.simd.combine_mask8x32(block2, block2)
5317 }
5318 #[inline(always)]
5319 fn from_fn(simd: S, f: impl FnMut(usize) -> i8) -> Self {
5320 simd.load_array_mask8x64(core::array::from_fn(f))
5321 }
5322 #[inline(always)]
5323 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
5324 self.simd
5325 .slide_mask8x64::<SHIFT>(self, rhs.simd_into(self.simd))
5326 }
5327 #[inline(always)]
5328 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
5329 self.simd
5330 .slide_within_blocks_mask8x64::<SHIFT>(self, rhs.simd_into(self.simd))
5331 }
5332}
5333impl<S: Simd> crate::SimdMask<S> for mask8x64<S> {
5334 #[inline(always)]
5335 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5336 self.simd.simd_eq_mask8x64(self, rhs.simd_into(self.simd))
5337 }
5338 #[inline(always)]
5339 fn any_true(self) -> bool {
5340 self.simd.any_true_mask8x64(self)
5341 }
5342 #[inline(always)]
5343 fn all_true(self) -> bool {
5344 self.simd.all_true_mask8x64(self)
5345 }
5346 #[inline(always)]
5347 fn any_false(self) -> bool {
5348 self.simd.any_false_mask8x64(self)
5349 }
5350 #[inline(always)]
5351 fn all_false(self) -> bool {
5352 self.simd.all_false_mask8x64(self)
5353 }
5354}
5355impl<S: Simd> crate::SimdSplit<S> for mask8x64<S> {
5356 type Split = mask8x32<S>;
5357 #[inline(always)]
5358 fn split(self) -> (Self::Split, Self::Split) {
5359 self.simd.split_mask8x64(self)
5360 }
5361}
5362#[doc = "A SIMD vector of 32 [`i16`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, i16x32};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = i16x32::splat(simd, 1);\n let b = i16x32::simd_from(simd, 1);\n\n // From a slice:\n let c = i16x32::from_slice(simd, &[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, 26, 27, 28, 29, 30, 31, 32]);\n\n // From an array:\n let d = i16x32::simd_from(simd, [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, 26, 27, 28, 29, 30, 31, 32]);\n\n // From an element-wise function:\n let e = i16x32::from_fn(simd, |i| i as i16);\n # use fearless_simd::i16x8;\n // From `Self::Block`:\n let f = i16x32::block_splat(i16x8::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8]));\n}\n```"]
5363#[derive(Clone, Copy)]
5364#[repr(C, align(64))]
5365pub struct i16x32<S: Simd> {
5366 pub(crate) val: S::i16x32,
5367 pub simd: S,
5368}
5369impl<S: Simd> SimdFrom<[i16; 32], S> for i16x32<S> {
5370 #[inline(always)]
5371 fn simd_from(simd: S, val: [i16; 32]) -> Self {
5372 simd.load_array_i16x32(val)
5373 }
5374}
5375impl<S: Simd> From<i16x32<S>> for [i16; 32] {
5376 #[inline(always)]
5377 fn from(value: i16x32<S>) -> Self {
5378 value.simd.as_array_i16x32(value)
5379 }
5380}
5381impl<S: Simd> core::ops::Deref for i16x32<S> {
5382 type Target = [i16; 32];
5383 #[inline(always)]
5384 fn deref(&self) -> &Self::Target {
5385 self.simd.as_array_ref_i16x32(self)
5386 }
5387}
5388impl<S: Simd> core::ops::DerefMut for i16x32<S> {
5389 #[inline(always)]
5390 fn deref_mut(&mut self) -> &mut Self::Target {
5391 self.simd.as_array_mut_i16x32(self)
5392 }
5393}
5394impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i16x32<S> {
5395 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5396 crate::support::simd_debug_impl(
5397 f,
5398 "i16x32",
5399 &self.simd,
5400 self.simd.as_array_ref_i16x32(self),
5401 )
5402 }
5403}
5404impl<S: Simd> SimdFrom<i16, S> for i16x32<S> {
5405 #[inline(always)]
5406 fn simd_from(simd: S, value: i16) -> Self {
5407 simd.splat_i16x32(value)
5408 }
5409}
5410impl<S: Simd> core::ops::Index<usize> for i16x32<S> {
5411 type Output = i16;
5412 #[inline(always)]
5413 fn index(&self, i: usize) -> &Self::Output {
5414 &self.simd.as_array_ref_i16x32(self)[i]
5415 }
5416}
5417impl<S: Simd> core::ops::IndexMut<usize> for i16x32<S> {
5418 #[inline(always)]
5419 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
5420 &mut self.simd.as_array_mut_i16x32(self)[i]
5421 }
5422}
5423impl<S: Simd> Select<i16x32<S>> for mask16x32<S> {
5424 #[inline(always)]
5425 fn select(self, if_true: i16x32<S>, if_false: i16x32<S>) -> i16x32<S> {
5426 self.simd.select_i16x32(self, if_true, if_false)
5427 }
5428}
5429impl<S: Simd> Bytes for i16x32<S> {
5430 type Bytes = u8x64<S>;
5431 #[inline(always)]
5432 fn to_bytes(self) -> Self::Bytes {
5433 self.simd.cvt_to_bytes_i16x32(self)
5434 }
5435 #[inline(always)]
5436 fn from_bytes(value: Self::Bytes) -> Self {
5437 value.simd.cvt_from_bytes_i16x32(value)
5438 }
5439}
5440impl<S: Simd> SimdBase<S> for i16x32<S> {
5441 type Element = i16;
5442 const N: usize = 32;
5443 type Mask = mask16x32<S>;
5444 type Block = i16x8<S>;
5445 type Array = [i16; 32];
5446 #[inline(always)]
5447 fn witness(&self) -> S {
5448 self.simd
5449 }
5450 #[inline(always)]
5451 fn as_slice(&self) -> &[i16] {
5452 self.simd.as_array_ref_i16x32(self).as_slice()
5453 }
5454 #[inline(always)]
5455 fn as_mut_slice(&mut self) -> &mut [i16] {
5456 self.simd.as_array_mut_i16x32(self).as_mut_slice()
5457 }
5458 #[inline(always)]
5459 fn from_slice(simd: S, slice: &[i16]) -> Self {
5460 simd.load_array_ref_i16x32(slice.try_into().unwrap())
5461 }
5462 #[inline(always)]
5463 fn store_slice(&self, slice: &mut [i16]) {
5464 self.simd
5465 .store_array_i16x32(*self, slice.try_into().unwrap());
5466 }
5467 #[inline(always)]
5468 fn splat(simd: S, val: i16) -> Self {
5469 simd.splat_i16x32(val)
5470 }
5471 #[inline(always)]
5472 fn block_splat(block: Self::Block) -> Self {
5473 let block2 = block.simd.combine_i16x8(block, block);
5474 block2.simd.combine_i16x16(block2, block2)
5475 }
5476 #[inline(always)]
5477 fn from_fn(simd: S, f: impl FnMut(usize) -> i16) -> Self {
5478 simd.load_array_i16x32(core::array::from_fn(f))
5479 }
5480 #[inline(always)]
5481 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
5482 self.simd
5483 .slide_i16x32::<SHIFT>(self, rhs.simd_into(self.simd))
5484 }
5485 #[inline(always)]
5486 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
5487 self.simd
5488 .slide_within_blocks_i16x32::<SHIFT>(self, rhs.simd_into(self.simd))
5489 }
5490}
5491impl<S: Simd> crate::SimdInt<S> for i16x32<S> {
5492 #[inline(always)]
5493 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5494 self.simd.simd_eq_i16x32(self, rhs.simd_into(self.simd))
5495 }
5496 #[inline(always)]
5497 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5498 self.simd.simd_lt_i16x32(self, rhs.simd_into(self.simd))
5499 }
5500 #[inline(always)]
5501 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5502 self.simd.simd_le_i16x32(self, rhs.simd_into(self.simd))
5503 }
5504 #[inline(always)]
5505 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5506 self.simd.simd_ge_i16x32(self, rhs.simd_into(self.simd))
5507 }
5508 #[inline(always)]
5509 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5510 self.simd.simd_gt_i16x32(self, rhs.simd_into(self.simd))
5511 }
5512 #[inline(always)]
5513 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
5514 self.simd.zip_low_i16x32(self, rhs.simd_into(self.simd))
5515 }
5516 #[inline(always)]
5517 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
5518 self.simd.zip_high_i16x32(self, rhs.simd_into(self.simd))
5519 }
5520 #[inline(always)]
5521 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
5522 self.simd.unzip_low_i16x32(self, rhs.simd_into(self.simd))
5523 }
5524 #[inline(always)]
5525 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
5526 self.simd.unzip_high_i16x32(self, rhs.simd_into(self.simd))
5527 }
5528 #[inline(always)]
5529 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
5530 self.simd.interleave_i16x32(self, rhs.simd_into(self.simd))
5531 }
5532 #[inline(always)]
5533 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
5534 self.simd
5535 .deinterleave_i16x32(self, rhs.simd_into(self.simd))
5536 }
5537 #[inline(always)]
5538 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
5539 self.simd.min_i16x32(self, rhs.simd_into(self.simd))
5540 }
5541 #[inline(always)]
5542 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
5543 self.simd.max_i16x32(self, rhs.simd_into(self.simd))
5544 }
5545}
5546impl<S: Simd> crate::SimdSplit<S> for i16x32<S> {
5547 type Split = i16x16<S>;
5548 #[inline(always)]
5549 fn split(self) -> (Self::Split, Self::Split) {
5550 self.simd.split_i16x32(self)
5551 }
5552}
5553#[doc = "A SIMD vector of 32 [`u16`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, u16x32};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = u16x32::splat(simd, 1);\n let b = u16x32::simd_from(simd, 1);\n\n // From a slice:\n let c = u16x32::from_slice(simd, &[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, 26, 27, 28, 29, 30, 31, 32]);\n\n // From an array:\n let d = u16x32::simd_from(simd, [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, 26, 27, 28, 29, 30, 31, 32]);\n\n // From an element-wise function:\n let e = u16x32::from_fn(simd, |i| i as u16);\n # use fearless_simd::u16x8;\n // From `Self::Block`:\n let f = u16x32::block_splat(u16x8::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8]));\n}\n```"]
5554#[derive(Clone, Copy)]
5555#[repr(C, align(64))]
5556pub struct u16x32<S: Simd> {
5557 pub(crate) val: S::u16x32,
5558 pub simd: S,
5559}
5560impl<S: Simd> SimdFrom<[u16; 32], S> for u16x32<S> {
5561 #[inline(always)]
5562 fn simd_from(simd: S, val: [u16; 32]) -> Self {
5563 simd.load_array_u16x32(val)
5564 }
5565}
5566impl<S: Simd> From<u16x32<S>> for [u16; 32] {
5567 #[inline(always)]
5568 fn from(value: u16x32<S>) -> Self {
5569 value.simd.as_array_u16x32(value)
5570 }
5571}
5572impl<S: Simd> core::ops::Deref for u16x32<S> {
5573 type Target = [u16; 32];
5574 #[inline(always)]
5575 fn deref(&self) -> &Self::Target {
5576 self.simd.as_array_ref_u16x32(self)
5577 }
5578}
5579impl<S: Simd> core::ops::DerefMut for u16x32<S> {
5580 #[inline(always)]
5581 fn deref_mut(&mut self) -> &mut Self::Target {
5582 self.simd.as_array_mut_u16x32(self)
5583 }
5584}
5585impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u16x32<S> {
5586 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5587 crate::support::simd_debug_impl(
5588 f,
5589 "u16x32",
5590 &self.simd,
5591 self.simd.as_array_ref_u16x32(self),
5592 )
5593 }
5594}
5595impl<S: Simd> SimdFrom<u16, S> for u16x32<S> {
5596 #[inline(always)]
5597 fn simd_from(simd: S, value: u16) -> Self {
5598 simd.splat_u16x32(value)
5599 }
5600}
5601impl<S: Simd> core::ops::Index<usize> for u16x32<S> {
5602 type Output = u16;
5603 #[inline(always)]
5604 fn index(&self, i: usize) -> &Self::Output {
5605 &self.simd.as_array_ref_u16x32(self)[i]
5606 }
5607}
5608impl<S: Simd> core::ops::IndexMut<usize> for u16x32<S> {
5609 #[inline(always)]
5610 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
5611 &mut self.simd.as_array_mut_u16x32(self)[i]
5612 }
5613}
5614impl<S: Simd> Select<u16x32<S>> for mask16x32<S> {
5615 #[inline(always)]
5616 fn select(self, if_true: u16x32<S>, if_false: u16x32<S>) -> u16x32<S> {
5617 self.simd.select_u16x32(self, if_true, if_false)
5618 }
5619}
5620impl<S: Simd> Bytes for u16x32<S> {
5621 type Bytes = u8x64<S>;
5622 #[inline(always)]
5623 fn to_bytes(self) -> Self::Bytes {
5624 self.simd.cvt_to_bytes_u16x32(self)
5625 }
5626 #[inline(always)]
5627 fn from_bytes(value: Self::Bytes) -> Self {
5628 value.simd.cvt_from_bytes_u16x32(value)
5629 }
5630}
5631impl<S: Simd> SimdBase<S> for u16x32<S> {
5632 type Element = u16;
5633 const N: usize = 32;
5634 type Mask = mask16x32<S>;
5635 type Block = u16x8<S>;
5636 type Array = [u16; 32];
5637 #[inline(always)]
5638 fn witness(&self) -> S {
5639 self.simd
5640 }
5641 #[inline(always)]
5642 fn as_slice(&self) -> &[u16] {
5643 self.simd.as_array_ref_u16x32(self).as_slice()
5644 }
5645 #[inline(always)]
5646 fn as_mut_slice(&mut self) -> &mut [u16] {
5647 self.simd.as_array_mut_u16x32(self).as_mut_slice()
5648 }
5649 #[inline(always)]
5650 fn from_slice(simd: S, slice: &[u16]) -> Self {
5651 simd.load_array_ref_u16x32(slice.try_into().unwrap())
5652 }
5653 #[inline(always)]
5654 fn store_slice(&self, slice: &mut [u16]) {
5655 self.simd
5656 .store_array_u16x32(*self, slice.try_into().unwrap());
5657 }
5658 #[inline(always)]
5659 fn splat(simd: S, val: u16) -> Self {
5660 simd.splat_u16x32(val)
5661 }
5662 #[inline(always)]
5663 fn block_splat(block: Self::Block) -> Self {
5664 let block2 = block.simd.combine_u16x8(block, block);
5665 block2.simd.combine_u16x16(block2, block2)
5666 }
5667 #[inline(always)]
5668 fn from_fn(simd: S, f: impl FnMut(usize) -> u16) -> Self {
5669 simd.load_array_u16x32(core::array::from_fn(f))
5670 }
5671 #[inline(always)]
5672 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
5673 self.simd
5674 .slide_u16x32::<SHIFT>(self, rhs.simd_into(self.simd))
5675 }
5676 #[inline(always)]
5677 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
5678 self.simd
5679 .slide_within_blocks_u16x32::<SHIFT>(self, rhs.simd_into(self.simd))
5680 }
5681}
5682impl<S: Simd> crate::SimdInt<S> for u16x32<S> {
5683 #[inline(always)]
5684 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5685 self.simd.simd_eq_u16x32(self, rhs.simd_into(self.simd))
5686 }
5687 #[inline(always)]
5688 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5689 self.simd.simd_lt_u16x32(self, rhs.simd_into(self.simd))
5690 }
5691 #[inline(always)]
5692 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5693 self.simd.simd_le_u16x32(self, rhs.simd_into(self.simd))
5694 }
5695 #[inline(always)]
5696 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5697 self.simd.simd_ge_u16x32(self, rhs.simd_into(self.simd))
5698 }
5699 #[inline(always)]
5700 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5701 self.simd.simd_gt_u16x32(self, rhs.simd_into(self.simd))
5702 }
5703 #[inline(always)]
5704 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
5705 self.simd.zip_low_u16x32(self, rhs.simd_into(self.simd))
5706 }
5707 #[inline(always)]
5708 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
5709 self.simd.zip_high_u16x32(self, rhs.simd_into(self.simd))
5710 }
5711 #[inline(always)]
5712 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
5713 self.simd.unzip_low_u16x32(self, rhs.simd_into(self.simd))
5714 }
5715 #[inline(always)]
5716 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
5717 self.simd.unzip_high_u16x32(self, rhs.simd_into(self.simd))
5718 }
5719 #[inline(always)]
5720 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
5721 self.simd.interleave_u16x32(self, rhs.simd_into(self.simd))
5722 }
5723 #[inline(always)]
5724 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
5725 self.simd
5726 .deinterleave_u16x32(self, rhs.simd_into(self.simd))
5727 }
5728 #[inline(always)]
5729 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
5730 self.simd.min_u16x32(self, rhs.simd_into(self.simd))
5731 }
5732 #[inline(always)]
5733 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
5734 self.simd.max_u16x32(self, rhs.simd_into(self.simd))
5735 }
5736}
5737impl<S: Simd> crate::SimdSplit<S> for u16x32<S> {
5738 type Split = u16x16<S>;
5739 #[inline(always)]
5740 fn split(self) -> (Self::Split, Self::Split) {
5741 self.simd.split_u16x32(self)
5742 }
5743}
5744#[doc = "A SIMD mask of 32 16-bit elements.\n\nWhen created from a comparison operation, and as it should be used in a [`Self::select`] operation, each element will be all ones if it's \"true\", and all zeroes if it's \"false\"."]
5745#[derive(Clone, Copy)]
5746#[repr(C, align(64))]
5747pub struct mask16x32<S: Simd> {
5748 pub(crate) val: S::mask16x32,
5749 pub simd: S,
5750}
5751impl<S: Simd> SimdFrom<[i16; 32], S> for mask16x32<S> {
5752 #[inline(always)]
5753 fn simd_from(simd: S, val: [i16; 32]) -> Self {
5754 simd.load_array_mask16x32(val)
5755 }
5756}
5757impl<S: Simd> From<mask16x32<S>> for [i16; 32] {
5758 #[inline(always)]
5759 fn from(value: mask16x32<S>) -> Self {
5760 value.simd.as_array_mask16x32(value)
5761 }
5762}
5763impl<S: Simd> core::ops::Deref for mask16x32<S> {
5764 type Target = [i16; 32];
5765 #[inline(always)]
5766 fn deref(&self) -> &Self::Target {
5767 self.simd.as_array_ref_mask16x32(self)
5768 }
5769}
5770impl<S: Simd> core::ops::DerefMut for mask16x32<S> {
5771 #[inline(always)]
5772 fn deref_mut(&mut self) -> &mut Self::Target {
5773 self.simd.as_array_mut_mask16x32(self)
5774 }
5775}
5776impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask16x32<S> {
5777 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5778 crate::support::simd_debug_impl(
5779 f,
5780 "mask16x32",
5781 &self.simd,
5782 self.simd.as_array_ref_mask16x32(self),
5783 )
5784 }
5785}
5786impl<S: Simd> SimdFrom<i16, S> for mask16x32<S> {
5787 #[inline(always)]
5788 fn simd_from(simd: S, value: i16) -> Self {
5789 simd.splat_mask16x32(value)
5790 }
5791}
5792impl<S: Simd> core::ops::Index<usize> for mask16x32<S> {
5793 type Output = i16;
5794 #[inline(always)]
5795 fn index(&self, i: usize) -> &Self::Output {
5796 &self.simd.as_array_ref_mask16x32(self)[i]
5797 }
5798}
5799impl<S: Simd> core::ops::IndexMut<usize> for mask16x32<S> {
5800 #[inline(always)]
5801 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
5802 &mut self.simd.as_array_mut_mask16x32(self)[i]
5803 }
5804}
5805impl<S: Simd> Select<mask16x32<S>> for mask16x32<S> {
5806 #[inline(always)]
5807 fn select(self, if_true: mask16x32<S>, if_false: mask16x32<S>) -> mask16x32<S> {
5808 self.simd.select_mask16x32(self, if_true, if_false)
5809 }
5810}
5811impl<S: Simd> Bytes for mask16x32<S> {
5812 type Bytes = u8x64<S>;
5813 #[inline(always)]
5814 fn to_bytes(self) -> Self::Bytes {
5815 self.simd.cvt_to_bytes_mask16x32(self)
5816 }
5817 #[inline(always)]
5818 fn from_bytes(value: Self::Bytes) -> Self {
5819 value.simd.cvt_from_bytes_mask16x32(value)
5820 }
5821}
5822impl<S: Simd> SimdBase<S> for mask16x32<S> {
5823 type Element = i16;
5824 const N: usize = 32;
5825 type Mask = mask16x32<S>;
5826 type Block = mask16x8<S>;
5827 type Array = [i16; 32];
5828 #[inline(always)]
5829 fn witness(&self) -> S {
5830 self.simd
5831 }
5832 #[inline(always)]
5833 fn as_slice(&self) -> &[i16] {
5834 self.simd.as_array_ref_mask16x32(self).as_slice()
5835 }
5836 #[inline(always)]
5837 fn as_mut_slice(&mut self) -> &mut [i16] {
5838 self.simd.as_array_mut_mask16x32(self).as_mut_slice()
5839 }
5840 #[inline(always)]
5841 fn from_slice(simd: S, slice: &[i16]) -> Self {
5842 simd.load_array_ref_mask16x32(slice.try_into().unwrap())
5843 }
5844 #[inline(always)]
5845 fn store_slice(&self, slice: &mut [i16]) {
5846 self.simd
5847 .store_array_mask16x32(*self, slice.try_into().unwrap());
5848 }
5849 #[inline(always)]
5850 fn splat(simd: S, val: i16) -> Self {
5851 simd.splat_mask16x32(val)
5852 }
5853 #[inline(always)]
5854 fn block_splat(block: Self::Block) -> Self {
5855 let block2 = block.simd.combine_mask16x8(block, block);
5856 block2.simd.combine_mask16x16(block2, block2)
5857 }
5858 #[inline(always)]
5859 fn from_fn(simd: S, f: impl FnMut(usize) -> i16) -> Self {
5860 simd.load_array_mask16x32(core::array::from_fn(f))
5861 }
5862 #[inline(always)]
5863 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
5864 self.simd
5865 .slide_mask16x32::<SHIFT>(self, rhs.simd_into(self.simd))
5866 }
5867 #[inline(always)]
5868 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
5869 self.simd
5870 .slide_within_blocks_mask16x32::<SHIFT>(self, rhs.simd_into(self.simd))
5871 }
5872}
5873impl<S: Simd> crate::SimdMask<S> for mask16x32<S> {
5874 #[inline(always)]
5875 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5876 self.simd.simd_eq_mask16x32(self, rhs.simd_into(self.simd))
5877 }
5878 #[inline(always)]
5879 fn any_true(self) -> bool {
5880 self.simd.any_true_mask16x32(self)
5881 }
5882 #[inline(always)]
5883 fn all_true(self) -> bool {
5884 self.simd.all_true_mask16x32(self)
5885 }
5886 #[inline(always)]
5887 fn any_false(self) -> bool {
5888 self.simd.any_false_mask16x32(self)
5889 }
5890 #[inline(always)]
5891 fn all_false(self) -> bool {
5892 self.simd.all_false_mask16x32(self)
5893 }
5894}
5895impl<S: Simd> crate::SimdSplit<S> for mask16x32<S> {
5896 type Split = mask16x16<S>;
5897 #[inline(always)]
5898 fn split(self) -> (Self::Split, Self::Split) {
5899 self.simd.split_mask16x32(self)
5900 }
5901}
5902#[doc = "A SIMD vector of 16 [`i32`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, i32x16};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = i32x16::splat(simd, 1);\n let b = i32x16::simd_from(simd, 1);\n\n // From a slice:\n let c = i32x16::from_slice(simd, &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);\n\n // From an array:\n let d = i32x16::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);\n\n // From an element-wise function:\n let e = i32x16::from_fn(simd, |i| i as i32);\n # use fearless_simd::i32x4;\n // From `Self::Block`:\n let f = i32x16::block_splat(i32x4::simd_from(simd, [1, 2, 3, 4]));\n}\n```"]
5903#[derive(Clone, Copy)]
5904#[repr(C, align(64))]
5905pub struct i32x16<S: Simd> {
5906 pub(crate) val: S::i32x16,
5907 pub simd: S,
5908}
5909impl<S: Simd> SimdFrom<[i32; 16], S> for i32x16<S> {
5910 #[inline(always)]
5911 fn simd_from(simd: S, val: [i32; 16]) -> Self {
5912 simd.load_array_i32x16(val)
5913 }
5914}
5915impl<S: Simd> From<i32x16<S>> for [i32; 16] {
5916 #[inline(always)]
5917 fn from(value: i32x16<S>) -> Self {
5918 value.simd.as_array_i32x16(value)
5919 }
5920}
5921impl<S: Simd> core::ops::Deref for i32x16<S> {
5922 type Target = [i32; 16];
5923 #[inline(always)]
5924 fn deref(&self) -> &Self::Target {
5925 self.simd.as_array_ref_i32x16(self)
5926 }
5927}
5928impl<S: Simd> core::ops::DerefMut for i32x16<S> {
5929 #[inline(always)]
5930 fn deref_mut(&mut self) -> &mut Self::Target {
5931 self.simd.as_array_mut_i32x16(self)
5932 }
5933}
5934impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i32x16<S> {
5935 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5936 crate::support::simd_debug_impl(
5937 f,
5938 "i32x16",
5939 &self.simd,
5940 self.simd.as_array_ref_i32x16(self),
5941 )
5942 }
5943}
5944impl<S: Simd> SimdFrom<i32, S> for i32x16<S> {
5945 #[inline(always)]
5946 fn simd_from(simd: S, value: i32) -> Self {
5947 simd.splat_i32x16(value)
5948 }
5949}
5950impl<S: Simd> core::ops::Index<usize> for i32x16<S> {
5951 type Output = i32;
5952 #[inline(always)]
5953 fn index(&self, i: usize) -> &Self::Output {
5954 &self.simd.as_array_ref_i32x16(self)[i]
5955 }
5956}
5957impl<S: Simd> core::ops::IndexMut<usize> for i32x16<S> {
5958 #[inline(always)]
5959 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
5960 &mut self.simd.as_array_mut_i32x16(self)[i]
5961 }
5962}
5963impl<S: Simd> Select<i32x16<S>> for mask32x16<S> {
5964 #[inline(always)]
5965 fn select(self, if_true: i32x16<S>, if_false: i32x16<S>) -> i32x16<S> {
5966 self.simd.select_i32x16(self, if_true, if_false)
5967 }
5968}
5969impl<S: Simd> Bytes for i32x16<S> {
5970 type Bytes = u8x64<S>;
5971 #[inline(always)]
5972 fn to_bytes(self) -> Self::Bytes {
5973 self.simd.cvt_to_bytes_i32x16(self)
5974 }
5975 #[inline(always)]
5976 fn from_bytes(value: Self::Bytes) -> Self {
5977 value.simd.cvt_from_bytes_i32x16(value)
5978 }
5979}
5980impl<S: Simd> SimdBase<S> for i32x16<S> {
5981 type Element = i32;
5982 const N: usize = 16;
5983 type Mask = mask32x16<S>;
5984 type Block = i32x4<S>;
5985 type Array = [i32; 16];
5986 #[inline(always)]
5987 fn witness(&self) -> S {
5988 self.simd
5989 }
5990 #[inline(always)]
5991 fn as_slice(&self) -> &[i32] {
5992 self.simd.as_array_ref_i32x16(self).as_slice()
5993 }
5994 #[inline(always)]
5995 fn as_mut_slice(&mut self) -> &mut [i32] {
5996 self.simd.as_array_mut_i32x16(self).as_mut_slice()
5997 }
5998 #[inline(always)]
5999 fn from_slice(simd: S, slice: &[i32]) -> Self {
6000 simd.load_array_ref_i32x16(slice.try_into().unwrap())
6001 }
6002 #[inline(always)]
6003 fn store_slice(&self, slice: &mut [i32]) {
6004 self.simd
6005 .store_array_i32x16(*self, slice.try_into().unwrap());
6006 }
6007 #[inline(always)]
6008 fn splat(simd: S, val: i32) -> Self {
6009 simd.splat_i32x16(val)
6010 }
6011 #[inline(always)]
6012 fn block_splat(block: Self::Block) -> Self {
6013 let block2 = block.simd.combine_i32x4(block, block);
6014 block2.simd.combine_i32x8(block2, block2)
6015 }
6016 #[inline(always)]
6017 fn from_fn(simd: S, f: impl FnMut(usize) -> i32) -> Self {
6018 simd.load_array_i32x16(core::array::from_fn(f))
6019 }
6020 #[inline(always)]
6021 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
6022 self.simd
6023 .slide_i32x16::<SHIFT>(self, rhs.simd_into(self.simd))
6024 }
6025 #[inline(always)]
6026 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
6027 self.simd
6028 .slide_within_blocks_i32x16::<SHIFT>(self, rhs.simd_into(self.simd))
6029 }
6030}
6031impl<S: Simd> crate::SimdInt<S> for i32x16<S> {
6032 #[inline(always)]
6033 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6034 self.simd.simd_eq_i32x16(self, rhs.simd_into(self.simd))
6035 }
6036 #[inline(always)]
6037 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6038 self.simd.simd_lt_i32x16(self, rhs.simd_into(self.simd))
6039 }
6040 #[inline(always)]
6041 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6042 self.simd.simd_le_i32x16(self, rhs.simd_into(self.simd))
6043 }
6044 #[inline(always)]
6045 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6046 self.simd.simd_ge_i32x16(self, rhs.simd_into(self.simd))
6047 }
6048 #[inline(always)]
6049 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6050 self.simd.simd_gt_i32x16(self, rhs.simd_into(self.simd))
6051 }
6052 #[inline(always)]
6053 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
6054 self.simd.zip_low_i32x16(self, rhs.simd_into(self.simd))
6055 }
6056 #[inline(always)]
6057 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
6058 self.simd.zip_high_i32x16(self, rhs.simd_into(self.simd))
6059 }
6060 #[inline(always)]
6061 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
6062 self.simd.unzip_low_i32x16(self, rhs.simd_into(self.simd))
6063 }
6064 #[inline(always)]
6065 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
6066 self.simd.unzip_high_i32x16(self, rhs.simd_into(self.simd))
6067 }
6068 #[inline(always)]
6069 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
6070 self.simd.interleave_i32x16(self, rhs.simd_into(self.simd))
6071 }
6072 #[inline(always)]
6073 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
6074 self.simd
6075 .deinterleave_i32x16(self, rhs.simd_into(self.simd))
6076 }
6077 #[inline(always)]
6078 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
6079 self.simd.min_i32x16(self, rhs.simd_into(self.simd))
6080 }
6081 #[inline(always)]
6082 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
6083 self.simd.max_i32x16(self, rhs.simd_into(self.simd))
6084 }
6085}
6086impl<S: Simd> SimdCvtTruncate<f32x16<S>> for i32x16<S> {
6087 #[doc = "Convert each floating-point element to a signed 32-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
6088 #[inline(always)]
6089 fn truncate_from(x: f32x16<S>) -> Self {
6090 x.simd.cvt_i32_f32x16(x)
6091 }
6092 #[doc = "Convert each floating-point element to a signed 32-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
6093 #[inline(always)]
6094 fn truncate_from_precise(x: f32x16<S>) -> Self {
6095 x.simd.cvt_i32_precise_f32x16(x)
6096 }
6097}
6098impl<S: Simd> crate::SimdSplit<S> for i32x16<S> {
6099 type Split = i32x8<S>;
6100 #[inline(always)]
6101 fn split(self) -> (Self::Split, Self::Split) {
6102 self.simd.split_i32x16(self)
6103 }
6104}
6105#[doc = "A SIMD vector of 16 [`u32`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, u32x16};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = u32x16::splat(simd, 1);\n let b = u32x16::simd_from(simd, 1);\n\n // From a slice:\n let c = u32x16::from_slice(simd, &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);\n\n // From an array:\n let d = u32x16::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);\n\n // From an element-wise function:\n let e = u32x16::from_fn(simd, |i| i as u32);\n # use fearless_simd::u32x4;\n // From `Self::Block`:\n let f = u32x16::block_splat(u32x4::simd_from(simd, [1, 2, 3, 4]));\n}\n```"]
6106#[derive(Clone, Copy)]
6107#[repr(C, align(64))]
6108pub struct u32x16<S: Simd> {
6109 pub(crate) val: S::u32x16,
6110 pub simd: S,
6111}
6112impl<S: Simd> SimdFrom<[u32; 16], S> for u32x16<S> {
6113 #[inline(always)]
6114 fn simd_from(simd: S, val: [u32; 16]) -> Self {
6115 simd.load_array_u32x16(val)
6116 }
6117}
6118impl<S: Simd> From<u32x16<S>> for [u32; 16] {
6119 #[inline(always)]
6120 fn from(value: u32x16<S>) -> Self {
6121 value.simd.as_array_u32x16(value)
6122 }
6123}
6124impl<S: Simd> core::ops::Deref for u32x16<S> {
6125 type Target = [u32; 16];
6126 #[inline(always)]
6127 fn deref(&self) -> &Self::Target {
6128 self.simd.as_array_ref_u32x16(self)
6129 }
6130}
6131impl<S: Simd> core::ops::DerefMut for u32x16<S> {
6132 #[inline(always)]
6133 fn deref_mut(&mut self) -> &mut Self::Target {
6134 self.simd.as_array_mut_u32x16(self)
6135 }
6136}
6137impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u32x16<S> {
6138 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
6139 crate::support::simd_debug_impl(
6140 f,
6141 "u32x16",
6142 &self.simd,
6143 self.simd.as_array_ref_u32x16(self),
6144 )
6145 }
6146}
6147impl<S: Simd> SimdFrom<u32, S> for u32x16<S> {
6148 #[inline(always)]
6149 fn simd_from(simd: S, value: u32) -> Self {
6150 simd.splat_u32x16(value)
6151 }
6152}
6153impl<S: Simd> core::ops::Index<usize> for u32x16<S> {
6154 type Output = u32;
6155 #[inline(always)]
6156 fn index(&self, i: usize) -> &Self::Output {
6157 &self.simd.as_array_ref_u32x16(self)[i]
6158 }
6159}
6160impl<S: Simd> core::ops::IndexMut<usize> for u32x16<S> {
6161 #[inline(always)]
6162 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
6163 &mut self.simd.as_array_mut_u32x16(self)[i]
6164 }
6165}
6166impl<S: Simd> Select<u32x16<S>> for mask32x16<S> {
6167 #[inline(always)]
6168 fn select(self, if_true: u32x16<S>, if_false: u32x16<S>) -> u32x16<S> {
6169 self.simd.select_u32x16(self, if_true, if_false)
6170 }
6171}
6172impl<S: Simd> Bytes for u32x16<S> {
6173 type Bytes = u8x64<S>;
6174 #[inline(always)]
6175 fn to_bytes(self) -> Self::Bytes {
6176 self.simd.cvt_to_bytes_u32x16(self)
6177 }
6178 #[inline(always)]
6179 fn from_bytes(value: Self::Bytes) -> Self {
6180 value.simd.cvt_from_bytes_u32x16(value)
6181 }
6182}
6183impl<S: Simd> SimdBase<S> for u32x16<S> {
6184 type Element = u32;
6185 const N: usize = 16;
6186 type Mask = mask32x16<S>;
6187 type Block = u32x4<S>;
6188 type Array = [u32; 16];
6189 #[inline(always)]
6190 fn witness(&self) -> S {
6191 self.simd
6192 }
6193 #[inline(always)]
6194 fn as_slice(&self) -> &[u32] {
6195 self.simd.as_array_ref_u32x16(self).as_slice()
6196 }
6197 #[inline(always)]
6198 fn as_mut_slice(&mut self) -> &mut [u32] {
6199 self.simd.as_array_mut_u32x16(self).as_mut_slice()
6200 }
6201 #[inline(always)]
6202 fn from_slice(simd: S, slice: &[u32]) -> Self {
6203 simd.load_array_ref_u32x16(slice.try_into().unwrap())
6204 }
6205 #[inline(always)]
6206 fn store_slice(&self, slice: &mut [u32]) {
6207 self.simd
6208 .store_array_u32x16(*self, slice.try_into().unwrap());
6209 }
6210 #[inline(always)]
6211 fn splat(simd: S, val: u32) -> Self {
6212 simd.splat_u32x16(val)
6213 }
6214 #[inline(always)]
6215 fn block_splat(block: Self::Block) -> Self {
6216 let block2 = block.simd.combine_u32x4(block, block);
6217 block2.simd.combine_u32x8(block2, block2)
6218 }
6219 #[inline(always)]
6220 fn from_fn(simd: S, f: impl FnMut(usize) -> u32) -> Self {
6221 simd.load_array_u32x16(core::array::from_fn(f))
6222 }
6223 #[inline(always)]
6224 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
6225 self.simd
6226 .slide_u32x16::<SHIFT>(self, rhs.simd_into(self.simd))
6227 }
6228 #[inline(always)]
6229 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
6230 self.simd
6231 .slide_within_blocks_u32x16::<SHIFT>(self, rhs.simd_into(self.simd))
6232 }
6233}
6234impl<S: Simd> crate::SimdInt<S> for u32x16<S> {
6235 #[inline(always)]
6236 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6237 self.simd.simd_eq_u32x16(self, rhs.simd_into(self.simd))
6238 }
6239 #[inline(always)]
6240 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6241 self.simd.simd_lt_u32x16(self, rhs.simd_into(self.simd))
6242 }
6243 #[inline(always)]
6244 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6245 self.simd.simd_le_u32x16(self, rhs.simd_into(self.simd))
6246 }
6247 #[inline(always)]
6248 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6249 self.simd.simd_ge_u32x16(self, rhs.simd_into(self.simd))
6250 }
6251 #[inline(always)]
6252 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6253 self.simd.simd_gt_u32x16(self, rhs.simd_into(self.simd))
6254 }
6255 #[inline(always)]
6256 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
6257 self.simd.zip_low_u32x16(self, rhs.simd_into(self.simd))
6258 }
6259 #[inline(always)]
6260 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
6261 self.simd.zip_high_u32x16(self, rhs.simd_into(self.simd))
6262 }
6263 #[inline(always)]
6264 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
6265 self.simd.unzip_low_u32x16(self, rhs.simd_into(self.simd))
6266 }
6267 #[inline(always)]
6268 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
6269 self.simd.unzip_high_u32x16(self, rhs.simd_into(self.simd))
6270 }
6271 #[inline(always)]
6272 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
6273 self.simd.interleave_u32x16(self, rhs.simd_into(self.simd))
6274 }
6275 #[inline(always)]
6276 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
6277 self.simd
6278 .deinterleave_u32x16(self, rhs.simd_into(self.simd))
6279 }
6280 #[inline(always)]
6281 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
6282 self.simd.min_u32x16(self, rhs.simd_into(self.simd))
6283 }
6284 #[inline(always)]
6285 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
6286 self.simd.max_u32x16(self, rhs.simd_into(self.simd))
6287 }
6288}
6289impl<S: Simd> SimdCvtTruncate<f32x16<S>> for u32x16<S> {
6290 #[doc = "Convert each floating-point element to an unsigned 32-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results.\n\nOn x86 platforms, this operation will still be slower than converting to `i32`, because there is no native instruction for converting to `u32` (at least until AVX-512, which is currently not supported).\nIf you know your values fit within range of an `i32`, you should convert to an `i32` and cast to your desired datatype afterwards."]
6291 #[inline(always)]
6292 fn truncate_from(x: f32x16<S>) -> Self {
6293 x.simd.cvt_u32_f32x16(x)
6294 }
6295 #[doc = "Convert each floating-point element to an unsigned 32-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
6296 #[inline(always)]
6297 fn truncate_from_precise(x: f32x16<S>) -> Self {
6298 x.simd.cvt_u32_precise_f32x16(x)
6299 }
6300}
6301impl<S: Simd> crate::SimdSplit<S> for u32x16<S> {
6302 type Split = u32x8<S>;
6303 #[inline(always)]
6304 fn split(self) -> (Self::Split, Self::Split) {
6305 self.simd.split_u32x16(self)
6306 }
6307}
6308#[doc = "A SIMD mask of 16 32-bit elements.\n\nWhen created from a comparison operation, and as it should be used in a [`Self::select`] operation, each element will be all ones if it's \"true\", and all zeroes if it's \"false\"."]
6309#[derive(Clone, Copy)]
6310#[repr(C, align(64))]
6311pub struct mask32x16<S: Simd> {
6312 pub(crate) val: S::mask32x16,
6313 pub simd: S,
6314}
6315impl<S: Simd> SimdFrom<[i32; 16], S> for mask32x16<S> {
6316 #[inline(always)]
6317 fn simd_from(simd: S, val: [i32; 16]) -> Self {
6318 simd.load_array_mask32x16(val)
6319 }
6320}
6321impl<S: Simd> From<mask32x16<S>> for [i32; 16] {
6322 #[inline(always)]
6323 fn from(value: mask32x16<S>) -> Self {
6324 value.simd.as_array_mask32x16(value)
6325 }
6326}
6327impl<S: Simd> core::ops::Deref for mask32x16<S> {
6328 type Target = [i32; 16];
6329 #[inline(always)]
6330 fn deref(&self) -> &Self::Target {
6331 self.simd.as_array_ref_mask32x16(self)
6332 }
6333}
6334impl<S: Simd> core::ops::DerefMut for mask32x16<S> {
6335 #[inline(always)]
6336 fn deref_mut(&mut self) -> &mut Self::Target {
6337 self.simd.as_array_mut_mask32x16(self)
6338 }
6339}
6340impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask32x16<S> {
6341 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
6342 crate::support::simd_debug_impl(
6343 f,
6344 "mask32x16",
6345 &self.simd,
6346 self.simd.as_array_ref_mask32x16(self),
6347 )
6348 }
6349}
6350impl<S: Simd> SimdFrom<i32, S> for mask32x16<S> {
6351 #[inline(always)]
6352 fn simd_from(simd: S, value: i32) -> Self {
6353 simd.splat_mask32x16(value)
6354 }
6355}
6356impl<S: Simd> core::ops::Index<usize> for mask32x16<S> {
6357 type Output = i32;
6358 #[inline(always)]
6359 fn index(&self, i: usize) -> &Self::Output {
6360 &self.simd.as_array_ref_mask32x16(self)[i]
6361 }
6362}
6363impl<S: Simd> core::ops::IndexMut<usize> for mask32x16<S> {
6364 #[inline(always)]
6365 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
6366 &mut self.simd.as_array_mut_mask32x16(self)[i]
6367 }
6368}
6369impl<S: Simd> Select<mask32x16<S>> for mask32x16<S> {
6370 #[inline(always)]
6371 fn select(self, if_true: mask32x16<S>, if_false: mask32x16<S>) -> mask32x16<S> {
6372 self.simd.select_mask32x16(self, if_true, if_false)
6373 }
6374}
6375impl<S: Simd> Bytes for mask32x16<S> {
6376 type Bytes = u8x64<S>;
6377 #[inline(always)]
6378 fn to_bytes(self) -> Self::Bytes {
6379 self.simd.cvt_to_bytes_mask32x16(self)
6380 }
6381 #[inline(always)]
6382 fn from_bytes(value: Self::Bytes) -> Self {
6383 value.simd.cvt_from_bytes_mask32x16(value)
6384 }
6385}
6386impl<S: Simd> SimdBase<S> for mask32x16<S> {
6387 type Element = i32;
6388 const N: usize = 16;
6389 type Mask = mask32x16<S>;
6390 type Block = mask32x4<S>;
6391 type Array = [i32; 16];
6392 #[inline(always)]
6393 fn witness(&self) -> S {
6394 self.simd
6395 }
6396 #[inline(always)]
6397 fn as_slice(&self) -> &[i32] {
6398 self.simd.as_array_ref_mask32x16(self).as_slice()
6399 }
6400 #[inline(always)]
6401 fn as_mut_slice(&mut self) -> &mut [i32] {
6402 self.simd.as_array_mut_mask32x16(self).as_mut_slice()
6403 }
6404 #[inline(always)]
6405 fn from_slice(simd: S, slice: &[i32]) -> Self {
6406 simd.load_array_ref_mask32x16(slice.try_into().unwrap())
6407 }
6408 #[inline(always)]
6409 fn store_slice(&self, slice: &mut [i32]) {
6410 self.simd
6411 .store_array_mask32x16(*self, slice.try_into().unwrap());
6412 }
6413 #[inline(always)]
6414 fn splat(simd: S, val: i32) -> Self {
6415 simd.splat_mask32x16(val)
6416 }
6417 #[inline(always)]
6418 fn block_splat(block: Self::Block) -> Self {
6419 let block2 = block.simd.combine_mask32x4(block, block);
6420 block2.simd.combine_mask32x8(block2, block2)
6421 }
6422 #[inline(always)]
6423 fn from_fn(simd: S, f: impl FnMut(usize) -> i32) -> Self {
6424 simd.load_array_mask32x16(core::array::from_fn(f))
6425 }
6426 #[inline(always)]
6427 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
6428 self.simd
6429 .slide_mask32x16::<SHIFT>(self, rhs.simd_into(self.simd))
6430 }
6431 #[inline(always)]
6432 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
6433 self.simd
6434 .slide_within_blocks_mask32x16::<SHIFT>(self, rhs.simd_into(self.simd))
6435 }
6436}
6437impl<S: Simd> crate::SimdMask<S> for mask32x16<S> {
6438 #[inline(always)]
6439 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6440 self.simd.simd_eq_mask32x16(self, rhs.simd_into(self.simd))
6441 }
6442 #[inline(always)]
6443 fn any_true(self) -> bool {
6444 self.simd.any_true_mask32x16(self)
6445 }
6446 #[inline(always)]
6447 fn all_true(self) -> bool {
6448 self.simd.all_true_mask32x16(self)
6449 }
6450 #[inline(always)]
6451 fn any_false(self) -> bool {
6452 self.simd.any_false_mask32x16(self)
6453 }
6454 #[inline(always)]
6455 fn all_false(self) -> bool {
6456 self.simd.all_false_mask32x16(self)
6457 }
6458}
6459impl<S: Simd> crate::SimdSplit<S> for mask32x16<S> {
6460 type Split = mask32x8<S>;
6461 #[inline(always)]
6462 fn split(self) -> (Self::Split, Self::Split) {
6463 self.simd.split_mask32x16(self)
6464 }
6465}
6466#[doc = "A SIMD vector of 8 [`f64`] elements.\n\nYou may construct this vector type using the [`Self::splat`], [`Self::from_slice`], [`Self::simd_from`], [`Self::from_fn`], and [`Self::block_splat`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, f64x8};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = f64x8::splat(simd, 1.0);\n let b = f64x8::simd_from(simd, 1.0);\n\n // From a slice:\n let c = f64x8::from_slice(simd, &[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]);\n\n // From an array:\n let d = f64x8::simd_from(simd, [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]);\n\n // From an element-wise function:\n let e = f64x8::from_fn(simd, |i| i as f64);\n # use fearless_simd::f64x2;\n // From `Self::Block`:\n let f = f64x8::block_splat(f64x2::simd_from(simd, [1.0, 2.0]));\n}\n```"]
6467#[derive(Clone, Copy)]
6468#[repr(C, align(64))]
6469pub struct f64x8<S: Simd> {
6470 pub(crate) val: S::f64x8,
6471 pub simd: S,
6472}
6473impl<S: Simd> SimdFrom<[f64; 8], S> for f64x8<S> {
6474 #[inline(always)]
6475 fn simd_from(simd: S, val: [f64; 8]) -> Self {
6476 simd.load_array_f64x8(val)
6477 }
6478}
6479impl<S: Simd> From<f64x8<S>> for [f64; 8] {
6480 #[inline(always)]
6481 fn from(value: f64x8<S>) -> Self {
6482 value.simd.as_array_f64x8(value)
6483 }
6484}
6485impl<S: Simd> core::ops::Deref for f64x8<S> {
6486 type Target = [f64; 8];
6487 #[inline(always)]
6488 fn deref(&self) -> &Self::Target {
6489 self.simd.as_array_ref_f64x8(self)
6490 }
6491}
6492impl<S: Simd> core::ops::DerefMut for f64x8<S> {
6493 #[inline(always)]
6494 fn deref_mut(&mut self) -> &mut Self::Target {
6495 self.simd.as_array_mut_f64x8(self)
6496 }
6497}
6498impl<S: Simd + core::fmt::Debug> core::fmt::Debug for f64x8<S> {
6499 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
6500 crate::support::simd_debug_impl(f, "f64x8", &self.simd, self.simd.as_array_ref_f64x8(self))
6501 }
6502}
6503impl<S: Simd> SimdFrom<f64, S> for f64x8<S> {
6504 #[inline(always)]
6505 fn simd_from(simd: S, value: f64) -> Self {
6506 simd.splat_f64x8(value)
6507 }
6508}
6509impl<S: Simd> core::ops::Index<usize> for f64x8<S> {
6510 type Output = f64;
6511 #[inline(always)]
6512 fn index(&self, i: usize) -> &Self::Output {
6513 &self.simd.as_array_ref_f64x8(self)[i]
6514 }
6515}
6516impl<S: Simd> core::ops::IndexMut<usize> for f64x8<S> {
6517 #[inline(always)]
6518 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
6519 &mut self.simd.as_array_mut_f64x8(self)[i]
6520 }
6521}
6522impl<S: Simd> Select<f64x8<S>> for mask64x8<S> {
6523 #[inline(always)]
6524 fn select(self, if_true: f64x8<S>, if_false: f64x8<S>) -> f64x8<S> {
6525 self.simd.select_f64x8(self, if_true, if_false)
6526 }
6527}
6528impl<S: Simd> Bytes for f64x8<S> {
6529 type Bytes = u8x64<S>;
6530 #[inline(always)]
6531 fn to_bytes(self) -> Self::Bytes {
6532 self.simd.cvt_to_bytes_f64x8(self)
6533 }
6534 #[inline(always)]
6535 fn from_bytes(value: Self::Bytes) -> Self {
6536 value.simd.cvt_from_bytes_f64x8(value)
6537 }
6538}
6539impl<S: Simd> SimdBase<S> for f64x8<S> {
6540 type Element = f64;
6541 const N: usize = 8;
6542 type Mask = mask64x8<S>;
6543 type Block = f64x2<S>;
6544 type Array = [f64; 8];
6545 #[inline(always)]
6546 fn witness(&self) -> S {
6547 self.simd
6548 }
6549 #[inline(always)]
6550 fn as_slice(&self) -> &[f64] {
6551 self.simd.as_array_ref_f64x8(self).as_slice()
6552 }
6553 #[inline(always)]
6554 fn as_mut_slice(&mut self) -> &mut [f64] {
6555 self.simd.as_array_mut_f64x8(self).as_mut_slice()
6556 }
6557 #[inline(always)]
6558 fn from_slice(simd: S, slice: &[f64]) -> Self {
6559 simd.load_array_ref_f64x8(slice.try_into().unwrap())
6560 }
6561 #[inline(always)]
6562 fn store_slice(&self, slice: &mut [f64]) {
6563 self.simd
6564 .store_array_f64x8(*self, slice.try_into().unwrap());
6565 }
6566 #[inline(always)]
6567 fn splat(simd: S, val: f64) -> Self {
6568 simd.splat_f64x8(val)
6569 }
6570 #[inline(always)]
6571 fn block_splat(block: Self::Block) -> Self {
6572 let block2 = block.simd.combine_f64x2(block, block);
6573 block2.simd.combine_f64x4(block2, block2)
6574 }
6575 #[inline(always)]
6576 fn from_fn(simd: S, f: impl FnMut(usize) -> f64) -> Self {
6577 simd.load_array_f64x8(core::array::from_fn(f))
6578 }
6579 #[inline(always)]
6580 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
6581 self.simd
6582 .slide_f64x8::<SHIFT>(self, rhs.simd_into(self.simd))
6583 }
6584 #[inline(always)]
6585 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
6586 self.simd
6587 .slide_within_blocks_f64x8::<SHIFT>(self, rhs.simd_into(self.simd))
6588 }
6589}
6590impl<S: Simd> crate::SimdFloat<S> for f64x8<S> {
6591 #[inline(always)]
6592 fn abs(self) -> Self {
6593 self.simd.abs_f64x8(self)
6594 }
6595 #[inline(always)]
6596 fn sqrt(self) -> Self {
6597 self.simd.sqrt_f64x8(self)
6598 }
6599 #[inline(always)]
6600 fn copysign(self, rhs: impl SimdInto<Self, S>) -> Self {
6601 self.simd.copysign_f64x8(self, rhs.simd_into(self.simd))
6602 }
6603 #[inline(always)]
6604 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6605 self.simd.simd_eq_f64x8(self, rhs.simd_into(self.simd))
6606 }
6607 #[inline(always)]
6608 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6609 self.simd.simd_lt_f64x8(self, rhs.simd_into(self.simd))
6610 }
6611 #[inline(always)]
6612 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6613 self.simd.simd_le_f64x8(self, rhs.simd_into(self.simd))
6614 }
6615 #[inline(always)]
6616 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6617 self.simd.simd_ge_f64x8(self, rhs.simd_into(self.simd))
6618 }
6619 #[inline(always)]
6620 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6621 self.simd.simd_gt_f64x8(self, rhs.simd_into(self.simd))
6622 }
6623 #[inline(always)]
6624 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
6625 self.simd.zip_low_f64x8(self, rhs.simd_into(self.simd))
6626 }
6627 #[inline(always)]
6628 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
6629 self.simd.zip_high_f64x8(self, rhs.simd_into(self.simd))
6630 }
6631 #[inline(always)]
6632 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
6633 self.simd.unzip_low_f64x8(self, rhs.simd_into(self.simd))
6634 }
6635 #[inline(always)]
6636 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
6637 self.simd.unzip_high_f64x8(self, rhs.simd_into(self.simd))
6638 }
6639 #[inline(always)]
6640 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
6641 self.simd.interleave_f64x8(self, rhs.simd_into(self.simd))
6642 }
6643 #[inline(always)]
6644 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
6645 self.simd.deinterleave_f64x8(self, rhs.simd_into(self.simd))
6646 }
6647 #[inline(always)]
6648 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
6649 self.simd.max_f64x8(self, rhs.simd_into(self.simd))
6650 }
6651 #[inline(always)]
6652 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
6653 self.simd.min_f64x8(self, rhs.simd_into(self.simd))
6654 }
6655 #[inline(always)]
6656 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
6657 self.simd.max_precise_f64x8(self, rhs.simd_into(self.simd))
6658 }
6659 #[inline(always)]
6660 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
6661 self.simd.min_precise_f64x8(self, rhs.simd_into(self.simd))
6662 }
6663 #[inline(always)]
6664 fn mul_add(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
6665 self.simd
6666 .mul_add_f64x8(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
6667 }
6668 #[inline(always)]
6669 fn mul_sub(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
6670 self.simd
6671 .mul_sub_f64x8(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
6672 }
6673 #[inline(always)]
6674 fn floor(self) -> Self {
6675 self.simd.floor_f64x8(self)
6676 }
6677 #[inline(always)]
6678 fn ceil(self) -> Self {
6679 self.simd.ceil_f64x8(self)
6680 }
6681 #[inline(always)]
6682 fn round_ties_even(self) -> Self {
6683 self.simd.round_ties_even_f64x8(self)
6684 }
6685 #[inline(always)]
6686 fn fract(self) -> Self {
6687 self.simd.fract_f64x8(self)
6688 }
6689 #[inline(always)]
6690 fn trunc(self) -> Self {
6691 self.simd.trunc_f64x8(self)
6692 }
6693}
6694impl<S: Simd> crate::SimdSplit<S> for f64x8<S> {
6695 type Split = f64x4<S>;
6696 #[inline(always)]
6697 fn split(self) -> (Self::Split, Self::Split) {
6698 self.simd.split_f64x8(self)
6699 }
6700}
6701#[doc = "A SIMD mask of 8 64-bit elements.\n\nWhen created from a comparison operation, and as it should be used in a [`Self::select`] operation, each element will be all ones if it's \"true\", and all zeroes if it's \"false\"."]
6702#[derive(Clone, Copy)]
6703#[repr(C, align(64))]
6704pub struct mask64x8<S: Simd> {
6705 pub(crate) val: S::mask64x8,
6706 pub simd: S,
6707}
6708impl<S: Simd> SimdFrom<[i64; 8], S> for mask64x8<S> {
6709 #[inline(always)]
6710 fn simd_from(simd: S, val: [i64; 8]) -> Self {
6711 simd.load_array_mask64x8(val)
6712 }
6713}
6714impl<S: Simd> From<mask64x8<S>> for [i64; 8] {
6715 #[inline(always)]
6716 fn from(value: mask64x8<S>) -> Self {
6717 value.simd.as_array_mask64x8(value)
6718 }
6719}
6720impl<S: Simd> core::ops::Deref for mask64x8<S> {
6721 type Target = [i64; 8];
6722 #[inline(always)]
6723 fn deref(&self) -> &Self::Target {
6724 self.simd.as_array_ref_mask64x8(self)
6725 }
6726}
6727impl<S: Simd> core::ops::DerefMut for mask64x8<S> {
6728 #[inline(always)]
6729 fn deref_mut(&mut self) -> &mut Self::Target {
6730 self.simd.as_array_mut_mask64x8(self)
6731 }
6732}
6733impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask64x8<S> {
6734 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
6735 crate::support::simd_debug_impl(
6736 f,
6737 "mask64x8",
6738 &self.simd,
6739 self.simd.as_array_ref_mask64x8(self),
6740 )
6741 }
6742}
6743impl<S: Simd> SimdFrom<i64, S> for mask64x8<S> {
6744 #[inline(always)]
6745 fn simd_from(simd: S, value: i64) -> Self {
6746 simd.splat_mask64x8(value)
6747 }
6748}
6749impl<S: Simd> core::ops::Index<usize> for mask64x8<S> {
6750 type Output = i64;
6751 #[inline(always)]
6752 fn index(&self, i: usize) -> &Self::Output {
6753 &self.simd.as_array_ref_mask64x8(self)[i]
6754 }
6755}
6756impl<S: Simd> core::ops::IndexMut<usize> for mask64x8<S> {
6757 #[inline(always)]
6758 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
6759 &mut self.simd.as_array_mut_mask64x8(self)[i]
6760 }
6761}
6762impl<S: Simd> Select<mask64x8<S>> for mask64x8<S> {
6763 #[inline(always)]
6764 fn select(self, if_true: mask64x8<S>, if_false: mask64x8<S>) -> mask64x8<S> {
6765 self.simd.select_mask64x8(self, if_true, if_false)
6766 }
6767}
6768impl<S: Simd> Bytes for mask64x8<S> {
6769 type Bytes = u8x64<S>;
6770 #[inline(always)]
6771 fn to_bytes(self) -> Self::Bytes {
6772 self.simd.cvt_to_bytes_mask64x8(self)
6773 }
6774 #[inline(always)]
6775 fn from_bytes(value: Self::Bytes) -> Self {
6776 value.simd.cvt_from_bytes_mask64x8(value)
6777 }
6778}
6779impl<S: Simd> SimdBase<S> for mask64x8<S> {
6780 type Element = i64;
6781 const N: usize = 8;
6782 type Mask = mask64x8<S>;
6783 type Block = mask64x2<S>;
6784 type Array = [i64; 8];
6785 #[inline(always)]
6786 fn witness(&self) -> S {
6787 self.simd
6788 }
6789 #[inline(always)]
6790 fn as_slice(&self) -> &[i64] {
6791 self.simd.as_array_ref_mask64x8(self).as_slice()
6792 }
6793 #[inline(always)]
6794 fn as_mut_slice(&mut self) -> &mut [i64] {
6795 self.simd.as_array_mut_mask64x8(self).as_mut_slice()
6796 }
6797 #[inline(always)]
6798 fn from_slice(simd: S, slice: &[i64]) -> Self {
6799 simd.load_array_ref_mask64x8(slice.try_into().unwrap())
6800 }
6801 #[inline(always)]
6802 fn store_slice(&self, slice: &mut [i64]) {
6803 self.simd
6804 .store_array_mask64x8(*self, slice.try_into().unwrap());
6805 }
6806 #[inline(always)]
6807 fn splat(simd: S, val: i64) -> Self {
6808 simd.splat_mask64x8(val)
6809 }
6810 #[inline(always)]
6811 fn block_splat(block: Self::Block) -> Self {
6812 let block2 = block.simd.combine_mask64x2(block, block);
6813 block2.simd.combine_mask64x4(block2, block2)
6814 }
6815 #[inline(always)]
6816 fn from_fn(simd: S, f: impl FnMut(usize) -> i64) -> Self {
6817 simd.load_array_mask64x8(core::array::from_fn(f))
6818 }
6819 #[inline(always)]
6820 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
6821 self.simd
6822 .slide_mask64x8::<SHIFT>(self, rhs.simd_into(self.simd))
6823 }
6824 #[inline(always)]
6825 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
6826 self.simd
6827 .slide_within_blocks_mask64x8::<SHIFT>(self, rhs.simd_into(self.simd))
6828 }
6829}
6830impl<S: Simd> crate::SimdMask<S> for mask64x8<S> {
6831 #[inline(always)]
6832 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6833 self.simd.simd_eq_mask64x8(self, rhs.simd_into(self.simd))
6834 }
6835 #[inline(always)]
6836 fn any_true(self) -> bool {
6837 self.simd.any_true_mask64x8(self)
6838 }
6839 #[inline(always)]
6840 fn all_true(self) -> bool {
6841 self.simd.all_true_mask64x8(self)
6842 }
6843 #[inline(always)]
6844 fn any_false(self) -> bool {
6845 self.simd.any_false_mask64x8(self)
6846 }
6847 #[inline(always)]
6848 fn all_false(self) -> bool {
6849 self.simd.all_false_mask64x8(self)
6850 }
6851}
6852impl<S: Simd> crate::SimdSplit<S> for mask64x8<S> {
6853 type Split = mask64x4<S>;
6854 #[inline(always)]
6855 fn split(self) -> (Self::Split, Self::Split) {
6856 self.simd.split_mask64x8(self)
6857 }
6858}