1use crate::{
7 Bytes, ExtractToken, MaskNarrow, MaskWiden, Select, Simd, SimdBase, SimdCvtFloat,
8 SimdCvtTruncate, SimdFrom, SimdIntWiden, SimdInterleaved, SimdInto, SimdMask, SimdNarrow,
9 SimdWiden, seal::Seal,
10};
11impl<S: Simd> ExtractToken for f32x4<S> {
12 type S = S;
13 #[inline]
14 fn token(&self) -> S {
15 self.simd
16 }
17}
18#[doc = "A SIMD vector of 4 [`f32`] elements.\n\nThis type's memory layout is identical to that of [`[f32; 4]`](prim@array), except that it is aligned to 16 bytes.\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```"]
19#[derive(Clone, Copy)]
20#[repr(C, align(16))]
21pub struct f32x4<S: Simd> {
22 pub(crate) val: S::f32x4,
23 pub simd: S,
24}
25impl<S: Simd> Seal for f32x4<S> {}
26impl<S: Simd> SimdFrom<[f32; 4], S> for f32x4<S> {
27 #[inline(always)]
28 fn simd_from(simd: S, val: [f32; 4]) -> Self {
29 Self {
30 val: crate::transmute::checked_transmute_copy(&val),
31 simd,
32 }
33 }
34}
35impl<S: Simd> From<f32x4<S>> for [f32; 4] {
36 #[inline(always)]
37 fn from(value: f32x4<S>) -> Self {
38 crate::transmute::checked_transmute_copy(&value.val)
39 }
40}
41impl<S: Simd> core::ops::Deref for f32x4<S> {
42 type Target = [f32; 4];
43 #[inline(always)]
44 fn deref(&self) -> &Self::Target {
45 crate::transmute::checked_cast_ref(&self.val)
46 }
47}
48impl<S: Simd> core::ops::DerefMut for f32x4<S> {
49 #[inline(always)]
50 fn deref_mut(&mut self) -> &mut Self::Target {
51 crate::transmute::checked_cast_mut(&mut self.val)
52 }
53}
54impl<S: Simd + core::fmt::Debug> core::fmt::Debug for f32x4<S> {
55 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
56 crate::support::simd_debug_impl(f, "f32x4", &self.simd, self.as_array())
57 }
58}
59impl<S: Simd> SimdFrom<f32, S> for f32x4<S> {
60 #[inline(always)]
61 fn simd_from(simd: S, value: f32) -> Self {
62 simd.splat_f32x4(value)
63 }
64}
65impl<S: Simd> core::ops::Index<usize> for f32x4<S> {
66 type Output = f32;
67 #[inline(always)]
68 fn index(&self, i: usize) -> &Self::Output {
69 &self.as_array()[i]
70 }
71}
72impl<S: Simd> core::ops::IndexMut<usize> for f32x4<S> {
73 #[inline(always)]
74 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
75 &mut self.as_mut_array()[i]
76 }
77}
78impl<S: Simd> Select<f32x4<S>> for mask32x4<S> {
79 #[inline(always)]
80 fn select(self, if_true: f32x4<S>, if_false: f32x4<S>) -> f32x4<S> {
81 self.simd.select_f32x4(self, if_true, if_false)
82 }
83}
84impl<S: Simd> Bytes for f32x4<S> {
85 type Bytes = u8x16<S>;
86 #[inline(always)]
87 fn to_bytes(self) -> Self::Bytes {
88 u8x16 {
89 val: crate::transmute::checked_transmute_copy(&self.val),
90 simd: self.simd,
91 }
92 }
93 #[inline(always)]
94 fn from_bytes(value: Self::Bytes) -> Self {
95 Self {
96 val: crate::transmute::checked_transmute_copy(&value.val),
97 simd: value.simd,
98 }
99 }
100}
101impl<S: Simd> SimdBase<S> for f32x4<S> {
102 type Element = f32;
103 type ByteVector = u8x16<S>;
104 const LEN: usize = 4;
105 type Mask = mask32x4<S>;
106 type Block = f32x4<S>;
107 type Array = [f32; 4];
108 #[inline(always)]
109 fn as_slice(&self) -> &[f32] {
110 self.as_array().as_slice()
111 }
112 #[inline(always)]
113 fn as_mut_slice(&mut self) -> &mut [f32] {
114 self.as_mut_array().as_mut_slice()
115 }
116 #[inline(always)]
117 fn from_slice(simd: S, slice: &[f32]) -> Self {
118 Self::load_array_ref(simd, slice.try_into().unwrap())
119 }
120 #[inline(always)]
121 fn store_slice(&self, slice: &mut [f32]) {
122 (*self).store_array(slice.try_into().unwrap());
123 }
124 #[inline(always)]
125 fn splat(simd: S, val: f32) -> Self {
126 simd.splat_f32x4(val)
127 }
128 #[inline(always)]
129 fn block_splat(block: Self::Block) -> Self {
130 block
131 }
132 #[inline(always)]
133 fn from_fn(simd: S, mut f: impl FnMut(usize) -> f32) -> Self {
134 Self::load_array(simd, [f(0usize), f(1usize), f(2usize), f(3usize)])
135 }
136 #[inline(always)]
137 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
138 self.simd
139 .slide_f32x4::<SHIFT>(self, rhs.simd_into(self.simd))
140 }
141 #[inline(always)]
142 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
143 self.simd
144 .slide_within_blocks_f32x4::<SHIFT>(self, rhs.simd_into(self.simd))
145 }
146 #[inline(always)]
147 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
148 self.simd
149 .swizzle_dyn_within_blocks_f32x4(self, indices.simd_into(self.simd))
150 }
151 #[inline(always)]
152 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
153 self.simd
154 .swizzle_dyn_f32x4(self, indices.simd_into(self.simd))
155 }
156 #[inline(always)]
157 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
158 self.simd
159 .swizzle_dyn_precise_f32x4(self, indices.simd_into(self.simd))
160 }
161 #[inline(always)]
162 fn abs(self) -> Self {
163 self.simd.abs_f32x4(self)
164 }
165 #[inline(always)]
166 fn reverse(self) -> Self {
167 self.simd.reverse_f32x4(self)
168 }
169 #[inline(always)]
170 fn concat_swizzle_dyn(
171 self,
172 rhs: impl SimdInto<Self, S>,
173 indices: impl SimdInto<Self::Bytes, S>,
174 ) -> Self {
175 self.simd.concat_swizzle_dyn_f32x4(
176 self,
177 rhs.simd_into(self.simd),
178 indices.simd_into(self.simd),
179 )
180 }
181 #[inline(always)]
182 fn concat_swizzle_dyn_precise(
183 self,
184 rhs: impl SimdInto<Self, S>,
185 indices: impl SimdInto<Self::Bytes, S>,
186 ) -> Self {
187 self.simd.concat_swizzle_dyn_precise_f32x4(
188 self,
189 rhs.simd_into(self.simd),
190 indices.simd_into(self.simd),
191 )
192 }
193 #[inline(always)]
194 fn compress(self, mask: Self::Mask) -> Self {
195 self.simd.compress_f32x4(self, mask)
196 }
197 #[inline(always)]
198 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
199 self.simd
200 .compress_merge_f32x4(self, mask, merge.simd_into(self.simd))
201 }
202 #[inline(always)]
203 fn expand(self, mask: Self::Mask) -> Self {
204 self.simd.expand_f32x4(self, mask)
205 }
206 #[inline(always)]
207 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
208 self.simd
209 .expand_merge_f32x4(self, mask, merge.simd_into(self.simd))
210 }
211 #[inline(always)]
212 fn reduce_max(self) -> Self::Element {
213 self.simd.reduce_max_f32x4(self)
214 }
215 #[inline(always)]
216 fn reduce_min(self) -> Self::Element {
217 self.simd.reduce_min_f32x4(self)
218 }
219 #[inline(always)]
220 fn reduce_max_precise(self) -> Self::Element {
221 self.simd.reduce_max_precise_f32x4(self)
222 }
223 #[inline(always)]
224 fn reduce_min_precise(self) -> Self::Element {
225 self.simd.reduce_min_precise_f32x4(self)
226 }
227 #[inline(always)]
228 fn reduce_sum(self) -> Self::Element {
229 self.simd.reduce_sum_f32x4(self)
230 }
231 #[inline(always)]
232 fn reduce_product(self) -> Self::Element {
233 self.simd.reduce_product_f32x4(self)
234 }
235 #[inline(always)]
236 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
237 self.simd.max_f32x4(self, rhs.simd_into(self.simd))
238 }
239 #[inline(always)]
240 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
241 self.simd.min_f32x4(self, rhs.simd_into(self.simd))
242 }
243 #[inline(always)]
244 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
245 self.simd.max_precise_f32x4(self, rhs.simd_into(self.simd))
246 }
247 #[inline(always)]
248 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
249 self.simd.min_precise_f32x4(self, rhs.simd_into(self.simd))
250 }
251 #[inline(always)]
252 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
253 self.simd
254 .clamp_f32x4(self, min.simd_into(self.simd), max.simd_into(self.simd))
255 }
256 #[inline(always)]
257 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
258 self.simd.simd_eq_f32x4(self, rhs.simd_into(self.simd))
259 }
260 #[inline(always)]
261 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
262 self.simd.simd_ne_f32x4(self, rhs.simd_into(self.simd))
263 }
264 #[inline(always)]
265 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
266 self.simd.simd_lt_f32x4(self, rhs.simd_into(self.simd))
267 }
268 #[inline(always)]
269 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
270 self.simd.simd_le_f32x4(self, rhs.simd_into(self.simd))
271 }
272 #[inline(always)]
273 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
274 self.simd.simd_ge_f32x4(self, rhs.simd_into(self.simd))
275 }
276 #[inline(always)]
277 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
278 self.simd.simd_gt_f32x4(self, rhs.simd_into(self.simd))
279 }
280 #[inline(always)]
281 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
282 self.simd.zip_low_f32x4(self, rhs.simd_into(self.simd))
283 }
284 #[inline(always)]
285 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
286 self.simd.zip_high_f32x4(self, rhs.simd_into(self.simd))
287 }
288 #[inline(always)]
289 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
290 self.simd.unzip_low_f32x4(self, rhs.simd_into(self.simd))
291 }
292 #[inline(always)]
293 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
294 self.simd.unzip_high_f32x4(self, rhs.simd_into(self.simd))
295 }
296 #[inline(always)]
297 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
298 self.simd.interleave_f32x4(self, rhs.simd_into(self.simd))
299 }
300 #[inline(always)]
301 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
302 self.simd.deinterleave_f32x4(self, rhs.simd_into(self.simd))
303 }
304}
305impl<S: Simd> crate::SimdFloat<S> for f32x4<S> {
306 type Bits = u32x4<S>;
307 #[inline(always)]
308 fn sqrt(self) -> Self {
309 self.simd.sqrt_f32x4(self)
310 }
311 #[inline(always)]
312 fn approximate_recip(self) -> Self {
313 self.simd.approximate_recip_f32x4(self)
314 }
315 #[inline(always)]
316 fn copysign(self, rhs: impl SimdInto<Self, S>) -> Self {
317 self.simd.copysign_f32x4(self, rhs.simd_into(self.simd))
318 }
319 #[inline(always)]
320 fn mul_add(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
321 self.simd
322 .mul_add_f32x4(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
323 }
324 #[inline(always)]
325 fn mul_add_precise(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
326 self.simd
327 .mul_add_precise_f32x4(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
328 }
329 #[inline(always)]
330 fn mul_sub(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
331 self.simd
332 .mul_sub_f32x4(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
333 }
334 #[inline(always)]
335 fn mul_sub_precise(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
336 self.simd
337 .mul_sub_precise_f32x4(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
338 }
339 #[inline(always)]
340 fn floor(self) -> Self {
341 self.simd.floor_f32x4(self)
342 }
343 #[inline(always)]
344 fn ceil(self) -> Self {
345 self.simd.ceil_f32x4(self)
346 }
347 #[inline(always)]
348 fn round_ties_even(self) -> Self {
349 self.simd.round_ties_even_f32x4(self)
350 }
351 #[inline(always)]
352 fn round(self) -> Self {
353 self.simd.round_f32x4(self)
354 }
355 #[inline(always)]
356 fn fract(self) -> Self {
357 self.simd.fract_f32x4(self)
358 }
359 #[inline(always)]
360 fn trunc(self) -> Self {
361 self.simd.trunc_f32x4(self)
362 }
363 #[inline(always)]
364 fn to_degrees(self) -> Self {
365 self.simd.to_degrees_f32x4(self)
366 }
367 #[inline(always)]
368 fn to_radians(self) -> Self {
369 self.simd.to_radians_f32x4(self)
370 }
371 #[inline(always)]
372 fn is_nan(self) -> Self::Mask {
373 self.simd.is_nan_f32x4(self)
374 }
375 #[inline(always)]
376 fn is_infinite(self) -> Self::Mask {
377 self.simd.is_infinite_f32x4(self)
378 }
379 #[inline(always)]
380 fn is_finite(self) -> Self::Mask {
381 self.simd.is_finite_f32x4(self)
382 }
383 #[inline(always)]
384 fn is_subnormal(self) -> Self::Mask {
385 self.simd.is_subnormal_f32x4(self)
386 }
387 #[inline(always)]
388 fn is_normal(self) -> Self::Mask {
389 self.simd.is_normal_f32x4(self)
390 }
391 #[inline(always)]
392 fn is_sign_positive(self) -> Self::Mask {
393 self.simd.is_sign_positive_f32x4(self)
394 }
395 #[inline(always)]
396 fn is_sign_negative(self) -> Self::Mask {
397 self.simd.is_sign_negative_f32x4(self)
398 }
399}
400impl<S: Simd> SimdCvtFloat<u32x4<S>> for f32x4<S> {
401 #[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."]
402 #[inline(always)]
403 fn float_from(x: u32x4<S>) -> Self {
404 x.simd.cvt_f32_u32x4(x)
405 }
406}
407impl<S: Simd> SimdCvtFloat<i32x4<S>> for f32x4<S> {
408 #[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."]
409 #[inline(always)]
410 fn float_from(x: i32x4<S>) -> Self {
411 x.simd.cvt_f32_i32x4(x)
412 }
413}
414impl<S: Simd> SimdWiden<S> for f32x4<S> {
415 type Widened = f64x2<S>;
416 #[inline(always)]
417 fn widen(self) -> (Self::Widened, Self::Widened) {
418 self.simd.widen_f32x4(self)
419 }
420}
421impl<S: Simd> crate::SimdCombine<S> for f32x4<S> {
422 type Combined = f32x8<S>;
423 #[inline(always)]
424 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
425 self.simd.combine_f32x4(self, rhs.simd_into(self.simd))
426 }
427}
428impl<S: Simd> SimdInterleaved<S> for f32x4<S> {
429 #[inline(always)]
430 fn load_four_interleaved(simd: S, src: &[Self::Element]) -> [Self; 4] {
431 let src: &[f32; 16] = src.try_into().unwrap();
432 simd.load_four_interleaved_f32x4(src)
433 }
434 #[inline(always)]
435 fn store_four_interleaved(vectors: [Self; 4], dest: &mut [Self::Element]) {
436 let dest: &mut [f32; 16] = dest.try_into().unwrap();
437 vectors[0].simd.store_four_interleaved_f32x4(vectors, dest);
438 }
439}
440impl<S: Simd> ExtractToken for i8x16<S> {
441 type S = S;
442 #[inline]
443 fn token(&self) -> S {
444 self.simd
445 }
446}
447#[doc = "A SIMD vector of 16 [`i8`] elements.\n\nThis type's memory layout is identical to that of [`[i8; 16]`](prim@array), except that it is aligned to 16 bytes.\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```"]
448#[derive(Clone, Copy)]
449#[repr(C, align(16))]
450pub struct i8x16<S: Simd> {
451 pub(crate) val: S::i8x16,
452 pub simd: S,
453}
454impl<S: Simd> Seal for i8x16<S> {}
455impl<S: Simd> SimdFrom<[i8; 16], S> for i8x16<S> {
456 #[inline(always)]
457 fn simd_from(simd: S, val: [i8; 16]) -> Self {
458 Self {
459 val: crate::transmute::checked_transmute_copy(&val),
460 simd,
461 }
462 }
463}
464impl<S: Simd> From<i8x16<S>> for [i8; 16] {
465 #[inline(always)]
466 fn from(value: i8x16<S>) -> Self {
467 crate::transmute::checked_transmute_copy(&value.val)
468 }
469}
470impl<S: Simd> core::ops::Deref for i8x16<S> {
471 type Target = [i8; 16];
472 #[inline(always)]
473 fn deref(&self) -> &Self::Target {
474 crate::transmute::checked_cast_ref(&self.val)
475 }
476}
477impl<S: Simd> core::ops::DerefMut for i8x16<S> {
478 #[inline(always)]
479 fn deref_mut(&mut self) -> &mut Self::Target {
480 crate::transmute::checked_cast_mut(&mut self.val)
481 }
482}
483impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i8x16<S> {
484 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
485 crate::support::simd_debug_impl(f, "i8x16", &self.simd, self.as_array())
486 }
487}
488impl<S: Simd> SimdFrom<i8, S> for i8x16<S> {
489 #[inline(always)]
490 fn simd_from(simd: S, value: i8) -> Self {
491 simd.splat_i8x16(value)
492 }
493}
494impl<S: Simd> core::ops::Index<usize> for i8x16<S> {
495 type Output = i8;
496 #[inline(always)]
497 fn index(&self, i: usize) -> &Self::Output {
498 &self.as_array()[i]
499 }
500}
501impl<S: Simd> core::ops::IndexMut<usize> for i8x16<S> {
502 #[inline(always)]
503 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
504 &mut self.as_mut_array()[i]
505 }
506}
507impl<S: Simd> Select<i8x16<S>> for mask8x16<S> {
508 #[inline(always)]
509 fn select(self, if_true: i8x16<S>, if_false: i8x16<S>) -> i8x16<S> {
510 self.simd.select_i8x16(self, if_true, if_false)
511 }
512}
513impl<S: Simd> Bytes for i8x16<S> {
514 type Bytes = u8x16<S>;
515 #[inline(always)]
516 fn to_bytes(self) -> Self::Bytes {
517 u8x16 {
518 val: crate::transmute::checked_transmute_copy(&self.val),
519 simd: self.simd,
520 }
521 }
522 #[inline(always)]
523 fn from_bytes(value: Self::Bytes) -> Self {
524 Self {
525 val: crate::transmute::checked_transmute_copy(&value.val),
526 simd: value.simd,
527 }
528 }
529}
530impl<S: Simd> SimdBase<S> for i8x16<S> {
531 type Element = i8;
532 type ByteVector = u8x16<S>;
533 const LEN: usize = 16;
534 type Mask = mask8x16<S>;
535 type Block = i8x16<S>;
536 type Array = [i8; 16];
537 #[inline(always)]
538 fn as_slice(&self) -> &[i8] {
539 self.as_array().as_slice()
540 }
541 #[inline(always)]
542 fn as_mut_slice(&mut self) -> &mut [i8] {
543 self.as_mut_array().as_mut_slice()
544 }
545 #[inline(always)]
546 fn from_slice(simd: S, slice: &[i8]) -> Self {
547 Self::load_array_ref(simd, slice.try_into().unwrap())
548 }
549 #[inline(always)]
550 fn store_slice(&self, slice: &mut [i8]) {
551 (*self).store_array(slice.try_into().unwrap());
552 }
553 #[inline(always)]
554 fn splat(simd: S, val: i8) -> Self {
555 simd.splat_i8x16(val)
556 }
557 #[inline(always)]
558 fn block_splat(block: Self::Block) -> Self {
559 block
560 }
561 #[inline(always)]
562 fn from_fn(simd: S, mut f: impl FnMut(usize) -> i8) -> Self {
563 Self::load_array(
564 simd,
565 [
566 f(0usize),
567 f(1usize),
568 f(2usize),
569 f(3usize),
570 f(4usize),
571 f(5usize),
572 f(6usize),
573 f(7usize),
574 f(8usize),
575 f(9usize),
576 f(10usize),
577 f(11usize),
578 f(12usize),
579 f(13usize),
580 f(14usize),
581 f(15usize),
582 ],
583 )
584 }
585 #[inline(always)]
586 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
587 self.simd
588 .slide_i8x16::<SHIFT>(self, rhs.simd_into(self.simd))
589 }
590 #[inline(always)]
591 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
592 self.simd
593 .slide_within_blocks_i8x16::<SHIFT>(self, rhs.simd_into(self.simd))
594 }
595 #[inline(always)]
596 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
597 self.simd
598 .swizzle_dyn_within_blocks_i8x16(self, indices.simd_into(self.simd))
599 }
600 #[inline(always)]
601 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
602 self.simd
603 .swizzle_dyn_i8x16(self, indices.simd_into(self.simd))
604 }
605 #[inline(always)]
606 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
607 self.simd
608 .swizzle_dyn_precise_i8x16(self, indices.simd_into(self.simd))
609 }
610 #[inline(always)]
611 fn abs(self) -> Self {
612 self.simd.abs_i8x16(self)
613 }
614 #[inline(always)]
615 fn reverse(self) -> Self {
616 self.simd.reverse_i8x16(self)
617 }
618 #[inline(always)]
619 fn concat_swizzle_dyn(
620 self,
621 rhs: impl SimdInto<Self, S>,
622 indices: impl SimdInto<Self::Bytes, S>,
623 ) -> Self {
624 self.simd.concat_swizzle_dyn_i8x16(
625 self,
626 rhs.simd_into(self.simd),
627 indices.simd_into(self.simd),
628 )
629 }
630 #[inline(always)]
631 fn concat_swizzle_dyn_precise(
632 self,
633 rhs: impl SimdInto<Self, S>,
634 indices: impl SimdInto<Self::Bytes, S>,
635 ) -> Self {
636 self.simd.concat_swizzle_dyn_precise_i8x16(
637 self,
638 rhs.simd_into(self.simd),
639 indices.simd_into(self.simd),
640 )
641 }
642 #[inline(always)]
643 fn compress(self, mask: Self::Mask) -> Self {
644 self.simd.compress_i8x16(self, mask)
645 }
646 #[inline(always)]
647 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
648 self.simd
649 .compress_merge_i8x16(self, mask, merge.simd_into(self.simd))
650 }
651 #[inline(always)]
652 fn expand(self, mask: Self::Mask) -> Self {
653 self.simd.expand_i8x16(self, mask)
654 }
655 #[inline(always)]
656 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
657 self.simd
658 .expand_merge_i8x16(self, mask, merge.simd_into(self.simd))
659 }
660 #[inline(always)]
661 fn reduce_max(self) -> Self::Element {
662 self.simd.reduce_max_i8x16(self)
663 }
664 #[inline(always)]
665 fn reduce_min(self) -> Self::Element {
666 self.simd.reduce_min_i8x16(self)
667 }
668 #[inline(always)]
669 fn reduce_max_precise(self) -> Self::Element {
670 self.simd.reduce_max_i8x16(self)
671 }
672 #[inline(always)]
673 fn reduce_min_precise(self) -> Self::Element {
674 self.simd.reduce_min_i8x16(self)
675 }
676 #[inline(always)]
677 fn reduce_sum(self) -> Self::Element {
678 self.simd.reduce_sum_i8x16(self)
679 }
680 #[inline(always)]
681 fn reduce_product(self) -> Self::Element {
682 self.simd.reduce_product_i8x16(self)
683 }
684 #[inline(always)]
685 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
686 self.simd.max_i8x16(self, rhs.simd_into(self.simd))
687 }
688 #[inline(always)]
689 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
690 self.simd.min_i8x16(self, rhs.simd_into(self.simd))
691 }
692 #[inline(always)]
693 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
694 self.simd.max_i8x16(self, rhs.simd_into(self.simd))
695 }
696 #[inline(always)]
697 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
698 self.simd.min_i8x16(self, rhs.simd_into(self.simd))
699 }
700 #[inline(always)]
701 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
702 self.simd
703 .clamp_i8x16(self, min.simd_into(self.simd), max.simd_into(self.simd))
704 }
705 #[inline(always)]
706 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
707 self.simd.simd_eq_i8x16(self, rhs.simd_into(self.simd))
708 }
709 #[inline(always)]
710 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
711 self.simd.simd_ne_i8x16(self, rhs.simd_into(self.simd))
712 }
713 #[inline(always)]
714 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
715 self.simd.simd_lt_i8x16(self, rhs.simd_into(self.simd))
716 }
717 #[inline(always)]
718 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
719 self.simd.simd_le_i8x16(self, rhs.simd_into(self.simd))
720 }
721 #[inline(always)]
722 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
723 self.simd.simd_ge_i8x16(self, rhs.simd_into(self.simd))
724 }
725 #[inline(always)]
726 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
727 self.simd.simd_gt_i8x16(self, rhs.simd_into(self.simd))
728 }
729 #[inline(always)]
730 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
731 self.simd.zip_low_i8x16(self, rhs.simd_into(self.simd))
732 }
733 #[inline(always)]
734 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
735 self.simd.zip_high_i8x16(self, rhs.simd_into(self.simd))
736 }
737 #[inline(always)]
738 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
739 self.simd.unzip_low_i8x16(self, rhs.simd_into(self.simd))
740 }
741 #[inline(always)]
742 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
743 self.simd.unzip_high_i8x16(self, rhs.simd_into(self.simd))
744 }
745 #[inline(always)]
746 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
747 self.simd.interleave_i8x16(self, rhs.simd_into(self.simd))
748 }
749 #[inline(always)]
750 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
751 self.simd.deinterleave_i8x16(self, rhs.simd_into(self.simd))
752 }
753}
754impl<S: Simd> crate::SimdInt<S> for i8x16<S> {
755 #[inline(always)]
756 fn count_ones(self) -> Self {
757 self.simd.count_ones_i8x16(self)
758 }
759 #[inline(always)]
760 fn count_zeros(self) -> Self {
761 self.simd.count_zeros_i8x16(self)
762 }
763 #[inline(always)]
764 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
765 self.simd
766 .saturating_add_i8x16(self, rhs.simd_into(self.simd))
767 }
768 #[inline(always)]
769 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
770 self.simd
771 .saturating_sub_i8x16(self, rhs.simd_into(self.simd))
772 }
773}
774impl<S: Simd> SimdWiden<S> for i8x16<S> {
775 type Widened = i16x8<S>;
776 #[inline(always)]
777 fn widen(self) -> (Self::Widened, Self::Widened) {
778 self.simd.widen_i8x16(self)
779 }
780}
781impl<S: Simd> SimdIntWiden<S> for i8x16<S> {
782 #[inline(always)]
783 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
784 self.simd.widening_mul_i8x16(self, rhs.simd_into(self.simd))
785 }
786 #[inline(always)]
787 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
788 self.simd.widening_add_i8x16(self, rhs.simd_into(self.simd))
789 }
790 #[inline(always)]
791 fn pairwise_widening_add(self) -> Self::Widened {
792 self.simd.pairwise_widening_add_i8x16(self)
793 }
794 #[inline(always)]
795 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
796 self.simd
797 .pairwise_dot_product_i8x16(self, rhs.simd_into(self.simd))
798 }
799}
800impl<S: Simd> crate::SimdCombine<S> for i8x16<S> {
801 type Combined = i8x32<S>;
802 #[inline(always)]
803 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
804 self.simd.combine_i8x16(self, rhs.simd_into(self.simd))
805 }
806}
807impl<S: Simd> SimdInterleaved<S> for i8x16<S> {
808 #[inline(always)]
809 fn load_four_interleaved(simd: S, src: &[Self::Element]) -> [Self; 4] {
810 let src: &[i8; 64] = src.try_into().unwrap();
811 simd.load_four_interleaved_i8x16(src)
812 }
813 #[inline(always)]
814 fn store_four_interleaved(vectors: [Self; 4], dest: &mut [Self::Element]) {
815 let dest: &mut [i8; 64] = dest.try_into().unwrap();
816 vectors[0].simd.store_four_interleaved_i8x16(vectors, dest);
817 }
818}
819impl<S: Simd> ExtractToken for u8x16<S> {
820 type S = S;
821 #[inline]
822 fn token(&self) -> S {
823 self.simd
824 }
825}
826#[doc = "A SIMD vector of 16 [`u8`] elements.\n\nThis type's memory layout is identical to that of [`[u8; 16]`](prim@array), except that it is aligned to 16 bytes.\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```"]
827#[derive(Clone, Copy)]
828#[repr(C, align(16))]
829pub struct u8x16<S: Simd> {
830 pub(crate) val: S::u8x16,
831 pub simd: S,
832}
833impl<S: Simd> Seal for u8x16<S> {}
834impl<S: Simd> SimdFrom<[u8; 16], S> for u8x16<S> {
835 #[inline(always)]
836 fn simd_from(simd: S, val: [u8; 16]) -> Self {
837 Self {
838 val: crate::transmute::checked_transmute_copy(&val),
839 simd,
840 }
841 }
842}
843impl<S: Simd> From<u8x16<S>> for [u8; 16] {
844 #[inline(always)]
845 fn from(value: u8x16<S>) -> Self {
846 crate::transmute::checked_transmute_copy(&value.val)
847 }
848}
849impl<S: Simd> core::ops::Deref for u8x16<S> {
850 type Target = [u8; 16];
851 #[inline(always)]
852 fn deref(&self) -> &Self::Target {
853 crate::transmute::checked_cast_ref(&self.val)
854 }
855}
856impl<S: Simd> core::ops::DerefMut for u8x16<S> {
857 #[inline(always)]
858 fn deref_mut(&mut self) -> &mut Self::Target {
859 crate::transmute::checked_cast_mut(&mut self.val)
860 }
861}
862impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u8x16<S> {
863 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
864 crate::support::simd_debug_impl(f, "u8x16", &self.simd, self.as_array())
865 }
866}
867impl<S: Simd> SimdFrom<u8, S> for u8x16<S> {
868 #[inline(always)]
869 fn simd_from(simd: S, value: u8) -> Self {
870 simd.splat_u8x16(value)
871 }
872}
873impl<S: Simd> core::ops::Index<usize> for u8x16<S> {
874 type Output = u8;
875 #[inline(always)]
876 fn index(&self, i: usize) -> &Self::Output {
877 &self.as_array()[i]
878 }
879}
880impl<S: Simd> core::ops::IndexMut<usize> for u8x16<S> {
881 #[inline(always)]
882 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
883 &mut self.as_mut_array()[i]
884 }
885}
886impl<S: Simd> Select<u8x16<S>> for mask8x16<S> {
887 #[inline(always)]
888 fn select(self, if_true: u8x16<S>, if_false: u8x16<S>) -> u8x16<S> {
889 self.simd.select_u8x16(self, if_true, if_false)
890 }
891}
892impl<S: Simd> Bytes for u8x16<S> {
893 type Bytes = u8x16<S>;
894 #[inline(always)]
895 fn to_bytes(self) -> Self::Bytes {
896 u8x16 {
897 val: crate::transmute::checked_transmute_copy(&self.val),
898 simd: self.simd,
899 }
900 }
901 #[inline(always)]
902 fn from_bytes(value: Self::Bytes) -> Self {
903 Self {
904 val: crate::transmute::checked_transmute_copy(&value.val),
905 simd: value.simd,
906 }
907 }
908}
909impl<S: Simd> SimdBase<S> for u8x16<S> {
910 type Element = u8;
911 type ByteVector = u8x16<S>;
912 const LEN: usize = 16;
913 type Mask = mask8x16<S>;
914 type Block = u8x16<S>;
915 type Array = [u8; 16];
916 #[inline(always)]
917 fn as_slice(&self) -> &[u8] {
918 self.as_array().as_slice()
919 }
920 #[inline(always)]
921 fn as_mut_slice(&mut self) -> &mut [u8] {
922 self.as_mut_array().as_mut_slice()
923 }
924 #[inline(always)]
925 fn from_slice(simd: S, slice: &[u8]) -> Self {
926 Self::load_array_ref(simd, slice.try_into().unwrap())
927 }
928 #[inline(always)]
929 fn store_slice(&self, slice: &mut [u8]) {
930 (*self).store_array(slice.try_into().unwrap());
931 }
932 #[inline(always)]
933 fn splat(simd: S, val: u8) -> Self {
934 simd.splat_u8x16(val)
935 }
936 #[inline(always)]
937 fn block_splat(block: Self::Block) -> Self {
938 block
939 }
940 #[inline(always)]
941 fn from_fn(simd: S, mut f: impl FnMut(usize) -> u8) -> Self {
942 Self::load_array(
943 simd,
944 [
945 f(0usize),
946 f(1usize),
947 f(2usize),
948 f(3usize),
949 f(4usize),
950 f(5usize),
951 f(6usize),
952 f(7usize),
953 f(8usize),
954 f(9usize),
955 f(10usize),
956 f(11usize),
957 f(12usize),
958 f(13usize),
959 f(14usize),
960 f(15usize),
961 ],
962 )
963 }
964 #[inline(always)]
965 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
966 self.simd
967 .slide_u8x16::<SHIFT>(self, rhs.simd_into(self.simd))
968 }
969 #[inline(always)]
970 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
971 self.simd
972 .slide_within_blocks_u8x16::<SHIFT>(self, rhs.simd_into(self.simd))
973 }
974 #[inline(always)]
975 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
976 self.simd
977 .swizzle_dyn_within_blocks_u8x16(self, indices.simd_into(self.simd))
978 }
979 #[inline(always)]
980 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
981 self.simd
982 .swizzle_dyn_u8x16(self, indices.simd_into(self.simd))
983 }
984 #[inline(always)]
985 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
986 self.simd
987 .swizzle_dyn_precise_u8x16(self, indices.simd_into(self.simd))
988 }
989 #[inline(always)]
990 fn abs(self) -> Self {
991 self.simd.abs_u8x16(self)
992 }
993 #[inline(always)]
994 fn reverse(self) -> Self {
995 self.simd.reverse_u8x16(self)
996 }
997 #[inline(always)]
998 fn concat_swizzle_dyn(
999 self,
1000 rhs: impl SimdInto<Self, S>,
1001 indices: impl SimdInto<Self::Bytes, S>,
1002 ) -> Self {
1003 self.simd.concat_swizzle_dyn_u8x16(
1004 self,
1005 rhs.simd_into(self.simd),
1006 indices.simd_into(self.simd),
1007 )
1008 }
1009 #[inline(always)]
1010 fn concat_swizzle_dyn_precise(
1011 self,
1012 rhs: impl SimdInto<Self, S>,
1013 indices: impl SimdInto<Self::Bytes, S>,
1014 ) -> Self {
1015 self.simd.concat_swizzle_dyn_precise_u8x16(
1016 self,
1017 rhs.simd_into(self.simd),
1018 indices.simd_into(self.simd),
1019 )
1020 }
1021 #[inline(always)]
1022 fn compress(self, mask: Self::Mask) -> Self {
1023 self.simd.compress_u8x16(self, mask)
1024 }
1025 #[inline(always)]
1026 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
1027 self.simd
1028 .compress_merge_u8x16(self, mask, merge.simd_into(self.simd))
1029 }
1030 #[inline(always)]
1031 fn expand(self, mask: Self::Mask) -> Self {
1032 self.simd.expand_u8x16(self, mask)
1033 }
1034 #[inline(always)]
1035 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
1036 self.simd
1037 .expand_merge_u8x16(self, mask, merge.simd_into(self.simd))
1038 }
1039 #[inline(always)]
1040 fn reduce_max(self) -> Self::Element {
1041 self.simd.reduce_max_u8x16(self)
1042 }
1043 #[inline(always)]
1044 fn reduce_min(self) -> Self::Element {
1045 self.simd.reduce_min_u8x16(self)
1046 }
1047 #[inline(always)]
1048 fn reduce_max_precise(self) -> Self::Element {
1049 self.simd.reduce_max_u8x16(self)
1050 }
1051 #[inline(always)]
1052 fn reduce_min_precise(self) -> Self::Element {
1053 self.simd.reduce_min_u8x16(self)
1054 }
1055 #[inline(always)]
1056 fn reduce_sum(self) -> Self::Element {
1057 self.simd.reduce_sum_u8x16(self)
1058 }
1059 #[inline(always)]
1060 fn reduce_product(self) -> Self::Element {
1061 self.simd.reduce_product_u8x16(self)
1062 }
1063 #[inline(always)]
1064 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
1065 self.simd.max_u8x16(self, rhs.simd_into(self.simd))
1066 }
1067 #[inline(always)]
1068 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
1069 self.simd.min_u8x16(self, rhs.simd_into(self.simd))
1070 }
1071 #[inline(always)]
1072 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
1073 self.simd.max_u8x16(self, rhs.simd_into(self.simd))
1074 }
1075 #[inline(always)]
1076 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
1077 self.simd.min_u8x16(self, rhs.simd_into(self.simd))
1078 }
1079 #[inline(always)]
1080 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
1081 self.simd
1082 .clamp_u8x16(self, min.simd_into(self.simd), max.simd_into(self.simd))
1083 }
1084 #[inline(always)]
1085 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1086 self.simd.simd_eq_u8x16(self, rhs.simd_into(self.simd))
1087 }
1088 #[inline(always)]
1089 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1090 self.simd.simd_ne_u8x16(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_u8x16(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_u8x16(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_u8x16(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_u8x16(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_u8x16(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_u8x16(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_u8x16(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_u8x16(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_u8x16(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_u8x16(self, rhs.simd_into(self.simd))
1131 }
1132}
1133impl<S: Simd> crate::SimdInt<S> for u8x16<S> {
1134 #[inline(always)]
1135 fn count_ones(self) -> Self {
1136 self.simd.count_ones_u8x16(self)
1137 }
1138 #[inline(always)]
1139 fn count_zeros(self) -> Self {
1140 self.simd.count_zeros_u8x16(self)
1141 }
1142 #[inline(always)]
1143 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
1144 self.simd
1145 .saturating_add_u8x16(self, rhs.simd_into(self.simd))
1146 }
1147 #[inline(always)]
1148 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
1149 self.simd
1150 .saturating_sub_u8x16(self, rhs.simd_into(self.simd))
1151 }
1152}
1153impl<S: Simd> SimdWiden<S> for u8x16<S> {
1154 type Widened = u16x8<S>;
1155 #[inline(always)]
1156 fn widen(self) -> (Self::Widened, Self::Widened) {
1157 self.simd.widen_u8x16(self)
1158 }
1159}
1160impl<S: Simd> SimdIntWiden<S> for u8x16<S> {
1161 #[inline(always)]
1162 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
1163 self.simd.widening_mul_u8x16(self, rhs.simd_into(self.simd))
1164 }
1165 #[inline(always)]
1166 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
1167 self.simd.widening_add_u8x16(self, rhs.simd_into(self.simd))
1168 }
1169 #[inline(always)]
1170 fn pairwise_widening_add(self) -> Self::Widened {
1171 self.simd.pairwise_widening_add_u8x16(self)
1172 }
1173 #[inline(always)]
1174 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
1175 self.simd
1176 .pairwise_dot_product_u8x16(self, rhs.simd_into(self.simd))
1177 }
1178}
1179impl<S: Simd> crate::SimdCombine<S> for u8x16<S> {
1180 type Combined = u8x32<S>;
1181 #[inline(always)]
1182 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
1183 self.simd.combine_u8x16(self, rhs.simd_into(self.simd))
1184 }
1185}
1186impl<S: Simd> SimdInterleaved<S> for u8x16<S> {
1187 #[inline(always)]
1188 fn load_four_interleaved(simd: S, src: &[Self::Element]) -> [Self; 4] {
1189 let src: &[u8; 64] = src.try_into().unwrap();
1190 simd.load_four_interleaved_u8x16(src)
1191 }
1192 #[inline(always)]
1193 fn store_four_interleaved(vectors: [Self; 4], dest: &mut [Self::Element]) {
1194 let dest: &mut [u8; 64] = dest.try_into().unwrap();
1195 vectors[0].simd.store_four_interleaved_u8x16(vectors, dest);
1196 }
1197}
1198impl<S: Simd> ExtractToken for mask8x16<S> {
1199 type S = S;
1200 #[inline]
1201 fn token(&self) -> S {
1202 self.simd
1203 }
1204}
1205#[doc = "A SIMD mask of 16 logical lanes corresponding to 8-bit vector elements.\n\nThe storage representation of this type is intentionally opaque and may vary depending on the SIMD level.\n\nYou can construct this mask type using the [`Self::splat`], [`Self::from_bitmask`], [`Self::from_slice`], and [`Self::simd_from`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, mask8x16};\nfn construct_mask<S: Simd>(simd: S) {\n // From a single boolean value:\n let a = mask8x16::splat(simd, true);\n let b = mask8x16::simd_from(simd, true);\n\n // From signed integer mask lanes:\n let c = mask8x16::from_slice(simd, &[-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);\n let d = mask8x16::simd_from(simd, [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);\n\n // From a compact bitmask (same mask as above, least significant bit maps to lane 0):\n let e = mask8x16::from_bitmask(simd, 0b0001);\n\n // By setting individual lanes:\n let mut f = mask8x16::splat(simd, false);\n f.set(0, true);\n}\n```"]
1206#[derive(Clone, Copy)]
1207pub struct mask8x16<S: Simd> {
1208 pub(crate) val: S::mask8x16,
1209 pub(crate) simd: S,
1210}
1211impl<S: Simd> Seal for mask8x16<S> {}
1212impl<S: Simd> SimdFrom<[i8; 16], S> for mask8x16<S> {
1213 #[inline(always)]
1214 fn simd_from(simd: S, val: [i8; 16]) -> Self {
1215 Self {
1216 val: <S as crate::arch_types::ArchTypes>::mask8x16_from_array(simd, val),
1217 simd,
1218 }
1219 }
1220}
1221impl<S: Simd> From<mask8x16<S>> for [i8; 16] {
1222 #[inline(always)]
1223 fn from(value: mask8x16<S>) -> Self {
1224 <S as crate::arch_types::ArchTypes>::mask8x16_to_array(value.simd, value.val)
1225 }
1226}
1227impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask8x16<S> {
1228 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1229 let lanes: [i8; 16] = (*self).into();
1230 crate::support::simd_debug_impl(f, "mask8x16", &self.simd, &lanes)
1231 }
1232}
1233impl<S: Simd> SimdFrom<bool, S> for mask8x16<S> {
1234 #[inline(always)]
1235 fn simd_from(simd: S, value: bool) -> Self {
1236 simd.splat_mask8x16(value)
1237 }
1238}
1239impl<S: Simd> Select<mask8x16<S>> for mask8x16<S> {
1240 #[inline(always)]
1241 fn select(self, if_true: mask8x16<S>, if_false: mask8x16<S>) -> mask8x16<S> {
1242 self.simd.select_mask8x16(self, if_true, if_false)
1243 }
1244}
1245impl<S: Simd> SimdMask<S> for mask8x16<S> {
1246 type Element = i8;
1247 type Ints = i8x16<S>;
1248 const LEN: usize = 16;
1249 #[inline(always)]
1250 fn splat(simd: S, val: bool) -> Self {
1251 simd.splat_mask8x16(val)
1252 }
1253 #[inline(always)]
1254 fn from_bitmask(simd: S, bits: u64) -> Self {
1255 simd.from_bitmask_mask8x16(bits)
1256 }
1257 #[inline(always)]
1258 fn to_bitmask(self) -> u64 {
1259 self.simd.to_bitmask_mask8x16(self)
1260 }
1261 #[inline(always)]
1262 fn from_vector(vector: Self::Ints) -> Self {
1263 vector.token().from_vector_mask8x16(vector)
1264 }
1265 #[inline(always)]
1266 fn to_vector(self) -> Self::Ints {
1267 self.simd.to_vector_mask8x16(self)
1268 }
1269 #[inline(always)]
1270 fn set(&mut self, index: usize, value: bool) {
1271 self.simd.set_mask8x16(self, index, value);
1272 }
1273 #[inline(always)]
1274 fn from_slice(simd: S, slice: &[i8]) -> Self {
1275 let slice: &[i8; 16] = slice.try_into().unwrap();
1276 Self::simd_from(simd, *slice)
1277 }
1278 #[inline(always)]
1279 fn store_slice(&self, slice: &mut [i8]) {
1280 let slice: &mut [i8; 16] = slice.try_into().unwrap();
1281 *slice = (*self).into();
1282 }
1283 #[inline(always)]
1284 fn rotate_elements_left<const OFFSET: usize>(self) -> Self {
1285 self.simd.rotate_elements_left_mask8x16::<OFFSET>(self)
1286 }
1287 #[inline(always)]
1288 fn rotate_elements_right<const OFFSET: usize>(self) -> Self {
1289 self.simd.rotate_elements_right_mask8x16::<OFFSET>(self)
1290 }
1291 #[inline(always)]
1292 fn reverse(self) -> Self {
1293 self.simd.reverse_mask8x16(self)
1294 }
1295 #[inline(always)]
1296 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self {
1297 self.simd.simd_eq_mask8x16(self, rhs.simd_into(self.simd))
1298 }
1299 #[inline(always)]
1300 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self {
1301 self.simd.simd_ne_mask8x16(self, rhs.simd_into(self.simd))
1302 }
1303 #[inline(always)]
1304 fn any_true(self) -> bool {
1305 self.simd.any_true_mask8x16(self)
1306 }
1307 #[inline(always)]
1308 fn all_true(self) -> bool {
1309 self.simd.all_true_mask8x16(self)
1310 }
1311 #[inline(always)]
1312 fn any_false(self) -> bool {
1313 self.simd.any_false_mask8x16(self)
1314 }
1315 #[inline(always)]
1316 fn all_false(self) -> bool {
1317 self.simd.all_false_mask8x16(self)
1318 }
1319}
1320impl<S: Simd> MaskWiden<S> for mask8x16<S> {
1321 type Widened = mask16x8<S>;
1322 #[inline(always)]
1323 fn widen(self) -> (Self::Widened, Self::Widened) {
1324 self.simd.widen_mask8x16(self)
1325 }
1326}
1327impl<S: Simd> ExtractToken for i16x8<S> {
1328 type S = S;
1329 #[inline]
1330 fn token(&self) -> S {
1331 self.simd
1332 }
1333}
1334#[doc = "A SIMD vector of 8 [`i16`] elements.\n\nThis type's memory layout is identical to that of [`[i16; 8]`](prim@array), except that it is aligned to 16 bytes.\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```"]
1335#[derive(Clone, Copy)]
1336#[repr(C, align(16))]
1337pub struct i16x8<S: Simd> {
1338 pub(crate) val: S::i16x8,
1339 pub simd: S,
1340}
1341impl<S: Simd> Seal for i16x8<S> {}
1342impl<S: Simd> SimdFrom<[i16; 8], S> for i16x8<S> {
1343 #[inline(always)]
1344 fn simd_from(simd: S, val: [i16; 8]) -> Self {
1345 Self {
1346 val: crate::transmute::checked_transmute_copy(&val),
1347 simd,
1348 }
1349 }
1350}
1351impl<S: Simd> From<i16x8<S>> for [i16; 8] {
1352 #[inline(always)]
1353 fn from(value: i16x8<S>) -> Self {
1354 crate::transmute::checked_transmute_copy(&value.val)
1355 }
1356}
1357impl<S: Simd> core::ops::Deref for i16x8<S> {
1358 type Target = [i16; 8];
1359 #[inline(always)]
1360 fn deref(&self) -> &Self::Target {
1361 crate::transmute::checked_cast_ref(&self.val)
1362 }
1363}
1364impl<S: Simd> core::ops::DerefMut for i16x8<S> {
1365 #[inline(always)]
1366 fn deref_mut(&mut self) -> &mut Self::Target {
1367 crate::transmute::checked_cast_mut(&mut self.val)
1368 }
1369}
1370impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i16x8<S> {
1371 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1372 crate::support::simd_debug_impl(f, "i16x8", &self.simd, self.as_array())
1373 }
1374}
1375impl<S: Simd> SimdFrom<i16, S> for i16x8<S> {
1376 #[inline(always)]
1377 fn simd_from(simd: S, value: i16) -> Self {
1378 simd.splat_i16x8(value)
1379 }
1380}
1381impl<S: Simd> core::ops::Index<usize> for i16x8<S> {
1382 type Output = i16;
1383 #[inline(always)]
1384 fn index(&self, i: usize) -> &Self::Output {
1385 &self.as_array()[i]
1386 }
1387}
1388impl<S: Simd> core::ops::IndexMut<usize> for i16x8<S> {
1389 #[inline(always)]
1390 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
1391 &mut self.as_mut_array()[i]
1392 }
1393}
1394impl<S: Simd> Select<i16x8<S>> for mask16x8<S> {
1395 #[inline(always)]
1396 fn select(self, if_true: i16x8<S>, if_false: i16x8<S>) -> i16x8<S> {
1397 self.simd.select_i16x8(self, if_true, if_false)
1398 }
1399}
1400impl<S: Simd> Bytes for i16x8<S> {
1401 type Bytes = u8x16<S>;
1402 #[inline(always)]
1403 fn to_bytes(self) -> Self::Bytes {
1404 u8x16 {
1405 val: crate::transmute::checked_transmute_copy(&self.val),
1406 simd: self.simd,
1407 }
1408 }
1409 #[inline(always)]
1410 fn from_bytes(value: Self::Bytes) -> Self {
1411 Self {
1412 val: crate::transmute::checked_transmute_copy(&value.val),
1413 simd: value.simd,
1414 }
1415 }
1416}
1417impl<S: Simd> SimdBase<S> for i16x8<S> {
1418 type Element = i16;
1419 type ByteVector = u8x16<S>;
1420 const LEN: usize = 8;
1421 type Mask = mask16x8<S>;
1422 type Block = i16x8<S>;
1423 type Array = [i16; 8];
1424 #[inline(always)]
1425 fn as_slice(&self) -> &[i16] {
1426 self.as_array().as_slice()
1427 }
1428 #[inline(always)]
1429 fn as_mut_slice(&mut self) -> &mut [i16] {
1430 self.as_mut_array().as_mut_slice()
1431 }
1432 #[inline(always)]
1433 fn from_slice(simd: S, slice: &[i16]) -> Self {
1434 Self::load_array_ref(simd, slice.try_into().unwrap())
1435 }
1436 #[inline(always)]
1437 fn store_slice(&self, slice: &mut [i16]) {
1438 (*self).store_array(slice.try_into().unwrap());
1439 }
1440 #[inline(always)]
1441 fn splat(simd: S, val: i16) -> Self {
1442 simd.splat_i16x8(val)
1443 }
1444 #[inline(always)]
1445 fn block_splat(block: Self::Block) -> Self {
1446 block
1447 }
1448 #[inline(always)]
1449 fn from_fn(simd: S, mut f: impl FnMut(usize) -> i16) -> Self {
1450 Self::load_array(
1451 simd,
1452 [
1453 f(0usize),
1454 f(1usize),
1455 f(2usize),
1456 f(3usize),
1457 f(4usize),
1458 f(5usize),
1459 f(6usize),
1460 f(7usize),
1461 ],
1462 )
1463 }
1464 #[inline(always)]
1465 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
1466 self.simd
1467 .slide_i16x8::<SHIFT>(self, rhs.simd_into(self.simd))
1468 }
1469 #[inline(always)]
1470 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
1471 self.simd
1472 .slide_within_blocks_i16x8::<SHIFT>(self, rhs.simd_into(self.simd))
1473 }
1474 #[inline(always)]
1475 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
1476 self.simd
1477 .swizzle_dyn_within_blocks_i16x8(self, indices.simd_into(self.simd))
1478 }
1479 #[inline(always)]
1480 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
1481 self.simd
1482 .swizzle_dyn_i16x8(self, indices.simd_into(self.simd))
1483 }
1484 #[inline(always)]
1485 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
1486 self.simd
1487 .swizzle_dyn_precise_i16x8(self, indices.simd_into(self.simd))
1488 }
1489 #[inline(always)]
1490 fn abs(self) -> Self {
1491 self.simd.abs_i16x8(self)
1492 }
1493 #[inline(always)]
1494 fn reverse(self) -> Self {
1495 self.simd.reverse_i16x8(self)
1496 }
1497 #[inline(always)]
1498 fn concat_swizzle_dyn(
1499 self,
1500 rhs: impl SimdInto<Self, S>,
1501 indices: impl SimdInto<Self::Bytes, S>,
1502 ) -> Self {
1503 self.simd.concat_swizzle_dyn_i16x8(
1504 self,
1505 rhs.simd_into(self.simd),
1506 indices.simd_into(self.simd),
1507 )
1508 }
1509 #[inline(always)]
1510 fn concat_swizzle_dyn_precise(
1511 self,
1512 rhs: impl SimdInto<Self, S>,
1513 indices: impl SimdInto<Self::Bytes, S>,
1514 ) -> Self {
1515 self.simd.concat_swizzle_dyn_precise_i16x8(
1516 self,
1517 rhs.simd_into(self.simd),
1518 indices.simd_into(self.simd),
1519 )
1520 }
1521 #[inline(always)]
1522 fn compress(self, mask: Self::Mask) -> Self {
1523 self.simd.compress_i16x8(self, mask)
1524 }
1525 #[inline(always)]
1526 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
1527 self.simd
1528 .compress_merge_i16x8(self, mask, merge.simd_into(self.simd))
1529 }
1530 #[inline(always)]
1531 fn expand(self, mask: Self::Mask) -> Self {
1532 self.simd.expand_i16x8(self, mask)
1533 }
1534 #[inline(always)]
1535 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
1536 self.simd
1537 .expand_merge_i16x8(self, mask, merge.simd_into(self.simd))
1538 }
1539 #[inline(always)]
1540 fn reduce_max(self) -> Self::Element {
1541 self.simd.reduce_max_i16x8(self)
1542 }
1543 #[inline(always)]
1544 fn reduce_min(self) -> Self::Element {
1545 self.simd.reduce_min_i16x8(self)
1546 }
1547 #[inline(always)]
1548 fn reduce_max_precise(self) -> Self::Element {
1549 self.simd.reduce_max_i16x8(self)
1550 }
1551 #[inline(always)]
1552 fn reduce_min_precise(self) -> Self::Element {
1553 self.simd.reduce_min_i16x8(self)
1554 }
1555 #[inline(always)]
1556 fn reduce_sum(self) -> Self::Element {
1557 self.simd.reduce_sum_i16x8(self)
1558 }
1559 #[inline(always)]
1560 fn reduce_product(self) -> Self::Element {
1561 self.simd.reduce_product_i16x8(self)
1562 }
1563 #[inline(always)]
1564 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
1565 self.simd.max_i16x8(self, rhs.simd_into(self.simd))
1566 }
1567 #[inline(always)]
1568 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
1569 self.simd.min_i16x8(self, rhs.simd_into(self.simd))
1570 }
1571 #[inline(always)]
1572 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
1573 self.simd.max_i16x8(self, rhs.simd_into(self.simd))
1574 }
1575 #[inline(always)]
1576 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
1577 self.simd.min_i16x8(self, rhs.simd_into(self.simd))
1578 }
1579 #[inline(always)]
1580 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
1581 self.simd
1582 .clamp_i16x8(self, min.simd_into(self.simd), max.simd_into(self.simd))
1583 }
1584 #[inline(always)]
1585 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1586 self.simd.simd_eq_i16x8(self, rhs.simd_into(self.simd))
1587 }
1588 #[inline(always)]
1589 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1590 self.simd.simd_ne_i16x8(self, rhs.simd_into(self.simd))
1591 }
1592 #[inline(always)]
1593 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1594 self.simd.simd_lt_i16x8(self, rhs.simd_into(self.simd))
1595 }
1596 #[inline(always)]
1597 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1598 self.simd.simd_le_i16x8(self, rhs.simd_into(self.simd))
1599 }
1600 #[inline(always)]
1601 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1602 self.simd.simd_ge_i16x8(self, rhs.simd_into(self.simd))
1603 }
1604 #[inline(always)]
1605 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1606 self.simd.simd_gt_i16x8(self, rhs.simd_into(self.simd))
1607 }
1608 #[inline(always)]
1609 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
1610 self.simd.zip_low_i16x8(self, rhs.simd_into(self.simd))
1611 }
1612 #[inline(always)]
1613 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
1614 self.simd.zip_high_i16x8(self, rhs.simd_into(self.simd))
1615 }
1616 #[inline(always)]
1617 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
1618 self.simd.unzip_low_i16x8(self, rhs.simd_into(self.simd))
1619 }
1620 #[inline(always)]
1621 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
1622 self.simd.unzip_high_i16x8(self, rhs.simd_into(self.simd))
1623 }
1624 #[inline(always)]
1625 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
1626 self.simd.interleave_i16x8(self, rhs.simd_into(self.simd))
1627 }
1628 #[inline(always)]
1629 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
1630 self.simd.deinterleave_i16x8(self, rhs.simd_into(self.simd))
1631 }
1632}
1633impl<S: Simd> crate::SimdInt<S> for i16x8<S> {
1634 #[inline(always)]
1635 fn count_ones(self) -> Self {
1636 self.simd.count_ones_i16x8(self)
1637 }
1638 #[inline(always)]
1639 fn count_zeros(self) -> Self {
1640 self.simd.count_zeros_i16x8(self)
1641 }
1642 #[inline(always)]
1643 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
1644 self.simd
1645 .saturating_add_i16x8(self, rhs.simd_into(self.simd))
1646 }
1647 #[inline(always)]
1648 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
1649 self.simd
1650 .saturating_sub_i16x8(self, rhs.simd_into(self.simd))
1651 }
1652}
1653impl<S: Simd> SimdWiden<S> for i16x8<S> {
1654 type Widened = i32x4<S>;
1655 #[inline(always)]
1656 fn widen(self) -> (Self::Widened, Self::Widened) {
1657 self.simd.widen_i16x8(self)
1658 }
1659}
1660impl<S: Simd> SimdIntWiden<S> for i16x8<S> {
1661 #[inline(always)]
1662 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
1663 self.simd.widening_mul_i16x8(self, rhs.simd_into(self.simd))
1664 }
1665 #[inline(always)]
1666 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
1667 self.simd.widening_add_i16x8(self, rhs.simd_into(self.simd))
1668 }
1669 #[inline(always)]
1670 fn pairwise_widening_add(self) -> Self::Widened {
1671 self.simd.pairwise_widening_add_i16x8(self)
1672 }
1673 #[inline(always)]
1674 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
1675 self.simd
1676 .pairwise_dot_product_i16x8(self, rhs.simd_into(self.simd))
1677 }
1678}
1679impl<S: Simd> SimdNarrow<S> for i16x8<S> {
1680 type Narrowed = i8x16<S>;
1681 #[inline(always)]
1682 fn narrow(self, high: Self) -> Self::Narrowed {
1683 self.simd.narrow_i16x8(self, high)
1684 }
1685 #[inline(always)]
1686 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
1687 self.simd.saturating_narrow_i16x8(self, high)
1688 }
1689 #[inline(always)]
1690 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
1691 self.simd.relaxed_narrow_i16x8(self, high)
1692 }
1693}
1694impl<S: Simd> crate::SimdCombine<S> for i16x8<S> {
1695 type Combined = i16x16<S>;
1696 #[inline(always)]
1697 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
1698 self.simd.combine_i16x8(self, rhs.simd_into(self.simd))
1699 }
1700}
1701impl<S: Simd> SimdInterleaved<S> for i16x8<S> {
1702 #[inline(always)]
1703 fn load_four_interleaved(simd: S, src: &[Self::Element]) -> [Self; 4] {
1704 let src: &[i16; 32] = src.try_into().unwrap();
1705 simd.load_four_interleaved_i16x8(src)
1706 }
1707 #[inline(always)]
1708 fn store_four_interleaved(vectors: [Self; 4], dest: &mut [Self::Element]) {
1709 let dest: &mut [i16; 32] = dest.try_into().unwrap();
1710 vectors[0].simd.store_four_interleaved_i16x8(vectors, dest);
1711 }
1712}
1713impl<S: Simd> ExtractToken for u16x8<S> {
1714 type S = S;
1715 #[inline]
1716 fn token(&self) -> S {
1717 self.simd
1718 }
1719}
1720#[doc = "A SIMD vector of 8 [`u16`] elements.\n\nThis type's memory layout is identical to that of [`[u16; 8]`](prim@array), except that it is aligned to 16 bytes.\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```"]
1721#[derive(Clone, Copy)]
1722#[repr(C, align(16))]
1723pub struct u16x8<S: Simd> {
1724 pub(crate) val: S::u16x8,
1725 pub simd: S,
1726}
1727impl<S: Simd> Seal for u16x8<S> {}
1728impl<S: Simd> SimdFrom<[u16; 8], S> for u16x8<S> {
1729 #[inline(always)]
1730 fn simd_from(simd: S, val: [u16; 8]) -> Self {
1731 Self {
1732 val: crate::transmute::checked_transmute_copy(&val),
1733 simd,
1734 }
1735 }
1736}
1737impl<S: Simd> From<u16x8<S>> for [u16; 8] {
1738 #[inline(always)]
1739 fn from(value: u16x8<S>) -> Self {
1740 crate::transmute::checked_transmute_copy(&value.val)
1741 }
1742}
1743impl<S: Simd> core::ops::Deref for u16x8<S> {
1744 type Target = [u16; 8];
1745 #[inline(always)]
1746 fn deref(&self) -> &Self::Target {
1747 crate::transmute::checked_cast_ref(&self.val)
1748 }
1749}
1750impl<S: Simd> core::ops::DerefMut for u16x8<S> {
1751 #[inline(always)]
1752 fn deref_mut(&mut self) -> &mut Self::Target {
1753 crate::transmute::checked_cast_mut(&mut self.val)
1754 }
1755}
1756impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u16x8<S> {
1757 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1758 crate::support::simd_debug_impl(f, "u16x8", &self.simd, self.as_array())
1759 }
1760}
1761impl<S: Simd> SimdFrom<u16, S> for u16x8<S> {
1762 #[inline(always)]
1763 fn simd_from(simd: S, value: u16) -> Self {
1764 simd.splat_u16x8(value)
1765 }
1766}
1767impl<S: Simd> core::ops::Index<usize> for u16x8<S> {
1768 type Output = u16;
1769 #[inline(always)]
1770 fn index(&self, i: usize) -> &Self::Output {
1771 &self.as_array()[i]
1772 }
1773}
1774impl<S: Simd> core::ops::IndexMut<usize> for u16x8<S> {
1775 #[inline(always)]
1776 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
1777 &mut self.as_mut_array()[i]
1778 }
1779}
1780impl<S: Simd> Select<u16x8<S>> for mask16x8<S> {
1781 #[inline(always)]
1782 fn select(self, if_true: u16x8<S>, if_false: u16x8<S>) -> u16x8<S> {
1783 self.simd.select_u16x8(self, if_true, if_false)
1784 }
1785}
1786impl<S: Simd> Bytes for u16x8<S> {
1787 type Bytes = u8x16<S>;
1788 #[inline(always)]
1789 fn to_bytes(self) -> Self::Bytes {
1790 u8x16 {
1791 val: crate::transmute::checked_transmute_copy(&self.val),
1792 simd: self.simd,
1793 }
1794 }
1795 #[inline(always)]
1796 fn from_bytes(value: Self::Bytes) -> Self {
1797 Self {
1798 val: crate::transmute::checked_transmute_copy(&value.val),
1799 simd: value.simd,
1800 }
1801 }
1802}
1803impl<S: Simd> SimdBase<S> for u16x8<S> {
1804 type Element = u16;
1805 type ByteVector = u8x16<S>;
1806 const LEN: usize = 8;
1807 type Mask = mask16x8<S>;
1808 type Block = u16x8<S>;
1809 type Array = [u16; 8];
1810 #[inline(always)]
1811 fn as_slice(&self) -> &[u16] {
1812 self.as_array().as_slice()
1813 }
1814 #[inline(always)]
1815 fn as_mut_slice(&mut self) -> &mut [u16] {
1816 self.as_mut_array().as_mut_slice()
1817 }
1818 #[inline(always)]
1819 fn from_slice(simd: S, slice: &[u16]) -> Self {
1820 Self::load_array_ref(simd, slice.try_into().unwrap())
1821 }
1822 #[inline(always)]
1823 fn store_slice(&self, slice: &mut [u16]) {
1824 (*self).store_array(slice.try_into().unwrap());
1825 }
1826 #[inline(always)]
1827 fn splat(simd: S, val: u16) -> Self {
1828 simd.splat_u16x8(val)
1829 }
1830 #[inline(always)]
1831 fn block_splat(block: Self::Block) -> Self {
1832 block
1833 }
1834 #[inline(always)]
1835 fn from_fn(simd: S, mut f: impl FnMut(usize) -> u16) -> Self {
1836 Self::load_array(
1837 simd,
1838 [
1839 f(0usize),
1840 f(1usize),
1841 f(2usize),
1842 f(3usize),
1843 f(4usize),
1844 f(5usize),
1845 f(6usize),
1846 f(7usize),
1847 ],
1848 )
1849 }
1850 #[inline(always)]
1851 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
1852 self.simd
1853 .slide_u16x8::<SHIFT>(self, rhs.simd_into(self.simd))
1854 }
1855 #[inline(always)]
1856 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
1857 self.simd
1858 .slide_within_blocks_u16x8::<SHIFT>(self, rhs.simd_into(self.simd))
1859 }
1860 #[inline(always)]
1861 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
1862 self.simd
1863 .swizzle_dyn_within_blocks_u16x8(self, indices.simd_into(self.simd))
1864 }
1865 #[inline(always)]
1866 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
1867 self.simd
1868 .swizzle_dyn_u16x8(self, indices.simd_into(self.simd))
1869 }
1870 #[inline(always)]
1871 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
1872 self.simd
1873 .swizzle_dyn_precise_u16x8(self, indices.simd_into(self.simd))
1874 }
1875 #[inline(always)]
1876 fn abs(self) -> Self {
1877 self.simd.abs_u16x8(self)
1878 }
1879 #[inline(always)]
1880 fn reverse(self) -> Self {
1881 self.simd.reverse_u16x8(self)
1882 }
1883 #[inline(always)]
1884 fn concat_swizzle_dyn(
1885 self,
1886 rhs: impl SimdInto<Self, S>,
1887 indices: impl SimdInto<Self::Bytes, S>,
1888 ) -> Self {
1889 self.simd.concat_swizzle_dyn_u16x8(
1890 self,
1891 rhs.simd_into(self.simd),
1892 indices.simd_into(self.simd),
1893 )
1894 }
1895 #[inline(always)]
1896 fn concat_swizzle_dyn_precise(
1897 self,
1898 rhs: impl SimdInto<Self, S>,
1899 indices: impl SimdInto<Self::Bytes, S>,
1900 ) -> Self {
1901 self.simd.concat_swizzle_dyn_precise_u16x8(
1902 self,
1903 rhs.simd_into(self.simd),
1904 indices.simd_into(self.simd),
1905 )
1906 }
1907 #[inline(always)]
1908 fn compress(self, mask: Self::Mask) -> Self {
1909 self.simd.compress_u16x8(self, mask)
1910 }
1911 #[inline(always)]
1912 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
1913 self.simd
1914 .compress_merge_u16x8(self, mask, merge.simd_into(self.simd))
1915 }
1916 #[inline(always)]
1917 fn expand(self, mask: Self::Mask) -> Self {
1918 self.simd.expand_u16x8(self, mask)
1919 }
1920 #[inline(always)]
1921 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
1922 self.simd
1923 .expand_merge_u16x8(self, mask, merge.simd_into(self.simd))
1924 }
1925 #[inline(always)]
1926 fn reduce_max(self) -> Self::Element {
1927 self.simd.reduce_max_u16x8(self)
1928 }
1929 #[inline(always)]
1930 fn reduce_min(self) -> Self::Element {
1931 self.simd.reduce_min_u16x8(self)
1932 }
1933 #[inline(always)]
1934 fn reduce_max_precise(self) -> Self::Element {
1935 self.simd.reduce_max_u16x8(self)
1936 }
1937 #[inline(always)]
1938 fn reduce_min_precise(self) -> Self::Element {
1939 self.simd.reduce_min_u16x8(self)
1940 }
1941 #[inline(always)]
1942 fn reduce_sum(self) -> Self::Element {
1943 self.simd.reduce_sum_u16x8(self)
1944 }
1945 #[inline(always)]
1946 fn reduce_product(self) -> Self::Element {
1947 self.simd.reduce_product_u16x8(self)
1948 }
1949 #[inline(always)]
1950 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
1951 self.simd.max_u16x8(self, rhs.simd_into(self.simd))
1952 }
1953 #[inline(always)]
1954 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
1955 self.simd.min_u16x8(self, rhs.simd_into(self.simd))
1956 }
1957 #[inline(always)]
1958 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
1959 self.simd.max_u16x8(self, rhs.simd_into(self.simd))
1960 }
1961 #[inline(always)]
1962 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
1963 self.simd.min_u16x8(self, rhs.simd_into(self.simd))
1964 }
1965 #[inline(always)]
1966 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
1967 self.simd
1968 .clamp_u16x8(self, min.simd_into(self.simd), max.simd_into(self.simd))
1969 }
1970 #[inline(always)]
1971 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1972 self.simd.simd_eq_u16x8(self, rhs.simd_into(self.simd))
1973 }
1974 #[inline(always)]
1975 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1976 self.simd.simd_ne_u16x8(self, rhs.simd_into(self.simd))
1977 }
1978 #[inline(always)]
1979 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1980 self.simd.simd_lt_u16x8(self, rhs.simd_into(self.simd))
1981 }
1982 #[inline(always)]
1983 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1984 self.simd.simd_le_u16x8(self, rhs.simd_into(self.simd))
1985 }
1986 #[inline(always)]
1987 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1988 self.simd.simd_ge_u16x8(self, rhs.simd_into(self.simd))
1989 }
1990 #[inline(always)]
1991 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
1992 self.simd.simd_gt_u16x8(self, rhs.simd_into(self.simd))
1993 }
1994 #[inline(always)]
1995 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
1996 self.simd.zip_low_u16x8(self, rhs.simd_into(self.simd))
1997 }
1998 #[inline(always)]
1999 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
2000 self.simd.zip_high_u16x8(self, rhs.simd_into(self.simd))
2001 }
2002 #[inline(always)]
2003 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
2004 self.simd.unzip_low_u16x8(self, rhs.simd_into(self.simd))
2005 }
2006 #[inline(always)]
2007 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
2008 self.simd.unzip_high_u16x8(self, rhs.simd_into(self.simd))
2009 }
2010 #[inline(always)]
2011 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
2012 self.simd.interleave_u16x8(self, rhs.simd_into(self.simd))
2013 }
2014 #[inline(always)]
2015 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
2016 self.simd.deinterleave_u16x8(self, rhs.simd_into(self.simd))
2017 }
2018}
2019impl<S: Simd> crate::SimdInt<S> for u16x8<S> {
2020 #[inline(always)]
2021 fn count_ones(self) -> Self {
2022 self.simd.count_ones_u16x8(self)
2023 }
2024 #[inline(always)]
2025 fn count_zeros(self) -> Self {
2026 self.simd.count_zeros_u16x8(self)
2027 }
2028 #[inline(always)]
2029 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
2030 self.simd
2031 .saturating_add_u16x8(self, rhs.simd_into(self.simd))
2032 }
2033 #[inline(always)]
2034 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
2035 self.simd
2036 .saturating_sub_u16x8(self, rhs.simd_into(self.simd))
2037 }
2038}
2039impl<S: Simd> SimdWiden<S> for u16x8<S> {
2040 type Widened = u32x4<S>;
2041 #[inline(always)]
2042 fn widen(self) -> (Self::Widened, Self::Widened) {
2043 self.simd.widen_u16x8(self)
2044 }
2045}
2046impl<S: Simd> SimdIntWiden<S> for u16x8<S> {
2047 #[inline(always)]
2048 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
2049 self.simd.widening_mul_u16x8(self, rhs.simd_into(self.simd))
2050 }
2051 #[inline(always)]
2052 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
2053 self.simd.widening_add_u16x8(self, rhs.simd_into(self.simd))
2054 }
2055 #[inline(always)]
2056 fn pairwise_widening_add(self) -> Self::Widened {
2057 self.simd.pairwise_widening_add_u16x8(self)
2058 }
2059 #[inline(always)]
2060 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
2061 self.simd
2062 .pairwise_dot_product_u16x8(self, rhs.simd_into(self.simd))
2063 }
2064}
2065impl<S: Simd> SimdNarrow<S> for u16x8<S> {
2066 type Narrowed = u8x16<S>;
2067 #[inline(always)]
2068 fn narrow(self, high: Self) -> Self::Narrowed {
2069 self.simd.narrow_u16x8(self, high)
2070 }
2071 #[inline(always)]
2072 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
2073 self.simd.saturating_narrow_u16x8(self, high)
2074 }
2075 #[inline(always)]
2076 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
2077 self.simd.relaxed_narrow_u16x8(self, high)
2078 }
2079}
2080impl<S: Simd> crate::SimdCombine<S> for u16x8<S> {
2081 type Combined = u16x16<S>;
2082 #[inline(always)]
2083 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
2084 self.simd.combine_u16x8(self, rhs.simd_into(self.simd))
2085 }
2086}
2087impl<S: Simd> SimdInterleaved<S> for u16x8<S> {
2088 #[inline(always)]
2089 fn load_four_interleaved(simd: S, src: &[Self::Element]) -> [Self; 4] {
2090 let src: &[u16; 32] = src.try_into().unwrap();
2091 simd.load_four_interleaved_u16x8(src)
2092 }
2093 #[inline(always)]
2094 fn store_four_interleaved(vectors: [Self; 4], dest: &mut [Self::Element]) {
2095 let dest: &mut [u16; 32] = dest.try_into().unwrap();
2096 vectors[0].simd.store_four_interleaved_u16x8(vectors, dest);
2097 }
2098}
2099impl<S: Simd> ExtractToken for mask16x8<S> {
2100 type S = S;
2101 #[inline]
2102 fn token(&self) -> S {
2103 self.simd
2104 }
2105}
2106#[doc = "A SIMD mask of 8 logical lanes corresponding to 16-bit vector elements.\n\nThe storage representation of this type is intentionally opaque and may vary depending on the SIMD level.\n\nYou can construct this mask type using the [`Self::splat`], [`Self::from_bitmask`], [`Self::from_slice`], and [`Self::simd_from`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, mask16x8};\nfn construct_mask<S: Simd>(simd: S) {\n // From a single boolean value:\n let a = mask16x8::splat(simd, true);\n let b = mask16x8::simd_from(simd, true);\n\n // From signed integer mask lanes:\n let c = mask16x8::from_slice(simd, &[-1, 0, 0, 0, 0, 0, 0, 0]);\n let d = mask16x8::simd_from(simd, [-1, 0, 0, 0, 0, 0, 0, 0]);\n\n // From a compact bitmask (same mask as above, least significant bit maps to lane 0):\n let e = mask16x8::from_bitmask(simd, 0b0001);\n\n // By setting individual lanes:\n let mut f = mask16x8::splat(simd, false);\n f.set(0, true);\n}\n```"]
2107#[derive(Clone, Copy)]
2108pub struct mask16x8<S: Simd> {
2109 pub(crate) val: S::mask16x8,
2110 pub(crate) simd: S,
2111}
2112impl<S: Simd> Seal for mask16x8<S> {}
2113impl<S: Simd> SimdFrom<[i16; 8], S> for mask16x8<S> {
2114 #[inline(always)]
2115 fn simd_from(simd: S, val: [i16; 8]) -> Self {
2116 Self {
2117 val: <S as crate::arch_types::ArchTypes>::mask16x8_from_array(simd, val),
2118 simd,
2119 }
2120 }
2121}
2122impl<S: Simd> From<mask16x8<S>> for [i16; 8] {
2123 #[inline(always)]
2124 fn from(value: mask16x8<S>) -> Self {
2125 <S as crate::arch_types::ArchTypes>::mask16x8_to_array(value.simd, value.val)
2126 }
2127}
2128impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask16x8<S> {
2129 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2130 let lanes: [i16; 8] = (*self).into();
2131 crate::support::simd_debug_impl(f, "mask16x8", &self.simd, &lanes)
2132 }
2133}
2134impl<S: Simd> SimdFrom<bool, S> for mask16x8<S> {
2135 #[inline(always)]
2136 fn simd_from(simd: S, value: bool) -> Self {
2137 simd.splat_mask16x8(value)
2138 }
2139}
2140impl<S: Simd> Select<mask16x8<S>> for mask16x8<S> {
2141 #[inline(always)]
2142 fn select(self, if_true: mask16x8<S>, if_false: mask16x8<S>) -> mask16x8<S> {
2143 self.simd.select_mask16x8(self, if_true, if_false)
2144 }
2145}
2146impl<S: Simd> SimdMask<S> for mask16x8<S> {
2147 type Element = i16;
2148 type Ints = i16x8<S>;
2149 const LEN: usize = 8;
2150 #[inline(always)]
2151 fn splat(simd: S, val: bool) -> Self {
2152 simd.splat_mask16x8(val)
2153 }
2154 #[inline(always)]
2155 fn from_bitmask(simd: S, bits: u64) -> Self {
2156 simd.from_bitmask_mask16x8(bits)
2157 }
2158 #[inline(always)]
2159 fn to_bitmask(self) -> u64 {
2160 self.simd.to_bitmask_mask16x8(self)
2161 }
2162 #[inline(always)]
2163 fn from_vector(vector: Self::Ints) -> Self {
2164 vector.token().from_vector_mask16x8(vector)
2165 }
2166 #[inline(always)]
2167 fn to_vector(self) -> Self::Ints {
2168 self.simd.to_vector_mask16x8(self)
2169 }
2170 #[inline(always)]
2171 fn set(&mut self, index: usize, value: bool) {
2172 self.simd.set_mask16x8(self, index, value);
2173 }
2174 #[inline(always)]
2175 fn from_slice(simd: S, slice: &[i16]) -> Self {
2176 let slice: &[i16; 8] = slice.try_into().unwrap();
2177 Self::simd_from(simd, *slice)
2178 }
2179 #[inline(always)]
2180 fn store_slice(&self, slice: &mut [i16]) {
2181 let slice: &mut [i16; 8] = slice.try_into().unwrap();
2182 *slice = (*self).into();
2183 }
2184 #[inline(always)]
2185 fn rotate_elements_left<const OFFSET: usize>(self) -> Self {
2186 self.simd.rotate_elements_left_mask16x8::<OFFSET>(self)
2187 }
2188 #[inline(always)]
2189 fn rotate_elements_right<const OFFSET: usize>(self) -> Self {
2190 self.simd.rotate_elements_right_mask16x8::<OFFSET>(self)
2191 }
2192 #[inline(always)]
2193 fn reverse(self) -> Self {
2194 self.simd.reverse_mask16x8(self)
2195 }
2196 #[inline(always)]
2197 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self {
2198 self.simd.simd_eq_mask16x8(self, rhs.simd_into(self.simd))
2199 }
2200 #[inline(always)]
2201 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self {
2202 self.simd.simd_ne_mask16x8(self, rhs.simd_into(self.simd))
2203 }
2204 #[inline(always)]
2205 fn any_true(self) -> bool {
2206 self.simd.any_true_mask16x8(self)
2207 }
2208 #[inline(always)]
2209 fn all_true(self) -> bool {
2210 self.simd.all_true_mask16x8(self)
2211 }
2212 #[inline(always)]
2213 fn any_false(self) -> bool {
2214 self.simd.any_false_mask16x8(self)
2215 }
2216 #[inline(always)]
2217 fn all_false(self) -> bool {
2218 self.simd.all_false_mask16x8(self)
2219 }
2220}
2221impl<S: Simd> MaskWiden<S> for mask16x8<S> {
2222 type Widened = mask32x4<S>;
2223 #[inline(always)]
2224 fn widen(self) -> (Self::Widened, Self::Widened) {
2225 self.simd.widen_mask16x8(self)
2226 }
2227}
2228impl<S: Simd> MaskNarrow<S> for mask16x8<S> {
2229 type Narrowed = mask8x16<S>;
2230 #[inline(always)]
2231 fn narrow(self, high: Self) -> Self::Narrowed {
2232 self.simd.narrow_mask16x8(self, high)
2233 }
2234}
2235impl<S: Simd> ExtractToken for i32x4<S> {
2236 type S = S;
2237 #[inline]
2238 fn token(&self) -> S {
2239 self.simd
2240 }
2241}
2242#[doc = "A SIMD vector of 4 [`i32`] elements.\n\nThis type's memory layout is identical to that of [`[i32; 4]`](prim@array), except that it is aligned to 16 bytes.\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```"]
2243#[derive(Clone, Copy)]
2244#[repr(C, align(16))]
2245pub struct i32x4<S: Simd> {
2246 pub(crate) val: S::i32x4,
2247 pub simd: S,
2248}
2249impl<S: Simd> Seal for i32x4<S> {}
2250impl<S: Simd> SimdFrom<[i32; 4], S> for i32x4<S> {
2251 #[inline(always)]
2252 fn simd_from(simd: S, val: [i32; 4]) -> Self {
2253 Self {
2254 val: crate::transmute::checked_transmute_copy(&val),
2255 simd,
2256 }
2257 }
2258}
2259impl<S: Simd> From<i32x4<S>> for [i32; 4] {
2260 #[inline(always)]
2261 fn from(value: i32x4<S>) -> Self {
2262 crate::transmute::checked_transmute_copy(&value.val)
2263 }
2264}
2265impl<S: Simd> core::ops::Deref for i32x4<S> {
2266 type Target = [i32; 4];
2267 #[inline(always)]
2268 fn deref(&self) -> &Self::Target {
2269 crate::transmute::checked_cast_ref(&self.val)
2270 }
2271}
2272impl<S: Simd> core::ops::DerefMut for i32x4<S> {
2273 #[inline(always)]
2274 fn deref_mut(&mut self) -> &mut Self::Target {
2275 crate::transmute::checked_cast_mut(&mut self.val)
2276 }
2277}
2278impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i32x4<S> {
2279 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2280 crate::support::simd_debug_impl(f, "i32x4", &self.simd, self.as_array())
2281 }
2282}
2283impl<S: Simd> SimdFrom<i32, S> for i32x4<S> {
2284 #[inline(always)]
2285 fn simd_from(simd: S, value: i32) -> Self {
2286 simd.splat_i32x4(value)
2287 }
2288}
2289impl<S: Simd> core::ops::Index<usize> for i32x4<S> {
2290 type Output = i32;
2291 #[inline(always)]
2292 fn index(&self, i: usize) -> &Self::Output {
2293 &self.as_array()[i]
2294 }
2295}
2296impl<S: Simd> core::ops::IndexMut<usize> for i32x4<S> {
2297 #[inline(always)]
2298 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
2299 &mut self.as_mut_array()[i]
2300 }
2301}
2302impl<S: Simd> Select<i32x4<S>> for mask32x4<S> {
2303 #[inline(always)]
2304 fn select(self, if_true: i32x4<S>, if_false: i32x4<S>) -> i32x4<S> {
2305 self.simd.select_i32x4(self, if_true, if_false)
2306 }
2307}
2308impl<S: Simd> Bytes for i32x4<S> {
2309 type Bytes = u8x16<S>;
2310 #[inline(always)]
2311 fn to_bytes(self) -> Self::Bytes {
2312 u8x16 {
2313 val: crate::transmute::checked_transmute_copy(&self.val),
2314 simd: self.simd,
2315 }
2316 }
2317 #[inline(always)]
2318 fn from_bytes(value: Self::Bytes) -> Self {
2319 Self {
2320 val: crate::transmute::checked_transmute_copy(&value.val),
2321 simd: value.simd,
2322 }
2323 }
2324}
2325impl<S: Simd> SimdBase<S> for i32x4<S> {
2326 type Element = i32;
2327 type ByteVector = u8x16<S>;
2328 const LEN: usize = 4;
2329 type Mask = mask32x4<S>;
2330 type Block = i32x4<S>;
2331 type Array = [i32; 4];
2332 #[inline(always)]
2333 fn as_slice(&self) -> &[i32] {
2334 self.as_array().as_slice()
2335 }
2336 #[inline(always)]
2337 fn as_mut_slice(&mut self) -> &mut [i32] {
2338 self.as_mut_array().as_mut_slice()
2339 }
2340 #[inline(always)]
2341 fn from_slice(simd: S, slice: &[i32]) -> Self {
2342 Self::load_array_ref(simd, slice.try_into().unwrap())
2343 }
2344 #[inline(always)]
2345 fn store_slice(&self, slice: &mut [i32]) {
2346 (*self).store_array(slice.try_into().unwrap());
2347 }
2348 #[inline(always)]
2349 fn splat(simd: S, val: i32) -> Self {
2350 simd.splat_i32x4(val)
2351 }
2352 #[inline(always)]
2353 fn block_splat(block: Self::Block) -> Self {
2354 block
2355 }
2356 #[inline(always)]
2357 fn from_fn(simd: S, mut f: impl FnMut(usize) -> i32) -> Self {
2358 Self::load_array(simd, [f(0usize), f(1usize), f(2usize), f(3usize)])
2359 }
2360 #[inline(always)]
2361 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
2362 self.simd
2363 .slide_i32x4::<SHIFT>(self, rhs.simd_into(self.simd))
2364 }
2365 #[inline(always)]
2366 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
2367 self.simd
2368 .slide_within_blocks_i32x4::<SHIFT>(self, rhs.simd_into(self.simd))
2369 }
2370 #[inline(always)]
2371 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
2372 self.simd
2373 .swizzle_dyn_within_blocks_i32x4(self, indices.simd_into(self.simd))
2374 }
2375 #[inline(always)]
2376 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
2377 self.simd
2378 .swizzle_dyn_i32x4(self, indices.simd_into(self.simd))
2379 }
2380 #[inline(always)]
2381 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
2382 self.simd
2383 .swizzle_dyn_precise_i32x4(self, indices.simd_into(self.simd))
2384 }
2385 #[inline(always)]
2386 fn abs(self) -> Self {
2387 self.simd.abs_i32x4(self)
2388 }
2389 #[inline(always)]
2390 fn reverse(self) -> Self {
2391 self.simd.reverse_i32x4(self)
2392 }
2393 #[inline(always)]
2394 fn concat_swizzle_dyn(
2395 self,
2396 rhs: impl SimdInto<Self, S>,
2397 indices: impl SimdInto<Self::Bytes, S>,
2398 ) -> Self {
2399 self.simd.concat_swizzle_dyn_i32x4(
2400 self,
2401 rhs.simd_into(self.simd),
2402 indices.simd_into(self.simd),
2403 )
2404 }
2405 #[inline(always)]
2406 fn concat_swizzle_dyn_precise(
2407 self,
2408 rhs: impl SimdInto<Self, S>,
2409 indices: impl SimdInto<Self::Bytes, S>,
2410 ) -> Self {
2411 self.simd.concat_swizzle_dyn_precise_i32x4(
2412 self,
2413 rhs.simd_into(self.simd),
2414 indices.simd_into(self.simd),
2415 )
2416 }
2417 #[inline(always)]
2418 fn compress(self, mask: Self::Mask) -> Self {
2419 self.simd.compress_i32x4(self, mask)
2420 }
2421 #[inline(always)]
2422 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
2423 self.simd
2424 .compress_merge_i32x4(self, mask, merge.simd_into(self.simd))
2425 }
2426 #[inline(always)]
2427 fn expand(self, mask: Self::Mask) -> Self {
2428 self.simd.expand_i32x4(self, mask)
2429 }
2430 #[inline(always)]
2431 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
2432 self.simd
2433 .expand_merge_i32x4(self, mask, merge.simd_into(self.simd))
2434 }
2435 #[inline(always)]
2436 fn reduce_max(self) -> Self::Element {
2437 self.simd.reduce_max_i32x4(self)
2438 }
2439 #[inline(always)]
2440 fn reduce_min(self) -> Self::Element {
2441 self.simd.reduce_min_i32x4(self)
2442 }
2443 #[inline(always)]
2444 fn reduce_max_precise(self) -> Self::Element {
2445 self.simd.reduce_max_i32x4(self)
2446 }
2447 #[inline(always)]
2448 fn reduce_min_precise(self) -> Self::Element {
2449 self.simd.reduce_min_i32x4(self)
2450 }
2451 #[inline(always)]
2452 fn reduce_sum(self) -> Self::Element {
2453 self.simd.reduce_sum_i32x4(self)
2454 }
2455 #[inline(always)]
2456 fn reduce_product(self) -> Self::Element {
2457 self.simd.reduce_product_i32x4(self)
2458 }
2459 #[inline(always)]
2460 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
2461 self.simd.max_i32x4(self, rhs.simd_into(self.simd))
2462 }
2463 #[inline(always)]
2464 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
2465 self.simd.min_i32x4(self, rhs.simd_into(self.simd))
2466 }
2467 #[inline(always)]
2468 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
2469 self.simd.max_i32x4(self, rhs.simd_into(self.simd))
2470 }
2471 #[inline(always)]
2472 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
2473 self.simd.min_i32x4(self, rhs.simd_into(self.simd))
2474 }
2475 #[inline(always)]
2476 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
2477 self.simd
2478 .clamp_i32x4(self, min.simd_into(self.simd), max.simd_into(self.simd))
2479 }
2480 #[inline(always)]
2481 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2482 self.simd.simd_eq_i32x4(self, rhs.simd_into(self.simd))
2483 }
2484 #[inline(always)]
2485 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2486 self.simd.simd_ne_i32x4(self, rhs.simd_into(self.simd))
2487 }
2488 #[inline(always)]
2489 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2490 self.simd.simd_lt_i32x4(self, rhs.simd_into(self.simd))
2491 }
2492 #[inline(always)]
2493 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2494 self.simd.simd_le_i32x4(self, rhs.simd_into(self.simd))
2495 }
2496 #[inline(always)]
2497 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2498 self.simd.simd_ge_i32x4(self, rhs.simd_into(self.simd))
2499 }
2500 #[inline(always)]
2501 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2502 self.simd.simd_gt_i32x4(self, rhs.simd_into(self.simd))
2503 }
2504 #[inline(always)]
2505 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
2506 self.simd.zip_low_i32x4(self, rhs.simd_into(self.simd))
2507 }
2508 #[inline(always)]
2509 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
2510 self.simd.zip_high_i32x4(self, rhs.simd_into(self.simd))
2511 }
2512 #[inline(always)]
2513 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
2514 self.simd.unzip_low_i32x4(self, rhs.simd_into(self.simd))
2515 }
2516 #[inline(always)]
2517 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
2518 self.simd.unzip_high_i32x4(self, rhs.simd_into(self.simd))
2519 }
2520 #[inline(always)]
2521 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
2522 self.simd.interleave_i32x4(self, rhs.simd_into(self.simd))
2523 }
2524 #[inline(always)]
2525 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
2526 self.simd.deinterleave_i32x4(self, rhs.simd_into(self.simd))
2527 }
2528}
2529impl<S: Simd> crate::SimdInt<S> for i32x4<S> {
2530 #[inline(always)]
2531 fn count_ones(self) -> Self {
2532 self.simd.count_ones_i32x4(self)
2533 }
2534 #[inline(always)]
2535 fn count_zeros(self) -> Self {
2536 self.simd.count_zeros_i32x4(self)
2537 }
2538 #[inline(always)]
2539 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
2540 self.simd
2541 .saturating_add_i32x4(self, rhs.simd_into(self.simd))
2542 }
2543 #[inline(always)]
2544 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
2545 self.simd
2546 .saturating_sub_i32x4(self, rhs.simd_into(self.simd))
2547 }
2548}
2549impl<S: Simd> SimdCvtTruncate<f32x4<S>> for i32x4<S> {
2550 #[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."]
2551 #[inline(always)]
2552 fn truncate_from(x: f32x4<S>) -> Self {
2553 x.simd.cvt_i32_f32x4(x)
2554 }
2555 #[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."]
2556 #[inline(always)]
2557 fn truncate_from_precise(x: f32x4<S>) -> Self {
2558 x.simd.cvt_i32_precise_f32x4(x)
2559 }
2560}
2561impl<S: Simd> SimdWiden<S> for i32x4<S> {
2562 type Widened = i64x2<S>;
2563 #[inline(always)]
2564 fn widen(self) -> (Self::Widened, Self::Widened) {
2565 self.simd.widen_i32x4(self)
2566 }
2567}
2568impl<S: Simd> SimdIntWiden<S> for i32x4<S> {
2569 #[inline(always)]
2570 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
2571 self.simd.widening_mul_i32x4(self, rhs.simd_into(self.simd))
2572 }
2573 #[inline(always)]
2574 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
2575 self.simd.widening_add_i32x4(self, rhs.simd_into(self.simd))
2576 }
2577 #[inline(always)]
2578 fn pairwise_widening_add(self) -> Self::Widened {
2579 self.simd.pairwise_widening_add_i32x4(self)
2580 }
2581 #[inline(always)]
2582 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
2583 self.simd
2584 .pairwise_dot_product_i32x4(self, rhs.simd_into(self.simd))
2585 }
2586}
2587impl<S: Simd> SimdNarrow<S> for i32x4<S> {
2588 type Narrowed = i16x8<S>;
2589 #[inline(always)]
2590 fn narrow(self, high: Self) -> Self::Narrowed {
2591 self.simd.narrow_i32x4(self, high)
2592 }
2593 #[inline(always)]
2594 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
2595 self.simd.saturating_narrow_i32x4(self, high)
2596 }
2597 #[inline(always)]
2598 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
2599 self.simd.relaxed_narrow_i32x4(self, high)
2600 }
2601}
2602impl<S: Simd> crate::SimdCombine<S> for i32x4<S> {
2603 type Combined = i32x8<S>;
2604 #[inline(always)]
2605 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
2606 self.simd.combine_i32x4(self, rhs.simd_into(self.simd))
2607 }
2608}
2609impl<S: Simd> SimdInterleaved<S> for i32x4<S> {
2610 #[inline(always)]
2611 fn load_four_interleaved(simd: S, src: &[Self::Element]) -> [Self; 4] {
2612 let src: &[i32; 16] = src.try_into().unwrap();
2613 simd.load_four_interleaved_i32x4(src)
2614 }
2615 #[inline(always)]
2616 fn store_four_interleaved(vectors: [Self; 4], dest: &mut [Self::Element]) {
2617 let dest: &mut [i32; 16] = dest.try_into().unwrap();
2618 vectors[0].simd.store_four_interleaved_i32x4(vectors, dest);
2619 }
2620}
2621impl<S: Simd> ExtractToken for u32x4<S> {
2622 type S = S;
2623 #[inline]
2624 fn token(&self) -> S {
2625 self.simd
2626 }
2627}
2628#[doc = "A SIMD vector of 4 [`u32`] elements.\n\nThis type's memory layout is identical to that of [`[u32; 4]`](prim@array), except that it is aligned to 16 bytes.\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```"]
2629#[derive(Clone, Copy)]
2630#[repr(C, align(16))]
2631pub struct u32x4<S: Simd> {
2632 pub(crate) val: S::u32x4,
2633 pub simd: S,
2634}
2635impl<S: Simd> Seal for u32x4<S> {}
2636impl<S: Simd> SimdFrom<[u32; 4], S> for u32x4<S> {
2637 #[inline(always)]
2638 fn simd_from(simd: S, val: [u32; 4]) -> Self {
2639 Self {
2640 val: crate::transmute::checked_transmute_copy(&val),
2641 simd,
2642 }
2643 }
2644}
2645impl<S: Simd> From<u32x4<S>> for [u32; 4] {
2646 #[inline(always)]
2647 fn from(value: u32x4<S>) -> Self {
2648 crate::transmute::checked_transmute_copy(&value.val)
2649 }
2650}
2651impl<S: Simd> core::ops::Deref for u32x4<S> {
2652 type Target = [u32; 4];
2653 #[inline(always)]
2654 fn deref(&self) -> &Self::Target {
2655 crate::transmute::checked_cast_ref(&self.val)
2656 }
2657}
2658impl<S: Simd> core::ops::DerefMut for u32x4<S> {
2659 #[inline(always)]
2660 fn deref_mut(&mut self) -> &mut Self::Target {
2661 crate::transmute::checked_cast_mut(&mut self.val)
2662 }
2663}
2664impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u32x4<S> {
2665 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2666 crate::support::simd_debug_impl(f, "u32x4", &self.simd, self.as_array())
2667 }
2668}
2669impl<S: Simd> SimdFrom<u32, S> for u32x4<S> {
2670 #[inline(always)]
2671 fn simd_from(simd: S, value: u32) -> Self {
2672 simd.splat_u32x4(value)
2673 }
2674}
2675impl<S: Simd> core::ops::Index<usize> for u32x4<S> {
2676 type Output = u32;
2677 #[inline(always)]
2678 fn index(&self, i: usize) -> &Self::Output {
2679 &self.as_array()[i]
2680 }
2681}
2682impl<S: Simd> core::ops::IndexMut<usize> for u32x4<S> {
2683 #[inline(always)]
2684 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
2685 &mut self.as_mut_array()[i]
2686 }
2687}
2688impl<S: Simd> Select<u32x4<S>> for mask32x4<S> {
2689 #[inline(always)]
2690 fn select(self, if_true: u32x4<S>, if_false: u32x4<S>) -> u32x4<S> {
2691 self.simd.select_u32x4(self, if_true, if_false)
2692 }
2693}
2694impl<S: Simd> Bytes for u32x4<S> {
2695 type Bytes = u8x16<S>;
2696 #[inline(always)]
2697 fn to_bytes(self) -> Self::Bytes {
2698 u8x16 {
2699 val: crate::transmute::checked_transmute_copy(&self.val),
2700 simd: self.simd,
2701 }
2702 }
2703 #[inline(always)]
2704 fn from_bytes(value: Self::Bytes) -> Self {
2705 Self {
2706 val: crate::transmute::checked_transmute_copy(&value.val),
2707 simd: value.simd,
2708 }
2709 }
2710}
2711impl<S: Simd> SimdBase<S> for u32x4<S> {
2712 type Element = u32;
2713 type ByteVector = u8x16<S>;
2714 const LEN: usize = 4;
2715 type Mask = mask32x4<S>;
2716 type Block = u32x4<S>;
2717 type Array = [u32; 4];
2718 #[inline(always)]
2719 fn as_slice(&self) -> &[u32] {
2720 self.as_array().as_slice()
2721 }
2722 #[inline(always)]
2723 fn as_mut_slice(&mut self) -> &mut [u32] {
2724 self.as_mut_array().as_mut_slice()
2725 }
2726 #[inline(always)]
2727 fn from_slice(simd: S, slice: &[u32]) -> Self {
2728 Self::load_array_ref(simd, slice.try_into().unwrap())
2729 }
2730 #[inline(always)]
2731 fn store_slice(&self, slice: &mut [u32]) {
2732 (*self).store_array(slice.try_into().unwrap());
2733 }
2734 #[inline(always)]
2735 fn splat(simd: S, val: u32) -> Self {
2736 simd.splat_u32x4(val)
2737 }
2738 #[inline(always)]
2739 fn block_splat(block: Self::Block) -> Self {
2740 block
2741 }
2742 #[inline(always)]
2743 fn from_fn(simd: S, mut f: impl FnMut(usize) -> u32) -> Self {
2744 Self::load_array(simd, [f(0usize), f(1usize), f(2usize), f(3usize)])
2745 }
2746 #[inline(always)]
2747 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
2748 self.simd
2749 .slide_u32x4::<SHIFT>(self, rhs.simd_into(self.simd))
2750 }
2751 #[inline(always)]
2752 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
2753 self.simd
2754 .slide_within_blocks_u32x4::<SHIFT>(self, rhs.simd_into(self.simd))
2755 }
2756 #[inline(always)]
2757 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
2758 self.simd
2759 .swizzle_dyn_within_blocks_u32x4(self, indices.simd_into(self.simd))
2760 }
2761 #[inline(always)]
2762 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
2763 self.simd
2764 .swizzle_dyn_u32x4(self, indices.simd_into(self.simd))
2765 }
2766 #[inline(always)]
2767 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
2768 self.simd
2769 .swizzle_dyn_precise_u32x4(self, indices.simd_into(self.simd))
2770 }
2771 #[inline(always)]
2772 fn abs(self) -> Self {
2773 self.simd.abs_u32x4(self)
2774 }
2775 #[inline(always)]
2776 fn reverse(self) -> Self {
2777 self.simd.reverse_u32x4(self)
2778 }
2779 #[inline(always)]
2780 fn concat_swizzle_dyn(
2781 self,
2782 rhs: impl SimdInto<Self, S>,
2783 indices: impl SimdInto<Self::Bytes, S>,
2784 ) -> Self {
2785 self.simd.concat_swizzle_dyn_u32x4(
2786 self,
2787 rhs.simd_into(self.simd),
2788 indices.simd_into(self.simd),
2789 )
2790 }
2791 #[inline(always)]
2792 fn concat_swizzle_dyn_precise(
2793 self,
2794 rhs: impl SimdInto<Self, S>,
2795 indices: impl SimdInto<Self::Bytes, S>,
2796 ) -> Self {
2797 self.simd.concat_swizzle_dyn_precise_u32x4(
2798 self,
2799 rhs.simd_into(self.simd),
2800 indices.simd_into(self.simd),
2801 )
2802 }
2803 #[inline(always)]
2804 fn compress(self, mask: Self::Mask) -> Self {
2805 self.simd.compress_u32x4(self, mask)
2806 }
2807 #[inline(always)]
2808 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
2809 self.simd
2810 .compress_merge_u32x4(self, mask, merge.simd_into(self.simd))
2811 }
2812 #[inline(always)]
2813 fn expand(self, mask: Self::Mask) -> Self {
2814 self.simd.expand_u32x4(self, mask)
2815 }
2816 #[inline(always)]
2817 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
2818 self.simd
2819 .expand_merge_u32x4(self, mask, merge.simd_into(self.simd))
2820 }
2821 #[inline(always)]
2822 fn reduce_max(self) -> Self::Element {
2823 self.simd.reduce_max_u32x4(self)
2824 }
2825 #[inline(always)]
2826 fn reduce_min(self) -> Self::Element {
2827 self.simd.reduce_min_u32x4(self)
2828 }
2829 #[inline(always)]
2830 fn reduce_max_precise(self) -> Self::Element {
2831 self.simd.reduce_max_u32x4(self)
2832 }
2833 #[inline(always)]
2834 fn reduce_min_precise(self) -> Self::Element {
2835 self.simd.reduce_min_u32x4(self)
2836 }
2837 #[inline(always)]
2838 fn reduce_sum(self) -> Self::Element {
2839 self.simd.reduce_sum_u32x4(self)
2840 }
2841 #[inline(always)]
2842 fn reduce_product(self) -> Self::Element {
2843 self.simd.reduce_product_u32x4(self)
2844 }
2845 #[inline(always)]
2846 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
2847 self.simd.max_u32x4(self, rhs.simd_into(self.simd))
2848 }
2849 #[inline(always)]
2850 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
2851 self.simd.min_u32x4(self, rhs.simd_into(self.simd))
2852 }
2853 #[inline(always)]
2854 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
2855 self.simd.max_u32x4(self, rhs.simd_into(self.simd))
2856 }
2857 #[inline(always)]
2858 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
2859 self.simd.min_u32x4(self, rhs.simd_into(self.simd))
2860 }
2861 #[inline(always)]
2862 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
2863 self.simd
2864 .clamp_u32x4(self, min.simd_into(self.simd), max.simd_into(self.simd))
2865 }
2866 #[inline(always)]
2867 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2868 self.simd.simd_eq_u32x4(self, rhs.simd_into(self.simd))
2869 }
2870 #[inline(always)]
2871 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2872 self.simd.simd_ne_u32x4(self, rhs.simd_into(self.simd))
2873 }
2874 #[inline(always)]
2875 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2876 self.simd.simd_lt_u32x4(self, rhs.simd_into(self.simd))
2877 }
2878 #[inline(always)]
2879 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2880 self.simd.simd_le_u32x4(self, rhs.simd_into(self.simd))
2881 }
2882 #[inline(always)]
2883 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2884 self.simd.simd_ge_u32x4(self, rhs.simd_into(self.simd))
2885 }
2886 #[inline(always)]
2887 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
2888 self.simd.simd_gt_u32x4(self, rhs.simd_into(self.simd))
2889 }
2890 #[inline(always)]
2891 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
2892 self.simd.zip_low_u32x4(self, rhs.simd_into(self.simd))
2893 }
2894 #[inline(always)]
2895 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
2896 self.simd.zip_high_u32x4(self, rhs.simd_into(self.simd))
2897 }
2898 #[inline(always)]
2899 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
2900 self.simd.unzip_low_u32x4(self, rhs.simd_into(self.simd))
2901 }
2902 #[inline(always)]
2903 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
2904 self.simd.unzip_high_u32x4(self, rhs.simd_into(self.simd))
2905 }
2906 #[inline(always)]
2907 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
2908 self.simd.interleave_u32x4(self, rhs.simd_into(self.simd))
2909 }
2910 #[inline(always)]
2911 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
2912 self.simd.deinterleave_u32x4(self, rhs.simd_into(self.simd))
2913 }
2914}
2915impl<S: Simd> crate::SimdInt<S> for u32x4<S> {
2916 #[inline(always)]
2917 fn count_ones(self) -> Self {
2918 self.simd.count_ones_u32x4(self)
2919 }
2920 #[inline(always)]
2921 fn count_zeros(self) -> Self {
2922 self.simd.count_zeros_u32x4(self)
2923 }
2924 #[inline(always)]
2925 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
2926 self.simd
2927 .saturating_add_u32x4(self, rhs.simd_into(self.simd))
2928 }
2929 #[inline(always)]
2930 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
2931 self.simd
2932 .saturating_sub_u32x4(self, rhs.simd_into(self.simd))
2933 }
2934}
2935impl<S: Simd> SimdCvtTruncate<f32x4<S>> for u32x4<S> {
2936 #[doc = "Convert each floating-point element to an unsigned 32-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results.\n\nOn x86 platforms below AVX-512, this operation will still be slower than converting to `i32`, because there is no native instruction for converting to `u32`.\nIf you know your values fit within range of an `i32`, you should convert to an `i32` and cast to your desired datatype afterwards."]
2937 #[inline(always)]
2938 fn truncate_from(x: f32x4<S>) -> Self {
2939 x.simd.cvt_u32_f32x4(x)
2940 }
2941 #[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."]
2942 #[inline(always)]
2943 fn truncate_from_precise(x: f32x4<S>) -> Self {
2944 x.simd.cvt_u32_precise_f32x4(x)
2945 }
2946}
2947impl<S: Simd> SimdWiden<S> for u32x4<S> {
2948 type Widened = u64x2<S>;
2949 #[inline(always)]
2950 fn widen(self) -> (Self::Widened, Self::Widened) {
2951 self.simd.widen_u32x4(self)
2952 }
2953}
2954impl<S: Simd> SimdIntWiden<S> for u32x4<S> {
2955 #[inline(always)]
2956 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
2957 self.simd.widening_mul_u32x4(self, rhs.simd_into(self.simd))
2958 }
2959 #[inline(always)]
2960 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
2961 self.simd.widening_add_u32x4(self, rhs.simd_into(self.simd))
2962 }
2963 #[inline(always)]
2964 fn pairwise_widening_add(self) -> Self::Widened {
2965 self.simd.pairwise_widening_add_u32x4(self)
2966 }
2967 #[inline(always)]
2968 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
2969 self.simd
2970 .pairwise_dot_product_u32x4(self, rhs.simd_into(self.simd))
2971 }
2972}
2973impl<S: Simd> SimdNarrow<S> for u32x4<S> {
2974 type Narrowed = u16x8<S>;
2975 #[inline(always)]
2976 fn narrow(self, high: Self) -> Self::Narrowed {
2977 self.simd.narrow_u32x4(self, high)
2978 }
2979 #[inline(always)]
2980 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
2981 self.simd.saturating_narrow_u32x4(self, high)
2982 }
2983 #[inline(always)]
2984 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
2985 self.simd.relaxed_narrow_u32x4(self, high)
2986 }
2987}
2988impl<S: Simd> crate::SimdCombine<S> for u32x4<S> {
2989 type Combined = u32x8<S>;
2990 #[inline(always)]
2991 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
2992 self.simd.combine_u32x4(self, rhs.simd_into(self.simd))
2993 }
2994}
2995impl<S: Simd> SimdInterleaved<S> for u32x4<S> {
2996 #[inline(always)]
2997 fn load_four_interleaved(simd: S, src: &[Self::Element]) -> [Self; 4] {
2998 let src: &[u32; 16] = src.try_into().unwrap();
2999 simd.load_four_interleaved_u32x4(src)
3000 }
3001 #[inline(always)]
3002 fn store_four_interleaved(vectors: [Self; 4], dest: &mut [Self::Element]) {
3003 let dest: &mut [u32; 16] = dest.try_into().unwrap();
3004 vectors[0].simd.store_four_interleaved_u32x4(vectors, dest);
3005 }
3006}
3007impl<S: Simd> ExtractToken for mask32x4<S> {
3008 type S = S;
3009 #[inline]
3010 fn token(&self) -> S {
3011 self.simd
3012 }
3013}
3014#[doc = "A SIMD mask of 4 logical lanes corresponding to 32-bit vector elements.\n\nThe storage representation of this type is intentionally opaque and may vary depending on the SIMD level.\n\nYou can construct this mask type using the [`Self::splat`], [`Self::from_bitmask`], [`Self::from_slice`], and [`Self::simd_from`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, mask32x4};\nfn construct_mask<S: Simd>(simd: S) {\n // From a single boolean value:\n let a = mask32x4::splat(simd, true);\n let b = mask32x4::simd_from(simd, true);\n\n // From signed integer mask lanes:\n let c = mask32x4::from_slice(simd, &[-1, 0, 0, 0]);\n let d = mask32x4::simd_from(simd, [-1, 0, 0, 0]);\n\n // From a compact bitmask (same mask as above, least significant bit maps to lane 0):\n let e = mask32x4::from_bitmask(simd, 0b0001);\n\n // By setting individual lanes:\n let mut f = mask32x4::splat(simd, false);\n f.set(0, true);\n}\n```"]
3015#[derive(Clone, Copy)]
3016pub struct mask32x4<S: Simd> {
3017 pub(crate) val: S::mask32x4,
3018 pub(crate) simd: S,
3019}
3020impl<S: Simd> Seal for mask32x4<S> {}
3021impl<S: Simd> SimdFrom<[i32; 4], S> for mask32x4<S> {
3022 #[inline(always)]
3023 fn simd_from(simd: S, val: [i32; 4]) -> Self {
3024 Self {
3025 val: <S as crate::arch_types::ArchTypes>::mask32x4_from_array(simd, val),
3026 simd,
3027 }
3028 }
3029}
3030impl<S: Simd> From<mask32x4<S>> for [i32; 4] {
3031 #[inline(always)]
3032 fn from(value: mask32x4<S>) -> Self {
3033 <S as crate::arch_types::ArchTypes>::mask32x4_to_array(value.simd, value.val)
3034 }
3035}
3036impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask32x4<S> {
3037 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3038 let lanes: [i32; 4] = (*self).into();
3039 crate::support::simd_debug_impl(f, "mask32x4", &self.simd, &lanes)
3040 }
3041}
3042impl<S: Simd> SimdFrom<bool, S> for mask32x4<S> {
3043 #[inline(always)]
3044 fn simd_from(simd: S, value: bool) -> Self {
3045 simd.splat_mask32x4(value)
3046 }
3047}
3048impl<S: Simd> Select<mask32x4<S>> for mask32x4<S> {
3049 #[inline(always)]
3050 fn select(self, if_true: mask32x4<S>, if_false: mask32x4<S>) -> mask32x4<S> {
3051 self.simd.select_mask32x4(self, if_true, if_false)
3052 }
3053}
3054impl<S: Simd> SimdMask<S> for mask32x4<S> {
3055 type Element = i32;
3056 type Ints = i32x4<S>;
3057 const LEN: usize = 4;
3058 #[inline(always)]
3059 fn splat(simd: S, val: bool) -> Self {
3060 simd.splat_mask32x4(val)
3061 }
3062 #[inline(always)]
3063 fn from_bitmask(simd: S, bits: u64) -> Self {
3064 simd.from_bitmask_mask32x4(bits)
3065 }
3066 #[inline(always)]
3067 fn to_bitmask(self) -> u64 {
3068 self.simd.to_bitmask_mask32x4(self)
3069 }
3070 #[inline(always)]
3071 fn from_vector(vector: Self::Ints) -> Self {
3072 vector.token().from_vector_mask32x4(vector)
3073 }
3074 #[inline(always)]
3075 fn to_vector(self) -> Self::Ints {
3076 self.simd.to_vector_mask32x4(self)
3077 }
3078 #[inline(always)]
3079 fn set(&mut self, index: usize, value: bool) {
3080 self.simd.set_mask32x4(self, index, value);
3081 }
3082 #[inline(always)]
3083 fn from_slice(simd: S, slice: &[i32]) -> Self {
3084 let slice: &[i32; 4] = slice.try_into().unwrap();
3085 Self::simd_from(simd, *slice)
3086 }
3087 #[inline(always)]
3088 fn store_slice(&self, slice: &mut [i32]) {
3089 let slice: &mut [i32; 4] = slice.try_into().unwrap();
3090 *slice = (*self).into();
3091 }
3092 #[inline(always)]
3093 fn rotate_elements_left<const OFFSET: usize>(self) -> Self {
3094 self.simd.rotate_elements_left_mask32x4::<OFFSET>(self)
3095 }
3096 #[inline(always)]
3097 fn rotate_elements_right<const OFFSET: usize>(self) -> Self {
3098 self.simd.rotate_elements_right_mask32x4::<OFFSET>(self)
3099 }
3100 #[inline(always)]
3101 fn reverse(self) -> Self {
3102 self.simd.reverse_mask32x4(self)
3103 }
3104 #[inline(always)]
3105 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self {
3106 self.simd.simd_eq_mask32x4(self, rhs.simd_into(self.simd))
3107 }
3108 #[inline(always)]
3109 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self {
3110 self.simd.simd_ne_mask32x4(self, rhs.simd_into(self.simd))
3111 }
3112 #[inline(always)]
3113 fn any_true(self) -> bool {
3114 self.simd.any_true_mask32x4(self)
3115 }
3116 #[inline(always)]
3117 fn all_true(self) -> bool {
3118 self.simd.all_true_mask32x4(self)
3119 }
3120 #[inline(always)]
3121 fn any_false(self) -> bool {
3122 self.simd.any_false_mask32x4(self)
3123 }
3124 #[inline(always)]
3125 fn all_false(self) -> bool {
3126 self.simd.all_false_mask32x4(self)
3127 }
3128}
3129impl<S: Simd> MaskWiden<S> for mask32x4<S> {
3130 type Widened = mask64x2<S>;
3131 #[inline(always)]
3132 fn widen(self) -> (Self::Widened, Self::Widened) {
3133 self.simd.widen_mask32x4(self)
3134 }
3135}
3136impl<S: Simd> MaskNarrow<S> for mask32x4<S> {
3137 type Narrowed = mask16x8<S>;
3138 #[inline(always)]
3139 fn narrow(self, high: Self) -> Self::Narrowed {
3140 self.simd.narrow_mask32x4(self, high)
3141 }
3142}
3143impl<S: Simd> ExtractToken for f64x2<S> {
3144 type S = S;
3145 #[inline]
3146 fn token(&self) -> S {
3147 self.simd
3148 }
3149}
3150#[doc = "A SIMD vector of 2 [`f64`] elements.\n\nThis type's memory layout is identical to that of [`[f64; 2]`](prim@array), except that it is aligned to 16 bytes.\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```"]
3151#[derive(Clone, Copy)]
3152#[repr(C, align(16))]
3153pub struct f64x2<S: Simd> {
3154 pub(crate) val: S::f64x2,
3155 pub simd: S,
3156}
3157impl<S: Simd> Seal for f64x2<S> {}
3158impl<S: Simd> SimdFrom<[f64; 2], S> for f64x2<S> {
3159 #[inline(always)]
3160 fn simd_from(simd: S, val: [f64; 2]) -> Self {
3161 Self {
3162 val: crate::transmute::checked_transmute_copy(&val),
3163 simd,
3164 }
3165 }
3166}
3167impl<S: Simd> From<f64x2<S>> for [f64; 2] {
3168 #[inline(always)]
3169 fn from(value: f64x2<S>) -> Self {
3170 crate::transmute::checked_transmute_copy(&value.val)
3171 }
3172}
3173impl<S: Simd> core::ops::Deref for f64x2<S> {
3174 type Target = [f64; 2];
3175 #[inline(always)]
3176 fn deref(&self) -> &Self::Target {
3177 crate::transmute::checked_cast_ref(&self.val)
3178 }
3179}
3180impl<S: Simd> core::ops::DerefMut for f64x2<S> {
3181 #[inline(always)]
3182 fn deref_mut(&mut self) -> &mut Self::Target {
3183 crate::transmute::checked_cast_mut(&mut self.val)
3184 }
3185}
3186impl<S: Simd + core::fmt::Debug> core::fmt::Debug for f64x2<S> {
3187 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3188 crate::support::simd_debug_impl(f, "f64x2", &self.simd, self.as_array())
3189 }
3190}
3191impl<S: Simd> SimdFrom<f64, S> for f64x2<S> {
3192 #[inline(always)]
3193 fn simd_from(simd: S, value: f64) -> Self {
3194 simd.splat_f64x2(value)
3195 }
3196}
3197impl<S: Simd> core::ops::Index<usize> for f64x2<S> {
3198 type Output = f64;
3199 #[inline(always)]
3200 fn index(&self, i: usize) -> &Self::Output {
3201 &self.as_array()[i]
3202 }
3203}
3204impl<S: Simd> core::ops::IndexMut<usize> for f64x2<S> {
3205 #[inline(always)]
3206 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
3207 &mut self.as_mut_array()[i]
3208 }
3209}
3210impl<S: Simd> Select<f64x2<S>> for mask64x2<S> {
3211 #[inline(always)]
3212 fn select(self, if_true: f64x2<S>, if_false: f64x2<S>) -> f64x2<S> {
3213 self.simd.select_f64x2(self, if_true, if_false)
3214 }
3215}
3216impl<S: Simd> Bytes for f64x2<S> {
3217 type Bytes = u8x16<S>;
3218 #[inline(always)]
3219 fn to_bytes(self) -> Self::Bytes {
3220 u8x16 {
3221 val: crate::transmute::checked_transmute_copy(&self.val),
3222 simd: self.simd,
3223 }
3224 }
3225 #[inline(always)]
3226 fn from_bytes(value: Self::Bytes) -> Self {
3227 Self {
3228 val: crate::transmute::checked_transmute_copy(&value.val),
3229 simd: value.simd,
3230 }
3231 }
3232}
3233impl<S: Simd> SimdBase<S> for f64x2<S> {
3234 type Element = f64;
3235 type ByteVector = u8x16<S>;
3236 const LEN: usize = 2;
3237 type Mask = mask64x2<S>;
3238 type Block = f64x2<S>;
3239 type Array = [f64; 2];
3240 #[inline(always)]
3241 fn as_slice(&self) -> &[f64] {
3242 self.as_array().as_slice()
3243 }
3244 #[inline(always)]
3245 fn as_mut_slice(&mut self) -> &mut [f64] {
3246 self.as_mut_array().as_mut_slice()
3247 }
3248 #[inline(always)]
3249 fn from_slice(simd: S, slice: &[f64]) -> Self {
3250 Self::load_array_ref(simd, slice.try_into().unwrap())
3251 }
3252 #[inline(always)]
3253 fn store_slice(&self, slice: &mut [f64]) {
3254 (*self).store_array(slice.try_into().unwrap());
3255 }
3256 #[inline(always)]
3257 fn splat(simd: S, val: f64) -> Self {
3258 simd.splat_f64x2(val)
3259 }
3260 #[inline(always)]
3261 fn block_splat(block: Self::Block) -> Self {
3262 block
3263 }
3264 #[inline(always)]
3265 fn from_fn(simd: S, mut f: impl FnMut(usize) -> f64) -> Self {
3266 Self::load_array(simd, [f(0usize), f(1usize)])
3267 }
3268 #[inline(always)]
3269 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
3270 self.simd
3271 .slide_f64x2::<SHIFT>(self, rhs.simd_into(self.simd))
3272 }
3273 #[inline(always)]
3274 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
3275 self.simd
3276 .slide_within_blocks_f64x2::<SHIFT>(self, rhs.simd_into(self.simd))
3277 }
3278 #[inline(always)]
3279 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
3280 self.simd
3281 .swizzle_dyn_within_blocks_f64x2(self, indices.simd_into(self.simd))
3282 }
3283 #[inline(always)]
3284 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
3285 self.simd
3286 .swizzle_dyn_f64x2(self, indices.simd_into(self.simd))
3287 }
3288 #[inline(always)]
3289 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
3290 self.simd
3291 .swizzle_dyn_precise_f64x2(self, indices.simd_into(self.simd))
3292 }
3293 #[inline(always)]
3294 fn abs(self) -> Self {
3295 self.simd.abs_f64x2(self)
3296 }
3297 #[inline(always)]
3298 fn reverse(self) -> Self {
3299 self.simd.reverse_f64x2(self)
3300 }
3301 #[inline(always)]
3302 fn concat_swizzle_dyn(
3303 self,
3304 rhs: impl SimdInto<Self, S>,
3305 indices: impl SimdInto<Self::Bytes, S>,
3306 ) -> Self {
3307 self.simd.concat_swizzle_dyn_f64x2(
3308 self,
3309 rhs.simd_into(self.simd),
3310 indices.simd_into(self.simd),
3311 )
3312 }
3313 #[inline(always)]
3314 fn concat_swizzle_dyn_precise(
3315 self,
3316 rhs: impl SimdInto<Self, S>,
3317 indices: impl SimdInto<Self::Bytes, S>,
3318 ) -> Self {
3319 self.simd.concat_swizzle_dyn_precise_f64x2(
3320 self,
3321 rhs.simd_into(self.simd),
3322 indices.simd_into(self.simd),
3323 )
3324 }
3325 #[inline(always)]
3326 fn compress(self, mask: Self::Mask) -> Self {
3327 self.simd.compress_f64x2(self, mask)
3328 }
3329 #[inline(always)]
3330 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
3331 self.simd
3332 .compress_merge_f64x2(self, mask, merge.simd_into(self.simd))
3333 }
3334 #[inline(always)]
3335 fn expand(self, mask: Self::Mask) -> Self {
3336 self.simd.expand_f64x2(self, mask)
3337 }
3338 #[inline(always)]
3339 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
3340 self.simd
3341 .expand_merge_f64x2(self, mask, merge.simd_into(self.simd))
3342 }
3343 #[inline(always)]
3344 fn reduce_max(self) -> Self::Element {
3345 self.simd.reduce_max_f64x2(self)
3346 }
3347 #[inline(always)]
3348 fn reduce_min(self) -> Self::Element {
3349 self.simd.reduce_min_f64x2(self)
3350 }
3351 #[inline(always)]
3352 fn reduce_max_precise(self) -> Self::Element {
3353 self.simd.reduce_max_precise_f64x2(self)
3354 }
3355 #[inline(always)]
3356 fn reduce_min_precise(self) -> Self::Element {
3357 self.simd.reduce_min_precise_f64x2(self)
3358 }
3359 #[inline(always)]
3360 fn reduce_sum(self) -> Self::Element {
3361 self.simd.reduce_sum_f64x2(self)
3362 }
3363 #[inline(always)]
3364 fn reduce_product(self) -> Self::Element {
3365 self.simd.reduce_product_f64x2(self)
3366 }
3367 #[inline(always)]
3368 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
3369 self.simd.max_f64x2(self, rhs.simd_into(self.simd))
3370 }
3371 #[inline(always)]
3372 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
3373 self.simd.min_f64x2(self, rhs.simd_into(self.simd))
3374 }
3375 #[inline(always)]
3376 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
3377 self.simd.max_precise_f64x2(self, rhs.simd_into(self.simd))
3378 }
3379 #[inline(always)]
3380 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
3381 self.simd.min_precise_f64x2(self, rhs.simd_into(self.simd))
3382 }
3383 #[inline(always)]
3384 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
3385 self.simd
3386 .clamp_f64x2(self, min.simd_into(self.simd), max.simd_into(self.simd))
3387 }
3388 #[inline(always)]
3389 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3390 self.simd.simd_eq_f64x2(self, rhs.simd_into(self.simd))
3391 }
3392 #[inline(always)]
3393 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3394 self.simd.simd_ne_f64x2(self, rhs.simd_into(self.simd))
3395 }
3396 #[inline(always)]
3397 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3398 self.simd.simd_lt_f64x2(self, rhs.simd_into(self.simd))
3399 }
3400 #[inline(always)]
3401 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3402 self.simd.simd_le_f64x2(self, rhs.simd_into(self.simd))
3403 }
3404 #[inline(always)]
3405 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3406 self.simd.simd_ge_f64x2(self, rhs.simd_into(self.simd))
3407 }
3408 #[inline(always)]
3409 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3410 self.simd.simd_gt_f64x2(self, rhs.simd_into(self.simd))
3411 }
3412 #[inline(always)]
3413 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
3414 self.simd.zip_low_f64x2(self, rhs.simd_into(self.simd))
3415 }
3416 #[inline(always)]
3417 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
3418 self.simd.zip_high_f64x2(self, rhs.simd_into(self.simd))
3419 }
3420 #[inline(always)]
3421 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
3422 self.simd.unzip_low_f64x2(self, rhs.simd_into(self.simd))
3423 }
3424 #[inline(always)]
3425 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
3426 self.simd.unzip_high_f64x2(self, rhs.simd_into(self.simd))
3427 }
3428 #[inline(always)]
3429 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
3430 self.simd.interleave_f64x2(self, rhs.simd_into(self.simd))
3431 }
3432 #[inline(always)]
3433 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
3434 self.simd.deinterleave_f64x2(self, rhs.simd_into(self.simd))
3435 }
3436}
3437impl<S: Simd> crate::SimdFloat<S> for f64x2<S> {
3438 type Bits = u64x2<S>;
3439 #[inline(always)]
3440 fn sqrt(self) -> Self {
3441 self.simd.sqrt_f64x2(self)
3442 }
3443 #[inline(always)]
3444 fn approximate_recip(self) -> Self {
3445 self.simd.approximate_recip_f64x2(self)
3446 }
3447 #[inline(always)]
3448 fn copysign(self, rhs: impl SimdInto<Self, S>) -> Self {
3449 self.simd.copysign_f64x2(self, rhs.simd_into(self.simd))
3450 }
3451 #[inline(always)]
3452 fn mul_add(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
3453 self.simd
3454 .mul_add_f64x2(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
3455 }
3456 #[inline(always)]
3457 fn mul_add_precise(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
3458 self.simd
3459 .mul_add_precise_f64x2(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
3460 }
3461 #[inline(always)]
3462 fn mul_sub(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
3463 self.simd
3464 .mul_sub_f64x2(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
3465 }
3466 #[inline(always)]
3467 fn mul_sub_precise(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
3468 self.simd
3469 .mul_sub_precise_f64x2(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
3470 }
3471 #[inline(always)]
3472 fn floor(self) -> Self {
3473 self.simd.floor_f64x2(self)
3474 }
3475 #[inline(always)]
3476 fn ceil(self) -> Self {
3477 self.simd.ceil_f64x2(self)
3478 }
3479 #[inline(always)]
3480 fn round_ties_even(self) -> Self {
3481 self.simd.round_ties_even_f64x2(self)
3482 }
3483 #[inline(always)]
3484 fn round(self) -> Self {
3485 self.simd.round_f64x2(self)
3486 }
3487 #[inline(always)]
3488 fn fract(self) -> Self {
3489 self.simd.fract_f64x2(self)
3490 }
3491 #[inline(always)]
3492 fn trunc(self) -> Self {
3493 self.simd.trunc_f64x2(self)
3494 }
3495 #[inline(always)]
3496 fn to_degrees(self) -> Self {
3497 self.simd.to_degrees_f64x2(self)
3498 }
3499 #[inline(always)]
3500 fn to_radians(self) -> Self {
3501 self.simd.to_radians_f64x2(self)
3502 }
3503 #[inline(always)]
3504 fn is_nan(self) -> Self::Mask {
3505 self.simd.is_nan_f64x2(self)
3506 }
3507 #[inline(always)]
3508 fn is_infinite(self) -> Self::Mask {
3509 self.simd.is_infinite_f64x2(self)
3510 }
3511 #[inline(always)]
3512 fn is_finite(self) -> Self::Mask {
3513 self.simd.is_finite_f64x2(self)
3514 }
3515 #[inline(always)]
3516 fn is_subnormal(self) -> Self::Mask {
3517 self.simd.is_subnormal_f64x2(self)
3518 }
3519 #[inline(always)]
3520 fn is_normal(self) -> Self::Mask {
3521 self.simd.is_normal_f64x2(self)
3522 }
3523 #[inline(always)]
3524 fn is_sign_positive(self) -> Self::Mask {
3525 self.simd.is_sign_positive_f64x2(self)
3526 }
3527 #[inline(always)]
3528 fn is_sign_negative(self) -> Self::Mask {
3529 self.simd.is_sign_negative_f64x2(self)
3530 }
3531}
3532impl<S: Simd> SimdCvtFloat<u64x2<S>> for f64x2<S> {
3533 #[doc = "Convert each unsigned 64-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
3534 #[inline(always)]
3535 fn float_from(x: u64x2<S>) -> Self {
3536 x.simd.cvt_f64_u64x2(x)
3537 }
3538}
3539impl<S: Simd> SimdCvtFloat<i64x2<S>> for f64x2<S> {
3540 #[doc = "Convert each signed 64-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
3541 #[inline(always)]
3542 fn float_from(x: i64x2<S>) -> Self {
3543 x.simd.cvt_f64_i64x2(x)
3544 }
3545}
3546impl<S: Simd> SimdNarrow<S> for f64x2<S> {
3547 type Narrowed = f32x4<S>;
3548 #[inline(always)]
3549 fn narrow(self, high: Self) -> Self::Narrowed {
3550 self.simd.narrow_f64x2(self, high)
3551 }
3552 #[inline(always)]
3553 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
3554 self.simd.saturating_narrow_f64x2(self, high)
3555 }
3556 #[inline(always)]
3557 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
3558 self.simd.relaxed_narrow_f64x2(self, high)
3559 }
3560}
3561impl<S: Simd> crate::SimdCombine<S> for f64x2<S> {
3562 type Combined = f64x4<S>;
3563 #[inline(always)]
3564 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
3565 self.simd.combine_f64x2(self, rhs.simd_into(self.simd))
3566 }
3567}
3568impl<S: Simd> SimdInterleaved<S> for f64x2<S> {
3569 #[inline(always)]
3570 fn load_four_interleaved(simd: S, src: &[Self::Element]) -> [Self; 4] {
3571 let src: &[f64; 8] = src.try_into().unwrap();
3572 simd.load_four_interleaved_f64x2(src)
3573 }
3574 #[inline(always)]
3575 fn store_four_interleaved(vectors: [Self; 4], dest: &mut [Self::Element]) {
3576 let dest: &mut [f64; 8] = dest.try_into().unwrap();
3577 vectors[0].simd.store_four_interleaved_f64x2(vectors, dest);
3578 }
3579}
3580impl<S: Simd> ExtractToken for i64x2<S> {
3581 type S = S;
3582 #[inline]
3583 fn token(&self) -> S {
3584 self.simd
3585 }
3586}
3587#[doc = "A SIMD vector of 2 [`i64`] elements.\n\nThis type's memory layout is identical to that of [`[i64; 2]`](prim@array), except that it is aligned to 16 bytes.\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::*, i64x2};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = i64x2::splat(simd, 1);\n let b = i64x2::simd_from(simd, 1);\n\n // From a slice:\n let c = i64x2::from_slice(simd, &[1, 2]);\n\n // From an array:\n let d = i64x2::simd_from(simd, [1, 2]);\n\n // From an element-wise function:\n let e = i64x2::from_fn(simd, |i| i as i64);\n}\n```"]
3588#[derive(Clone, Copy)]
3589#[repr(C, align(16))]
3590pub struct i64x2<S: Simd> {
3591 pub(crate) val: S::i64x2,
3592 pub simd: S,
3593}
3594impl<S: Simd> Seal for i64x2<S> {}
3595impl<S: Simd> SimdFrom<[i64; 2], S> for i64x2<S> {
3596 #[inline(always)]
3597 fn simd_from(simd: S, val: [i64; 2]) -> Self {
3598 Self {
3599 val: crate::transmute::checked_transmute_copy(&val),
3600 simd,
3601 }
3602 }
3603}
3604impl<S: Simd> From<i64x2<S>> for [i64; 2] {
3605 #[inline(always)]
3606 fn from(value: i64x2<S>) -> Self {
3607 crate::transmute::checked_transmute_copy(&value.val)
3608 }
3609}
3610impl<S: Simd> core::ops::Deref for i64x2<S> {
3611 type Target = [i64; 2];
3612 #[inline(always)]
3613 fn deref(&self) -> &Self::Target {
3614 crate::transmute::checked_cast_ref(&self.val)
3615 }
3616}
3617impl<S: Simd> core::ops::DerefMut for i64x2<S> {
3618 #[inline(always)]
3619 fn deref_mut(&mut self) -> &mut Self::Target {
3620 crate::transmute::checked_cast_mut(&mut self.val)
3621 }
3622}
3623impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i64x2<S> {
3624 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3625 crate::support::simd_debug_impl(f, "i64x2", &self.simd, self.as_array())
3626 }
3627}
3628impl<S: Simd> SimdFrom<i64, S> for i64x2<S> {
3629 #[inline(always)]
3630 fn simd_from(simd: S, value: i64) -> Self {
3631 simd.splat_i64x2(value)
3632 }
3633}
3634impl<S: Simd> core::ops::Index<usize> for i64x2<S> {
3635 type Output = i64;
3636 #[inline(always)]
3637 fn index(&self, i: usize) -> &Self::Output {
3638 &self.as_array()[i]
3639 }
3640}
3641impl<S: Simd> core::ops::IndexMut<usize> for i64x2<S> {
3642 #[inline(always)]
3643 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
3644 &mut self.as_mut_array()[i]
3645 }
3646}
3647impl<S: Simd> Select<i64x2<S>> for mask64x2<S> {
3648 #[inline(always)]
3649 fn select(self, if_true: i64x2<S>, if_false: i64x2<S>) -> i64x2<S> {
3650 self.simd.select_i64x2(self, if_true, if_false)
3651 }
3652}
3653impl<S: Simd> Bytes for i64x2<S> {
3654 type Bytes = u8x16<S>;
3655 #[inline(always)]
3656 fn to_bytes(self) -> Self::Bytes {
3657 u8x16 {
3658 val: crate::transmute::checked_transmute_copy(&self.val),
3659 simd: self.simd,
3660 }
3661 }
3662 #[inline(always)]
3663 fn from_bytes(value: Self::Bytes) -> Self {
3664 Self {
3665 val: crate::transmute::checked_transmute_copy(&value.val),
3666 simd: value.simd,
3667 }
3668 }
3669}
3670impl<S: Simd> SimdBase<S> for i64x2<S> {
3671 type Element = i64;
3672 type ByteVector = u8x16<S>;
3673 const LEN: usize = 2;
3674 type Mask = mask64x2<S>;
3675 type Block = i64x2<S>;
3676 type Array = [i64; 2];
3677 #[inline(always)]
3678 fn as_slice(&self) -> &[i64] {
3679 self.as_array().as_slice()
3680 }
3681 #[inline(always)]
3682 fn as_mut_slice(&mut self) -> &mut [i64] {
3683 self.as_mut_array().as_mut_slice()
3684 }
3685 #[inline(always)]
3686 fn from_slice(simd: S, slice: &[i64]) -> Self {
3687 Self::load_array_ref(simd, slice.try_into().unwrap())
3688 }
3689 #[inline(always)]
3690 fn store_slice(&self, slice: &mut [i64]) {
3691 (*self).store_array(slice.try_into().unwrap());
3692 }
3693 #[inline(always)]
3694 fn splat(simd: S, val: i64) -> Self {
3695 simd.splat_i64x2(val)
3696 }
3697 #[inline(always)]
3698 fn block_splat(block: Self::Block) -> Self {
3699 block
3700 }
3701 #[inline(always)]
3702 fn from_fn(simd: S, mut f: impl FnMut(usize) -> i64) -> Self {
3703 Self::load_array(simd, [f(0usize), f(1usize)])
3704 }
3705 #[inline(always)]
3706 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
3707 self.simd
3708 .slide_i64x2::<SHIFT>(self, rhs.simd_into(self.simd))
3709 }
3710 #[inline(always)]
3711 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
3712 self.simd
3713 .slide_within_blocks_i64x2::<SHIFT>(self, rhs.simd_into(self.simd))
3714 }
3715 #[inline(always)]
3716 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
3717 self.simd
3718 .swizzle_dyn_within_blocks_i64x2(self, indices.simd_into(self.simd))
3719 }
3720 #[inline(always)]
3721 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
3722 self.simd
3723 .swizzle_dyn_i64x2(self, indices.simd_into(self.simd))
3724 }
3725 #[inline(always)]
3726 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
3727 self.simd
3728 .swizzle_dyn_precise_i64x2(self, indices.simd_into(self.simd))
3729 }
3730 #[inline(always)]
3731 fn abs(self) -> Self {
3732 self.simd.abs_i64x2(self)
3733 }
3734 #[inline(always)]
3735 fn reverse(self) -> Self {
3736 self.simd.reverse_i64x2(self)
3737 }
3738 #[inline(always)]
3739 fn concat_swizzle_dyn(
3740 self,
3741 rhs: impl SimdInto<Self, S>,
3742 indices: impl SimdInto<Self::Bytes, S>,
3743 ) -> Self {
3744 self.simd.concat_swizzle_dyn_i64x2(
3745 self,
3746 rhs.simd_into(self.simd),
3747 indices.simd_into(self.simd),
3748 )
3749 }
3750 #[inline(always)]
3751 fn concat_swizzle_dyn_precise(
3752 self,
3753 rhs: impl SimdInto<Self, S>,
3754 indices: impl SimdInto<Self::Bytes, S>,
3755 ) -> Self {
3756 self.simd.concat_swizzle_dyn_precise_i64x2(
3757 self,
3758 rhs.simd_into(self.simd),
3759 indices.simd_into(self.simd),
3760 )
3761 }
3762 #[inline(always)]
3763 fn compress(self, mask: Self::Mask) -> Self {
3764 self.simd.compress_i64x2(self, mask)
3765 }
3766 #[inline(always)]
3767 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
3768 self.simd
3769 .compress_merge_i64x2(self, mask, merge.simd_into(self.simd))
3770 }
3771 #[inline(always)]
3772 fn expand(self, mask: Self::Mask) -> Self {
3773 self.simd.expand_i64x2(self, mask)
3774 }
3775 #[inline(always)]
3776 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
3777 self.simd
3778 .expand_merge_i64x2(self, mask, merge.simd_into(self.simd))
3779 }
3780 #[inline(always)]
3781 fn reduce_max(self) -> Self::Element {
3782 self.simd.reduce_max_i64x2(self)
3783 }
3784 #[inline(always)]
3785 fn reduce_min(self) -> Self::Element {
3786 self.simd.reduce_min_i64x2(self)
3787 }
3788 #[inline(always)]
3789 fn reduce_max_precise(self) -> Self::Element {
3790 self.simd.reduce_max_i64x2(self)
3791 }
3792 #[inline(always)]
3793 fn reduce_min_precise(self) -> Self::Element {
3794 self.simd.reduce_min_i64x2(self)
3795 }
3796 #[inline(always)]
3797 fn reduce_sum(self) -> Self::Element {
3798 self.simd.reduce_sum_i64x2(self)
3799 }
3800 #[inline(always)]
3801 fn reduce_product(self) -> Self::Element {
3802 self.simd.reduce_product_i64x2(self)
3803 }
3804 #[inline(always)]
3805 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
3806 self.simd.max_i64x2(self, rhs.simd_into(self.simd))
3807 }
3808 #[inline(always)]
3809 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
3810 self.simd.min_i64x2(self, rhs.simd_into(self.simd))
3811 }
3812 #[inline(always)]
3813 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
3814 self.simd.max_i64x2(self, rhs.simd_into(self.simd))
3815 }
3816 #[inline(always)]
3817 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
3818 self.simd.min_i64x2(self, rhs.simd_into(self.simd))
3819 }
3820 #[inline(always)]
3821 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
3822 self.simd
3823 .clamp_i64x2(self, min.simd_into(self.simd), max.simd_into(self.simd))
3824 }
3825 #[inline(always)]
3826 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3827 self.simd.simd_eq_i64x2(self, rhs.simd_into(self.simd))
3828 }
3829 #[inline(always)]
3830 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3831 self.simd.simd_ne_i64x2(self, rhs.simd_into(self.simd))
3832 }
3833 #[inline(always)]
3834 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3835 self.simd.simd_lt_i64x2(self, rhs.simd_into(self.simd))
3836 }
3837 #[inline(always)]
3838 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3839 self.simd.simd_le_i64x2(self, rhs.simd_into(self.simd))
3840 }
3841 #[inline(always)]
3842 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3843 self.simd.simd_ge_i64x2(self, rhs.simd_into(self.simd))
3844 }
3845 #[inline(always)]
3846 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
3847 self.simd.simd_gt_i64x2(self, rhs.simd_into(self.simd))
3848 }
3849 #[inline(always)]
3850 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
3851 self.simd.zip_low_i64x2(self, rhs.simd_into(self.simd))
3852 }
3853 #[inline(always)]
3854 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
3855 self.simd.zip_high_i64x2(self, rhs.simd_into(self.simd))
3856 }
3857 #[inline(always)]
3858 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
3859 self.simd.unzip_low_i64x2(self, rhs.simd_into(self.simd))
3860 }
3861 #[inline(always)]
3862 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
3863 self.simd.unzip_high_i64x2(self, rhs.simd_into(self.simd))
3864 }
3865 #[inline(always)]
3866 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
3867 self.simd.interleave_i64x2(self, rhs.simd_into(self.simd))
3868 }
3869 #[inline(always)]
3870 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
3871 self.simd.deinterleave_i64x2(self, rhs.simd_into(self.simd))
3872 }
3873}
3874impl<S: Simd> crate::SimdInt<S> for i64x2<S> {
3875 #[inline(always)]
3876 fn count_ones(self) -> Self {
3877 self.simd.count_ones_i64x2(self)
3878 }
3879 #[inline(always)]
3880 fn count_zeros(self) -> Self {
3881 self.simd.count_zeros_i64x2(self)
3882 }
3883 #[inline(always)]
3884 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
3885 self.simd
3886 .saturating_add_i64x2(self, rhs.simd_into(self.simd))
3887 }
3888 #[inline(always)]
3889 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
3890 self.simd
3891 .saturating_sub_i64x2(self, rhs.simd_into(self.simd))
3892 }
3893}
3894impl<S: Simd> SimdCvtTruncate<f64x2<S>> for i64x2<S> {
3895 #[doc = "Convert each floating-point element to a signed 64-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
3896 #[inline(always)]
3897 fn truncate_from(x: f64x2<S>) -> Self {
3898 x.simd.cvt_i64_f64x2(x)
3899 }
3900 #[doc = "Convert each floating-point element to a signed 64-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
3901 #[inline(always)]
3902 fn truncate_from_precise(x: f64x2<S>) -> Self {
3903 x.simd.cvt_i64_precise_f64x2(x)
3904 }
3905}
3906impl<S: Simd> SimdNarrow<S> for i64x2<S> {
3907 type Narrowed = i32x4<S>;
3908 #[inline(always)]
3909 fn narrow(self, high: Self) -> Self::Narrowed {
3910 self.simd.narrow_i64x2(self, high)
3911 }
3912 #[inline(always)]
3913 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
3914 self.simd.saturating_narrow_i64x2(self, high)
3915 }
3916 #[inline(always)]
3917 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
3918 self.simd.relaxed_narrow_i64x2(self, high)
3919 }
3920}
3921impl<S: Simd> crate::SimdCombine<S> for i64x2<S> {
3922 type Combined = i64x4<S>;
3923 #[inline(always)]
3924 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
3925 self.simd.combine_i64x2(self, rhs.simd_into(self.simd))
3926 }
3927}
3928impl<S: Simd> SimdInterleaved<S> for i64x2<S> {
3929 #[inline(always)]
3930 fn load_four_interleaved(simd: S, src: &[Self::Element]) -> [Self; 4] {
3931 let src: &[i64; 8] = src.try_into().unwrap();
3932 simd.load_four_interleaved_i64x2(src)
3933 }
3934 #[inline(always)]
3935 fn store_four_interleaved(vectors: [Self; 4], dest: &mut [Self::Element]) {
3936 let dest: &mut [i64; 8] = dest.try_into().unwrap();
3937 vectors[0].simd.store_four_interleaved_i64x2(vectors, dest);
3938 }
3939}
3940impl<S: Simd> ExtractToken for u64x2<S> {
3941 type S = S;
3942 #[inline]
3943 fn token(&self) -> S {
3944 self.simd
3945 }
3946}
3947#[doc = "A SIMD vector of 2 [`u64`] elements.\n\nThis type's memory layout is identical to that of [`[u64; 2]`](prim@array), except that it is aligned to 16 bytes.\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::*, u64x2};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = u64x2::splat(simd, 1);\n let b = u64x2::simd_from(simd, 1);\n\n // From a slice:\n let c = u64x2::from_slice(simd, &[1, 2]);\n\n // From an array:\n let d = u64x2::simd_from(simd, [1, 2]);\n\n // From an element-wise function:\n let e = u64x2::from_fn(simd, |i| i as u64);\n}\n```"]
3948#[derive(Clone, Copy)]
3949#[repr(C, align(16))]
3950pub struct u64x2<S: Simd> {
3951 pub(crate) val: S::u64x2,
3952 pub simd: S,
3953}
3954impl<S: Simd> Seal for u64x2<S> {}
3955impl<S: Simd> SimdFrom<[u64; 2], S> for u64x2<S> {
3956 #[inline(always)]
3957 fn simd_from(simd: S, val: [u64; 2]) -> Self {
3958 Self {
3959 val: crate::transmute::checked_transmute_copy(&val),
3960 simd,
3961 }
3962 }
3963}
3964impl<S: Simd> From<u64x2<S>> for [u64; 2] {
3965 #[inline(always)]
3966 fn from(value: u64x2<S>) -> Self {
3967 crate::transmute::checked_transmute_copy(&value.val)
3968 }
3969}
3970impl<S: Simd> core::ops::Deref for u64x2<S> {
3971 type Target = [u64; 2];
3972 #[inline(always)]
3973 fn deref(&self) -> &Self::Target {
3974 crate::transmute::checked_cast_ref(&self.val)
3975 }
3976}
3977impl<S: Simd> core::ops::DerefMut for u64x2<S> {
3978 #[inline(always)]
3979 fn deref_mut(&mut self) -> &mut Self::Target {
3980 crate::transmute::checked_cast_mut(&mut self.val)
3981 }
3982}
3983impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u64x2<S> {
3984 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
3985 crate::support::simd_debug_impl(f, "u64x2", &self.simd, self.as_array())
3986 }
3987}
3988impl<S: Simd> SimdFrom<u64, S> for u64x2<S> {
3989 #[inline(always)]
3990 fn simd_from(simd: S, value: u64) -> Self {
3991 simd.splat_u64x2(value)
3992 }
3993}
3994impl<S: Simd> core::ops::Index<usize> for u64x2<S> {
3995 type Output = u64;
3996 #[inline(always)]
3997 fn index(&self, i: usize) -> &Self::Output {
3998 &self.as_array()[i]
3999 }
4000}
4001impl<S: Simd> core::ops::IndexMut<usize> for u64x2<S> {
4002 #[inline(always)]
4003 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
4004 &mut self.as_mut_array()[i]
4005 }
4006}
4007impl<S: Simd> Select<u64x2<S>> for mask64x2<S> {
4008 #[inline(always)]
4009 fn select(self, if_true: u64x2<S>, if_false: u64x2<S>) -> u64x2<S> {
4010 self.simd.select_u64x2(self, if_true, if_false)
4011 }
4012}
4013impl<S: Simd> Bytes for u64x2<S> {
4014 type Bytes = u8x16<S>;
4015 #[inline(always)]
4016 fn to_bytes(self) -> Self::Bytes {
4017 u8x16 {
4018 val: crate::transmute::checked_transmute_copy(&self.val),
4019 simd: self.simd,
4020 }
4021 }
4022 #[inline(always)]
4023 fn from_bytes(value: Self::Bytes) -> Self {
4024 Self {
4025 val: crate::transmute::checked_transmute_copy(&value.val),
4026 simd: value.simd,
4027 }
4028 }
4029}
4030impl<S: Simd> SimdBase<S> for u64x2<S> {
4031 type Element = u64;
4032 type ByteVector = u8x16<S>;
4033 const LEN: usize = 2;
4034 type Mask = mask64x2<S>;
4035 type Block = u64x2<S>;
4036 type Array = [u64; 2];
4037 #[inline(always)]
4038 fn as_slice(&self) -> &[u64] {
4039 self.as_array().as_slice()
4040 }
4041 #[inline(always)]
4042 fn as_mut_slice(&mut self) -> &mut [u64] {
4043 self.as_mut_array().as_mut_slice()
4044 }
4045 #[inline(always)]
4046 fn from_slice(simd: S, slice: &[u64]) -> Self {
4047 Self::load_array_ref(simd, slice.try_into().unwrap())
4048 }
4049 #[inline(always)]
4050 fn store_slice(&self, slice: &mut [u64]) {
4051 (*self).store_array(slice.try_into().unwrap());
4052 }
4053 #[inline(always)]
4054 fn splat(simd: S, val: u64) -> Self {
4055 simd.splat_u64x2(val)
4056 }
4057 #[inline(always)]
4058 fn block_splat(block: Self::Block) -> Self {
4059 block
4060 }
4061 #[inline(always)]
4062 fn from_fn(simd: S, mut f: impl FnMut(usize) -> u64) -> Self {
4063 Self::load_array(simd, [f(0usize), f(1usize)])
4064 }
4065 #[inline(always)]
4066 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
4067 self.simd
4068 .slide_u64x2::<SHIFT>(self, rhs.simd_into(self.simd))
4069 }
4070 #[inline(always)]
4071 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
4072 self.simd
4073 .slide_within_blocks_u64x2::<SHIFT>(self, rhs.simd_into(self.simd))
4074 }
4075 #[inline(always)]
4076 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
4077 self.simd
4078 .swizzle_dyn_within_blocks_u64x2(self, indices.simd_into(self.simd))
4079 }
4080 #[inline(always)]
4081 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
4082 self.simd
4083 .swizzle_dyn_u64x2(self, indices.simd_into(self.simd))
4084 }
4085 #[inline(always)]
4086 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
4087 self.simd
4088 .swizzle_dyn_precise_u64x2(self, indices.simd_into(self.simd))
4089 }
4090 #[inline(always)]
4091 fn abs(self) -> Self {
4092 self.simd.abs_u64x2(self)
4093 }
4094 #[inline(always)]
4095 fn reverse(self) -> Self {
4096 self.simd.reverse_u64x2(self)
4097 }
4098 #[inline(always)]
4099 fn concat_swizzle_dyn(
4100 self,
4101 rhs: impl SimdInto<Self, S>,
4102 indices: impl SimdInto<Self::Bytes, S>,
4103 ) -> Self {
4104 self.simd.concat_swizzle_dyn_u64x2(
4105 self,
4106 rhs.simd_into(self.simd),
4107 indices.simd_into(self.simd),
4108 )
4109 }
4110 #[inline(always)]
4111 fn concat_swizzle_dyn_precise(
4112 self,
4113 rhs: impl SimdInto<Self, S>,
4114 indices: impl SimdInto<Self::Bytes, S>,
4115 ) -> Self {
4116 self.simd.concat_swizzle_dyn_precise_u64x2(
4117 self,
4118 rhs.simd_into(self.simd),
4119 indices.simd_into(self.simd),
4120 )
4121 }
4122 #[inline(always)]
4123 fn compress(self, mask: Self::Mask) -> Self {
4124 self.simd.compress_u64x2(self, mask)
4125 }
4126 #[inline(always)]
4127 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
4128 self.simd
4129 .compress_merge_u64x2(self, mask, merge.simd_into(self.simd))
4130 }
4131 #[inline(always)]
4132 fn expand(self, mask: Self::Mask) -> Self {
4133 self.simd.expand_u64x2(self, mask)
4134 }
4135 #[inline(always)]
4136 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
4137 self.simd
4138 .expand_merge_u64x2(self, mask, merge.simd_into(self.simd))
4139 }
4140 #[inline(always)]
4141 fn reduce_max(self) -> Self::Element {
4142 self.simd.reduce_max_u64x2(self)
4143 }
4144 #[inline(always)]
4145 fn reduce_min(self) -> Self::Element {
4146 self.simd.reduce_min_u64x2(self)
4147 }
4148 #[inline(always)]
4149 fn reduce_max_precise(self) -> Self::Element {
4150 self.simd.reduce_max_u64x2(self)
4151 }
4152 #[inline(always)]
4153 fn reduce_min_precise(self) -> Self::Element {
4154 self.simd.reduce_min_u64x2(self)
4155 }
4156 #[inline(always)]
4157 fn reduce_sum(self) -> Self::Element {
4158 self.simd.reduce_sum_u64x2(self)
4159 }
4160 #[inline(always)]
4161 fn reduce_product(self) -> Self::Element {
4162 self.simd.reduce_product_u64x2(self)
4163 }
4164 #[inline(always)]
4165 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
4166 self.simd.max_u64x2(self, rhs.simd_into(self.simd))
4167 }
4168 #[inline(always)]
4169 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
4170 self.simd.min_u64x2(self, rhs.simd_into(self.simd))
4171 }
4172 #[inline(always)]
4173 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
4174 self.simd.max_u64x2(self, rhs.simd_into(self.simd))
4175 }
4176 #[inline(always)]
4177 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
4178 self.simd.min_u64x2(self, rhs.simd_into(self.simd))
4179 }
4180 #[inline(always)]
4181 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
4182 self.simd
4183 .clamp_u64x2(self, min.simd_into(self.simd), max.simd_into(self.simd))
4184 }
4185 #[inline(always)]
4186 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4187 self.simd.simd_eq_u64x2(self, rhs.simd_into(self.simd))
4188 }
4189 #[inline(always)]
4190 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4191 self.simd.simd_ne_u64x2(self, rhs.simd_into(self.simd))
4192 }
4193 #[inline(always)]
4194 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4195 self.simd.simd_lt_u64x2(self, rhs.simd_into(self.simd))
4196 }
4197 #[inline(always)]
4198 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4199 self.simd.simd_le_u64x2(self, rhs.simd_into(self.simd))
4200 }
4201 #[inline(always)]
4202 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4203 self.simd.simd_ge_u64x2(self, rhs.simd_into(self.simd))
4204 }
4205 #[inline(always)]
4206 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4207 self.simd.simd_gt_u64x2(self, rhs.simd_into(self.simd))
4208 }
4209 #[inline(always)]
4210 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
4211 self.simd.zip_low_u64x2(self, rhs.simd_into(self.simd))
4212 }
4213 #[inline(always)]
4214 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
4215 self.simd.zip_high_u64x2(self, rhs.simd_into(self.simd))
4216 }
4217 #[inline(always)]
4218 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
4219 self.simd.unzip_low_u64x2(self, rhs.simd_into(self.simd))
4220 }
4221 #[inline(always)]
4222 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
4223 self.simd.unzip_high_u64x2(self, rhs.simd_into(self.simd))
4224 }
4225 #[inline(always)]
4226 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
4227 self.simd.interleave_u64x2(self, rhs.simd_into(self.simd))
4228 }
4229 #[inline(always)]
4230 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
4231 self.simd.deinterleave_u64x2(self, rhs.simd_into(self.simd))
4232 }
4233}
4234impl<S: Simd> crate::SimdInt<S> for u64x2<S> {
4235 #[inline(always)]
4236 fn count_ones(self) -> Self {
4237 self.simd.count_ones_u64x2(self)
4238 }
4239 #[inline(always)]
4240 fn count_zeros(self) -> Self {
4241 self.simd.count_zeros_u64x2(self)
4242 }
4243 #[inline(always)]
4244 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
4245 self.simd
4246 .saturating_add_u64x2(self, rhs.simd_into(self.simd))
4247 }
4248 #[inline(always)]
4249 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
4250 self.simd
4251 .saturating_sub_u64x2(self, rhs.simd_into(self.simd))
4252 }
4253}
4254impl<S: Simd> SimdCvtTruncate<f64x2<S>> for u64x2<S> {
4255 #[doc = "Convert each floating-point element to an unsigned 64-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
4256 #[inline(always)]
4257 fn truncate_from(x: f64x2<S>) -> Self {
4258 x.simd.cvt_u64_f64x2(x)
4259 }
4260 #[doc = "Convert each floating-point element to an unsigned 64-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
4261 #[inline(always)]
4262 fn truncate_from_precise(x: f64x2<S>) -> Self {
4263 x.simd.cvt_u64_precise_f64x2(x)
4264 }
4265}
4266impl<S: Simd> SimdNarrow<S> for u64x2<S> {
4267 type Narrowed = u32x4<S>;
4268 #[inline(always)]
4269 fn narrow(self, high: Self) -> Self::Narrowed {
4270 self.simd.narrow_u64x2(self, high)
4271 }
4272 #[inline(always)]
4273 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
4274 self.simd.saturating_narrow_u64x2(self, high)
4275 }
4276 #[inline(always)]
4277 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
4278 self.simd.relaxed_narrow_u64x2(self, high)
4279 }
4280}
4281impl<S: Simd> crate::SimdCombine<S> for u64x2<S> {
4282 type Combined = u64x4<S>;
4283 #[inline(always)]
4284 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
4285 self.simd.combine_u64x2(self, rhs.simd_into(self.simd))
4286 }
4287}
4288impl<S: Simd> SimdInterleaved<S> for u64x2<S> {
4289 #[inline(always)]
4290 fn load_four_interleaved(simd: S, src: &[Self::Element]) -> [Self; 4] {
4291 let src: &[u64; 8] = src.try_into().unwrap();
4292 simd.load_four_interleaved_u64x2(src)
4293 }
4294 #[inline(always)]
4295 fn store_four_interleaved(vectors: [Self; 4], dest: &mut [Self::Element]) {
4296 let dest: &mut [u64; 8] = dest.try_into().unwrap();
4297 vectors[0].simd.store_four_interleaved_u64x2(vectors, dest);
4298 }
4299}
4300impl<S: Simd> ExtractToken for mask64x2<S> {
4301 type S = S;
4302 #[inline]
4303 fn token(&self) -> S {
4304 self.simd
4305 }
4306}
4307#[doc = "A SIMD mask of 2 logical lanes corresponding to 64-bit vector elements.\n\nThe storage representation of this type is intentionally opaque and may vary depending on the SIMD level.\n\nYou can construct this mask type using the [`Self::splat`], [`Self::from_bitmask`], [`Self::from_slice`], and [`Self::simd_from`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, mask64x2};\nfn construct_mask<S: Simd>(simd: S) {\n // From a single boolean value:\n let a = mask64x2::splat(simd, true);\n let b = mask64x2::simd_from(simd, true);\n\n // From signed integer mask lanes:\n let c = mask64x2::from_slice(simd, &[-1, 0]);\n let d = mask64x2::simd_from(simd, [-1, 0]);\n\n // From a compact bitmask (same mask as above, least significant bit maps to lane 0):\n let e = mask64x2::from_bitmask(simd, 0b0001);\n\n // By setting individual lanes:\n let mut f = mask64x2::splat(simd, false);\n f.set(0, true);\n}\n```"]
4308#[derive(Clone, Copy)]
4309pub struct mask64x2<S: Simd> {
4310 pub(crate) val: S::mask64x2,
4311 pub(crate) simd: S,
4312}
4313impl<S: Simd> Seal for mask64x2<S> {}
4314impl<S: Simd> SimdFrom<[i64; 2], S> for mask64x2<S> {
4315 #[inline(always)]
4316 fn simd_from(simd: S, val: [i64; 2]) -> Self {
4317 Self {
4318 val: <S as crate::arch_types::ArchTypes>::mask64x2_from_array(simd, val),
4319 simd,
4320 }
4321 }
4322}
4323impl<S: Simd> From<mask64x2<S>> for [i64; 2] {
4324 #[inline(always)]
4325 fn from(value: mask64x2<S>) -> Self {
4326 <S as crate::arch_types::ArchTypes>::mask64x2_to_array(value.simd, value.val)
4327 }
4328}
4329impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask64x2<S> {
4330 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4331 let lanes: [i64; 2] = (*self).into();
4332 crate::support::simd_debug_impl(f, "mask64x2", &self.simd, &lanes)
4333 }
4334}
4335impl<S: Simd> SimdFrom<bool, S> for mask64x2<S> {
4336 #[inline(always)]
4337 fn simd_from(simd: S, value: bool) -> Self {
4338 simd.splat_mask64x2(value)
4339 }
4340}
4341impl<S: Simd> Select<mask64x2<S>> for mask64x2<S> {
4342 #[inline(always)]
4343 fn select(self, if_true: mask64x2<S>, if_false: mask64x2<S>) -> mask64x2<S> {
4344 self.simd.select_mask64x2(self, if_true, if_false)
4345 }
4346}
4347impl<S: Simd> SimdMask<S> for mask64x2<S> {
4348 type Element = i64;
4349 type Ints = i64x2<S>;
4350 const LEN: usize = 2;
4351 #[inline(always)]
4352 fn splat(simd: S, val: bool) -> Self {
4353 simd.splat_mask64x2(val)
4354 }
4355 #[inline(always)]
4356 fn from_bitmask(simd: S, bits: u64) -> Self {
4357 simd.from_bitmask_mask64x2(bits)
4358 }
4359 #[inline(always)]
4360 fn to_bitmask(self) -> u64 {
4361 self.simd.to_bitmask_mask64x2(self)
4362 }
4363 #[inline(always)]
4364 fn from_vector(vector: Self::Ints) -> Self {
4365 vector.token().from_vector_mask64x2(vector)
4366 }
4367 #[inline(always)]
4368 fn to_vector(self) -> Self::Ints {
4369 self.simd.to_vector_mask64x2(self)
4370 }
4371 #[inline(always)]
4372 fn set(&mut self, index: usize, value: bool) {
4373 self.simd.set_mask64x2(self, index, value);
4374 }
4375 #[inline(always)]
4376 fn from_slice(simd: S, slice: &[i64]) -> Self {
4377 let slice: &[i64; 2] = slice.try_into().unwrap();
4378 Self::simd_from(simd, *slice)
4379 }
4380 #[inline(always)]
4381 fn store_slice(&self, slice: &mut [i64]) {
4382 let slice: &mut [i64; 2] = slice.try_into().unwrap();
4383 *slice = (*self).into();
4384 }
4385 #[inline(always)]
4386 fn rotate_elements_left<const OFFSET: usize>(self) -> Self {
4387 self.simd.rotate_elements_left_mask64x2::<OFFSET>(self)
4388 }
4389 #[inline(always)]
4390 fn rotate_elements_right<const OFFSET: usize>(self) -> Self {
4391 self.simd.rotate_elements_right_mask64x2::<OFFSET>(self)
4392 }
4393 #[inline(always)]
4394 fn reverse(self) -> Self {
4395 self.simd.reverse_mask64x2(self)
4396 }
4397 #[inline(always)]
4398 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self {
4399 self.simd.simd_eq_mask64x2(self, rhs.simd_into(self.simd))
4400 }
4401 #[inline(always)]
4402 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self {
4403 self.simd.simd_ne_mask64x2(self, rhs.simd_into(self.simd))
4404 }
4405 #[inline(always)]
4406 fn any_true(self) -> bool {
4407 self.simd.any_true_mask64x2(self)
4408 }
4409 #[inline(always)]
4410 fn all_true(self) -> bool {
4411 self.simd.all_true_mask64x2(self)
4412 }
4413 #[inline(always)]
4414 fn any_false(self) -> bool {
4415 self.simd.any_false_mask64x2(self)
4416 }
4417 #[inline(always)]
4418 fn all_false(self) -> bool {
4419 self.simd.all_false_mask64x2(self)
4420 }
4421}
4422impl<S: Simd> MaskNarrow<S> for mask64x2<S> {
4423 type Narrowed = mask32x4<S>;
4424 #[inline(always)]
4425 fn narrow(self, high: Self) -> Self::Narrowed {
4426 self.simd.narrow_mask64x2(self, high)
4427 }
4428}
4429impl<S: Simd> ExtractToken for f32x8<S> {
4430 type S = S;
4431 #[inline]
4432 fn token(&self) -> S {
4433 self.simd
4434 }
4435}
4436#[doc = "A SIMD vector of 8 [`f32`] elements.\n\nThis type's memory layout is identical to that of [`[f32; 8]`](prim@array), except that it is aligned to 32 bytes.\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```"]
4437#[derive(Clone, Copy)]
4438#[repr(C, align(32))]
4439pub struct f32x8<S: Simd> {
4440 pub(crate) val: S::f32x8,
4441 pub simd: S,
4442}
4443impl<S: Simd> Seal for f32x8<S> {}
4444impl<S: Simd> SimdFrom<[f32; 8], S> for f32x8<S> {
4445 #[inline(always)]
4446 fn simd_from(simd: S, val: [f32; 8]) -> Self {
4447 Self {
4448 val: crate::transmute::checked_transmute_copy(&val),
4449 simd,
4450 }
4451 }
4452}
4453impl<S: Simd> From<f32x8<S>> for [f32; 8] {
4454 #[inline(always)]
4455 fn from(value: f32x8<S>) -> Self {
4456 crate::transmute::checked_transmute_copy(&value.val)
4457 }
4458}
4459impl<S: Simd> core::ops::Deref for f32x8<S> {
4460 type Target = [f32; 8];
4461 #[inline(always)]
4462 fn deref(&self) -> &Self::Target {
4463 crate::transmute::checked_cast_ref(&self.val)
4464 }
4465}
4466impl<S: Simd> core::ops::DerefMut for f32x8<S> {
4467 #[inline(always)]
4468 fn deref_mut(&mut self) -> &mut Self::Target {
4469 crate::transmute::checked_cast_mut(&mut self.val)
4470 }
4471}
4472impl<S: Simd + core::fmt::Debug> core::fmt::Debug for f32x8<S> {
4473 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4474 crate::support::simd_debug_impl(f, "f32x8", &self.simd, self.as_array())
4475 }
4476}
4477impl<S: Simd> SimdFrom<f32, S> for f32x8<S> {
4478 #[inline(always)]
4479 fn simd_from(simd: S, value: f32) -> Self {
4480 simd.splat_f32x8(value)
4481 }
4482}
4483impl<S: Simd> core::ops::Index<usize> for f32x8<S> {
4484 type Output = f32;
4485 #[inline(always)]
4486 fn index(&self, i: usize) -> &Self::Output {
4487 &self.as_array()[i]
4488 }
4489}
4490impl<S: Simd> core::ops::IndexMut<usize> for f32x8<S> {
4491 #[inline(always)]
4492 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
4493 &mut self.as_mut_array()[i]
4494 }
4495}
4496impl<S: Simd> Select<f32x8<S>> for mask32x8<S> {
4497 #[inline(always)]
4498 fn select(self, if_true: f32x8<S>, if_false: f32x8<S>) -> f32x8<S> {
4499 self.simd.select_f32x8(self, if_true, if_false)
4500 }
4501}
4502impl<S: Simd> Bytes for f32x8<S> {
4503 type Bytes = u8x32<S>;
4504 #[inline(always)]
4505 fn to_bytes(self) -> Self::Bytes {
4506 u8x32 {
4507 val: crate::transmute::checked_transmute_copy(&self.val),
4508 simd: self.simd,
4509 }
4510 }
4511 #[inline(always)]
4512 fn from_bytes(value: Self::Bytes) -> Self {
4513 Self {
4514 val: crate::transmute::checked_transmute_copy(&value.val),
4515 simd: value.simd,
4516 }
4517 }
4518}
4519impl<S: Simd> SimdBase<S> for f32x8<S> {
4520 type Element = f32;
4521 type ByteVector = u8x32<S>;
4522 const LEN: usize = 8;
4523 type Mask = mask32x8<S>;
4524 type Block = f32x4<S>;
4525 type Array = [f32; 8];
4526 #[inline(always)]
4527 fn as_slice(&self) -> &[f32] {
4528 self.as_array().as_slice()
4529 }
4530 #[inline(always)]
4531 fn as_mut_slice(&mut self) -> &mut [f32] {
4532 self.as_mut_array().as_mut_slice()
4533 }
4534 #[inline(always)]
4535 fn from_slice(simd: S, slice: &[f32]) -> Self {
4536 Self::load_array_ref(simd, slice.try_into().unwrap())
4537 }
4538 #[inline(always)]
4539 fn store_slice(&self, slice: &mut [f32]) {
4540 (*self).store_array(slice.try_into().unwrap());
4541 }
4542 #[inline(always)]
4543 fn splat(simd: S, val: f32) -> Self {
4544 simd.splat_f32x8(val)
4545 }
4546 #[inline(always)]
4547 fn block_splat(block: Self::Block) -> Self {
4548 block.simd.combine_f32x4(block, block)
4549 }
4550 #[inline(always)]
4551 fn from_fn(simd: S, mut f: impl FnMut(usize) -> f32) -> Self {
4552 Self::load_array(
4553 simd,
4554 [
4555 f(0usize),
4556 f(1usize),
4557 f(2usize),
4558 f(3usize),
4559 f(4usize),
4560 f(5usize),
4561 f(6usize),
4562 f(7usize),
4563 ],
4564 )
4565 }
4566 #[inline(always)]
4567 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
4568 self.simd
4569 .slide_f32x8::<SHIFT>(self, rhs.simd_into(self.simd))
4570 }
4571 #[inline(always)]
4572 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
4573 self.simd
4574 .slide_within_blocks_f32x8::<SHIFT>(self, rhs.simd_into(self.simd))
4575 }
4576 #[inline(always)]
4577 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
4578 self.simd
4579 .swizzle_dyn_within_blocks_f32x8(self, indices.simd_into(self.simd))
4580 }
4581 #[inline(always)]
4582 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
4583 self.simd
4584 .swizzle_dyn_f32x8(self, indices.simd_into(self.simd))
4585 }
4586 #[inline(always)]
4587 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
4588 self.simd
4589 .swizzle_dyn_precise_f32x8(self, indices.simd_into(self.simd))
4590 }
4591 #[inline(always)]
4592 fn abs(self) -> Self {
4593 self.simd.abs_f32x8(self)
4594 }
4595 #[inline(always)]
4596 fn reverse(self) -> Self {
4597 self.simd.reverse_f32x8(self)
4598 }
4599 #[inline(always)]
4600 fn concat_swizzle_dyn(
4601 self,
4602 rhs: impl SimdInto<Self, S>,
4603 indices: impl SimdInto<Self::Bytes, S>,
4604 ) -> Self {
4605 self.simd.concat_swizzle_dyn_f32x8(
4606 self,
4607 rhs.simd_into(self.simd),
4608 indices.simd_into(self.simd),
4609 )
4610 }
4611 #[inline(always)]
4612 fn concat_swizzle_dyn_precise(
4613 self,
4614 rhs: impl SimdInto<Self, S>,
4615 indices: impl SimdInto<Self::Bytes, S>,
4616 ) -> Self {
4617 self.simd.concat_swizzle_dyn_precise_f32x8(
4618 self,
4619 rhs.simd_into(self.simd),
4620 indices.simd_into(self.simd),
4621 )
4622 }
4623 #[inline(always)]
4624 fn compress(self, mask: Self::Mask) -> Self {
4625 self.simd.compress_f32x8(self, mask)
4626 }
4627 #[inline(always)]
4628 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
4629 self.simd
4630 .compress_merge_f32x8(self, mask, merge.simd_into(self.simd))
4631 }
4632 #[inline(always)]
4633 fn expand(self, mask: Self::Mask) -> Self {
4634 self.simd.expand_f32x8(self, mask)
4635 }
4636 #[inline(always)]
4637 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
4638 self.simd
4639 .expand_merge_f32x8(self, mask, merge.simd_into(self.simd))
4640 }
4641 #[inline(always)]
4642 fn reduce_max(self) -> Self::Element {
4643 self.simd.reduce_max_f32x8(self)
4644 }
4645 #[inline(always)]
4646 fn reduce_min(self) -> Self::Element {
4647 self.simd.reduce_min_f32x8(self)
4648 }
4649 #[inline(always)]
4650 fn reduce_max_precise(self) -> Self::Element {
4651 self.simd.reduce_max_precise_f32x8(self)
4652 }
4653 #[inline(always)]
4654 fn reduce_min_precise(self) -> Self::Element {
4655 self.simd.reduce_min_precise_f32x8(self)
4656 }
4657 #[inline(always)]
4658 fn reduce_sum(self) -> Self::Element {
4659 self.simd.reduce_sum_f32x8(self)
4660 }
4661 #[inline(always)]
4662 fn reduce_product(self) -> Self::Element {
4663 self.simd.reduce_product_f32x8(self)
4664 }
4665 #[inline(always)]
4666 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
4667 self.simd.max_f32x8(self, rhs.simd_into(self.simd))
4668 }
4669 #[inline(always)]
4670 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
4671 self.simd.min_f32x8(self, rhs.simd_into(self.simd))
4672 }
4673 #[inline(always)]
4674 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
4675 self.simd.max_precise_f32x8(self, rhs.simd_into(self.simd))
4676 }
4677 #[inline(always)]
4678 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
4679 self.simd.min_precise_f32x8(self, rhs.simd_into(self.simd))
4680 }
4681 #[inline(always)]
4682 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
4683 self.simd
4684 .clamp_f32x8(self, min.simd_into(self.simd), max.simd_into(self.simd))
4685 }
4686 #[inline(always)]
4687 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4688 self.simd.simd_eq_f32x8(self, rhs.simd_into(self.simd))
4689 }
4690 #[inline(always)]
4691 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4692 self.simd.simd_ne_f32x8(self, rhs.simd_into(self.simd))
4693 }
4694 #[inline(always)]
4695 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4696 self.simd.simd_lt_f32x8(self, rhs.simd_into(self.simd))
4697 }
4698 #[inline(always)]
4699 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4700 self.simd.simd_le_f32x8(self, rhs.simd_into(self.simd))
4701 }
4702 #[inline(always)]
4703 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4704 self.simd.simd_ge_f32x8(self, rhs.simd_into(self.simd))
4705 }
4706 #[inline(always)]
4707 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
4708 self.simd.simd_gt_f32x8(self, rhs.simd_into(self.simd))
4709 }
4710 #[inline(always)]
4711 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
4712 self.simd.zip_low_f32x8(self, rhs.simd_into(self.simd))
4713 }
4714 #[inline(always)]
4715 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
4716 self.simd.zip_high_f32x8(self, rhs.simd_into(self.simd))
4717 }
4718 #[inline(always)]
4719 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
4720 self.simd.unzip_low_f32x8(self, rhs.simd_into(self.simd))
4721 }
4722 #[inline(always)]
4723 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
4724 self.simd.unzip_high_f32x8(self, rhs.simd_into(self.simd))
4725 }
4726 #[inline(always)]
4727 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
4728 self.simd.interleave_f32x8(self, rhs.simd_into(self.simd))
4729 }
4730 #[inline(always)]
4731 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
4732 self.simd.deinterleave_f32x8(self, rhs.simd_into(self.simd))
4733 }
4734}
4735impl<S: Simd> crate::SimdFloat<S> for f32x8<S> {
4736 type Bits = u32x8<S>;
4737 #[inline(always)]
4738 fn sqrt(self) -> Self {
4739 self.simd.sqrt_f32x8(self)
4740 }
4741 #[inline(always)]
4742 fn approximate_recip(self) -> Self {
4743 self.simd.approximate_recip_f32x8(self)
4744 }
4745 #[inline(always)]
4746 fn copysign(self, rhs: impl SimdInto<Self, S>) -> Self {
4747 self.simd.copysign_f32x8(self, rhs.simd_into(self.simd))
4748 }
4749 #[inline(always)]
4750 fn mul_add(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
4751 self.simd
4752 .mul_add_f32x8(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
4753 }
4754 #[inline(always)]
4755 fn mul_add_precise(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
4756 self.simd
4757 .mul_add_precise_f32x8(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
4758 }
4759 #[inline(always)]
4760 fn mul_sub(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
4761 self.simd
4762 .mul_sub_f32x8(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
4763 }
4764 #[inline(always)]
4765 fn mul_sub_precise(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
4766 self.simd
4767 .mul_sub_precise_f32x8(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
4768 }
4769 #[inline(always)]
4770 fn floor(self) -> Self {
4771 self.simd.floor_f32x8(self)
4772 }
4773 #[inline(always)]
4774 fn ceil(self) -> Self {
4775 self.simd.ceil_f32x8(self)
4776 }
4777 #[inline(always)]
4778 fn round_ties_even(self) -> Self {
4779 self.simd.round_ties_even_f32x8(self)
4780 }
4781 #[inline(always)]
4782 fn round(self) -> Self {
4783 self.simd.round_f32x8(self)
4784 }
4785 #[inline(always)]
4786 fn fract(self) -> Self {
4787 self.simd.fract_f32x8(self)
4788 }
4789 #[inline(always)]
4790 fn trunc(self) -> Self {
4791 self.simd.trunc_f32x8(self)
4792 }
4793 #[inline(always)]
4794 fn to_degrees(self) -> Self {
4795 self.simd.to_degrees_f32x8(self)
4796 }
4797 #[inline(always)]
4798 fn to_radians(self) -> Self {
4799 self.simd.to_radians_f32x8(self)
4800 }
4801 #[inline(always)]
4802 fn is_nan(self) -> Self::Mask {
4803 self.simd.is_nan_f32x8(self)
4804 }
4805 #[inline(always)]
4806 fn is_infinite(self) -> Self::Mask {
4807 self.simd.is_infinite_f32x8(self)
4808 }
4809 #[inline(always)]
4810 fn is_finite(self) -> Self::Mask {
4811 self.simd.is_finite_f32x8(self)
4812 }
4813 #[inline(always)]
4814 fn is_subnormal(self) -> Self::Mask {
4815 self.simd.is_subnormal_f32x8(self)
4816 }
4817 #[inline(always)]
4818 fn is_normal(self) -> Self::Mask {
4819 self.simd.is_normal_f32x8(self)
4820 }
4821 #[inline(always)]
4822 fn is_sign_positive(self) -> Self::Mask {
4823 self.simd.is_sign_positive_f32x8(self)
4824 }
4825 #[inline(always)]
4826 fn is_sign_negative(self) -> Self::Mask {
4827 self.simd.is_sign_negative_f32x8(self)
4828 }
4829}
4830impl<S: Simd> SimdCvtFloat<u32x8<S>> for f32x8<S> {
4831 #[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."]
4832 #[inline(always)]
4833 fn float_from(x: u32x8<S>) -> Self {
4834 x.simd.cvt_f32_u32x8(x)
4835 }
4836}
4837impl<S: Simd> SimdCvtFloat<i32x8<S>> for f32x8<S> {
4838 #[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."]
4839 #[inline(always)]
4840 fn float_from(x: i32x8<S>) -> Self {
4841 x.simd.cvt_f32_i32x8(x)
4842 }
4843}
4844impl<S: Simd> SimdWiden<S> for f32x8<S> {
4845 type Widened = f64x4<S>;
4846 #[inline(always)]
4847 fn widen(self) -> (Self::Widened, Self::Widened) {
4848 self.simd.widen_f32x8(self)
4849 }
4850}
4851impl<S: Simd> crate::SimdSplit<S> for f32x8<S> {
4852 type Split = f32x4<S>;
4853 #[inline(always)]
4854 fn split(self) -> (Self::Split, Self::Split) {
4855 self.simd.split_f32x8(self)
4856 }
4857}
4858impl<S: Simd> crate::SimdCombine<S> for f32x8<S> {
4859 type Combined = f32x16<S>;
4860 #[inline(always)]
4861 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
4862 self.simd.combine_f32x8(self, rhs.simd_into(self.simd))
4863 }
4864}
4865impl<S: Simd> ExtractToken for i8x32<S> {
4866 type S = S;
4867 #[inline]
4868 fn token(&self) -> S {
4869 self.simd
4870 }
4871}
4872#[doc = "A SIMD vector of 32 [`i8`] elements.\n\nThis type's memory layout is identical to that of [`[i8; 32]`](prim@array), except that it is aligned to 32 bytes.\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```"]
4873#[derive(Clone, Copy)]
4874#[repr(C, align(32))]
4875pub struct i8x32<S: Simd> {
4876 pub(crate) val: S::i8x32,
4877 pub simd: S,
4878}
4879impl<S: Simd> Seal for i8x32<S> {}
4880impl<S: Simd> SimdFrom<[i8; 32], S> for i8x32<S> {
4881 #[inline(always)]
4882 fn simd_from(simd: S, val: [i8; 32]) -> Self {
4883 Self {
4884 val: crate::transmute::checked_transmute_copy(&val),
4885 simd,
4886 }
4887 }
4888}
4889impl<S: Simd> From<i8x32<S>> for [i8; 32] {
4890 #[inline(always)]
4891 fn from(value: i8x32<S>) -> Self {
4892 crate::transmute::checked_transmute_copy(&value.val)
4893 }
4894}
4895impl<S: Simd> core::ops::Deref for i8x32<S> {
4896 type Target = [i8; 32];
4897 #[inline(always)]
4898 fn deref(&self) -> &Self::Target {
4899 crate::transmute::checked_cast_ref(&self.val)
4900 }
4901}
4902impl<S: Simd> core::ops::DerefMut for i8x32<S> {
4903 #[inline(always)]
4904 fn deref_mut(&mut self) -> &mut Self::Target {
4905 crate::transmute::checked_cast_mut(&mut self.val)
4906 }
4907}
4908impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i8x32<S> {
4909 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
4910 crate::support::simd_debug_impl(f, "i8x32", &self.simd, self.as_array())
4911 }
4912}
4913impl<S: Simd> SimdFrom<i8, S> for i8x32<S> {
4914 #[inline(always)]
4915 fn simd_from(simd: S, value: i8) -> Self {
4916 simd.splat_i8x32(value)
4917 }
4918}
4919impl<S: Simd> core::ops::Index<usize> for i8x32<S> {
4920 type Output = i8;
4921 #[inline(always)]
4922 fn index(&self, i: usize) -> &Self::Output {
4923 &self.as_array()[i]
4924 }
4925}
4926impl<S: Simd> core::ops::IndexMut<usize> for i8x32<S> {
4927 #[inline(always)]
4928 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
4929 &mut self.as_mut_array()[i]
4930 }
4931}
4932impl<S: Simd> Select<i8x32<S>> for mask8x32<S> {
4933 #[inline(always)]
4934 fn select(self, if_true: i8x32<S>, if_false: i8x32<S>) -> i8x32<S> {
4935 self.simd.select_i8x32(self, if_true, if_false)
4936 }
4937}
4938impl<S: Simd> Bytes for i8x32<S> {
4939 type Bytes = u8x32<S>;
4940 #[inline(always)]
4941 fn to_bytes(self) -> Self::Bytes {
4942 u8x32 {
4943 val: crate::transmute::checked_transmute_copy(&self.val),
4944 simd: self.simd,
4945 }
4946 }
4947 #[inline(always)]
4948 fn from_bytes(value: Self::Bytes) -> Self {
4949 Self {
4950 val: crate::transmute::checked_transmute_copy(&value.val),
4951 simd: value.simd,
4952 }
4953 }
4954}
4955impl<S: Simd> SimdBase<S> for i8x32<S> {
4956 type Element = i8;
4957 type ByteVector = u8x32<S>;
4958 const LEN: usize = 32;
4959 type Mask = mask8x32<S>;
4960 type Block = i8x16<S>;
4961 type Array = [i8; 32];
4962 #[inline(always)]
4963 fn as_slice(&self) -> &[i8] {
4964 self.as_array().as_slice()
4965 }
4966 #[inline(always)]
4967 fn as_mut_slice(&mut self) -> &mut [i8] {
4968 self.as_mut_array().as_mut_slice()
4969 }
4970 #[inline(always)]
4971 fn from_slice(simd: S, slice: &[i8]) -> Self {
4972 Self::load_array_ref(simd, slice.try_into().unwrap())
4973 }
4974 #[inline(always)]
4975 fn store_slice(&self, slice: &mut [i8]) {
4976 (*self).store_array(slice.try_into().unwrap());
4977 }
4978 #[inline(always)]
4979 fn splat(simd: S, val: i8) -> Self {
4980 simd.splat_i8x32(val)
4981 }
4982 #[inline(always)]
4983 fn block_splat(block: Self::Block) -> Self {
4984 block.simd.combine_i8x16(block, block)
4985 }
4986 #[inline(always)]
4987 fn from_fn(simd: S, mut f: impl FnMut(usize) -> i8) -> Self {
4988 Self::load_array(
4989 simd,
4990 [
4991 f(0usize),
4992 f(1usize),
4993 f(2usize),
4994 f(3usize),
4995 f(4usize),
4996 f(5usize),
4997 f(6usize),
4998 f(7usize),
4999 f(8usize),
5000 f(9usize),
5001 f(10usize),
5002 f(11usize),
5003 f(12usize),
5004 f(13usize),
5005 f(14usize),
5006 f(15usize),
5007 f(16usize),
5008 f(17usize),
5009 f(18usize),
5010 f(19usize),
5011 f(20usize),
5012 f(21usize),
5013 f(22usize),
5014 f(23usize),
5015 f(24usize),
5016 f(25usize),
5017 f(26usize),
5018 f(27usize),
5019 f(28usize),
5020 f(29usize),
5021 f(30usize),
5022 f(31usize),
5023 ],
5024 )
5025 }
5026 #[inline(always)]
5027 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
5028 self.simd
5029 .slide_i8x32::<SHIFT>(self, rhs.simd_into(self.simd))
5030 }
5031 #[inline(always)]
5032 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
5033 self.simd
5034 .slide_within_blocks_i8x32::<SHIFT>(self, rhs.simd_into(self.simd))
5035 }
5036 #[inline(always)]
5037 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
5038 self.simd
5039 .swizzle_dyn_within_blocks_i8x32(self, indices.simd_into(self.simd))
5040 }
5041 #[inline(always)]
5042 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
5043 self.simd
5044 .swizzle_dyn_i8x32(self, indices.simd_into(self.simd))
5045 }
5046 #[inline(always)]
5047 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
5048 self.simd
5049 .swizzle_dyn_precise_i8x32(self, indices.simd_into(self.simd))
5050 }
5051 #[inline(always)]
5052 fn abs(self) -> Self {
5053 self.simd.abs_i8x32(self)
5054 }
5055 #[inline(always)]
5056 fn reverse(self) -> Self {
5057 self.simd.reverse_i8x32(self)
5058 }
5059 #[inline(always)]
5060 fn concat_swizzle_dyn(
5061 self,
5062 rhs: impl SimdInto<Self, S>,
5063 indices: impl SimdInto<Self::Bytes, S>,
5064 ) -> Self {
5065 self.simd.concat_swizzle_dyn_i8x32(
5066 self,
5067 rhs.simd_into(self.simd),
5068 indices.simd_into(self.simd),
5069 )
5070 }
5071 #[inline(always)]
5072 fn concat_swizzle_dyn_precise(
5073 self,
5074 rhs: impl SimdInto<Self, S>,
5075 indices: impl SimdInto<Self::Bytes, S>,
5076 ) -> Self {
5077 self.simd.concat_swizzle_dyn_precise_i8x32(
5078 self,
5079 rhs.simd_into(self.simd),
5080 indices.simd_into(self.simd),
5081 )
5082 }
5083 #[inline(always)]
5084 fn compress(self, mask: Self::Mask) -> Self {
5085 self.simd.compress_i8x32(self, mask)
5086 }
5087 #[inline(always)]
5088 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
5089 self.simd
5090 .compress_merge_i8x32(self, mask, merge.simd_into(self.simd))
5091 }
5092 #[inline(always)]
5093 fn expand(self, mask: Self::Mask) -> Self {
5094 self.simd.expand_i8x32(self, mask)
5095 }
5096 #[inline(always)]
5097 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
5098 self.simd
5099 .expand_merge_i8x32(self, mask, merge.simd_into(self.simd))
5100 }
5101 #[inline(always)]
5102 fn reduce_max(self) -> Self::Element {
5103 self.simd.reduce_max_i8x32(self)
5104 }
5105 #[inline(always)]
5106 fn reduce_min(self) -> Self::Element {
5107 self.simd.reduce_min_i8x32(self)
5108 }
5109 #[inline(always)]
5110 fn reduce_max_precise(self) -> Self::Element {
5111 self.simd.reduce_max_i8x32(self)
5112 }
5113 #[inline(always)]
5114 fn reduce_min_precise(self) -> Self::Element {
5115 self.simd.reduce_min_i8x32(self)
5116 }
5117 #[inline(always)]
5118 fn reduce_sum(self) -> Self::Element {
5119 self.simd.reduce_sum_i8x32(self)
5120 }
5121 #[inline(always)]
5122 fn reduce_product(self) -> Self::Element {
5123 self.simd.reduce_product_i8x32(self)
5124 }
5125 #[inline(always)]
5126 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
5127 self.simd.max_i8x32(self, rhs.simd_into(self.simd))
5128 }
5129 #[inline(always)]
5130 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
5131 self.simd.min_i8x32(self, rhs.simd_into(self.simd))
5132 }
5133 #[inline(always)]
5134 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
5135 self.simd.max_i8x32(self, rhs.simd_into(self.simd))
5136 }
5137 #[inline(always)]
5138 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
5139 self.simd.min_i8x32(self, rhs.simd_into(self.simd))
5140 }
5141 #[inline(always)]
5142 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
5143 self.simd
5144 .clamp_i8x32(self, min.simd_into(self.simd), max.simd_into(self.simd))
5145 }
5146 #[inline(always)]
5147 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5148 self.simd.simd_eq_i8x32(self, rhs.simd_into(self.simd))
5149 }
5150 #[inline(always)]
5151 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5152 self.simd.simd_ne_i8x32(self, rhs.simd_into(self.simd))
5153 }
5154 #[inline(always)]
5155 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5156 self.simd.simd_lt_i8x32(self, rhs.simd_into(self.simd))
5157 }
5158 #[inline(always)]
5159 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5160 self.simd.simd_le_i8x32(self, rhs.simd_into(self.simd))
5161 }
5162 #[inline(always)]
5163 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5164 self.simd.simd_ge_i8x32(self, rhs.simd_into(self.simd))
5165 }
5166 #[inline(always)]
5167 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5168 self.simd.simd_gt_i8x32(self, rhs.simd_into(self.simd))
5169 }
5170 #[inline(always)]
5171 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
5172 self.simd.zip_low_i8x32(self, rhs.simd_into(self.simd))
5173 }
5174 #[inline(always)]
5175 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
5176 self.simd.zip_high_i8x32(self, rhs.simd_into(self.simd))
5177 }
5178 #[inline(always)]
5179 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
5180 self.simd.unzip_low_i8x32(self, rhs.simd_into(self.simd))
5181 }
5182 #[inline(always)]
5183 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
5184 self.simd.unzip_high_i8x32(self, rhs.simd_into(self.simd))
5185 }
5186 #[inline(always)]
5187 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
5188 self.simd.interleave_i8x32(self, rhs.simd_into(self.simd))
5189 }
5190 #[inline(always)]
5191 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
5192 self.simd.deinterleave_i8x32(self, rhs.simd_into(self.simd))
5193 }
5194}
5195impl<S: Simd> crate::SimdInt<S> for i8x32<S> {
5196 #[inline(always)]
5197 fn count_ones(self) -> Self {
5198 self.simd.count_ones_i8x32(self)
5199 }
5200 #[inline(always)]
5201 fn count_zeros(self) -> Self {
5202 self.simd.count_zeros_i8x32(self)
5203 }
5204 #[inline(always)]
5205 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
5206 self.simd
5207 .saturating_add_i8x32(self, rhs.simd_into(self.simd))
5208 }
5209 #[inline(always)]
5210 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
5211 self.simd
5212 .saturating_sub_i8x32(self, rhs.simd_into(self.simd))
5213 }
5214}
5215impl<S: Simd> SimdWiden<S> for i8x32<S> {
5216 type Widened = i16x16<S>;
5217 #[inline(always)]
5218 fn widen(self) -> (Self::Widened, Self::Widened) {
5219 self.simd.widen_i8x32(self)
5220 }
5221}
5222impl<S: Simd> SimdIntWiden<S> for i8x32<S> {
5223 #[inline(always)]
5224 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
5225 self.simd.widening_mul_i8x32(self, rhs.simd_into(self.simd))
5226 }
5227 #[inline(always)]
5228 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
5229 self.simd.widening_add_i8x32(self, rhs.simd_into(self.simd))
5230 }
5231 #[inline(always)]
5232 fn pairwise_widening_add(self) -> Self::Widened {
5233 self.simd.pairwise_widening_add_i8x32(self)
5234 }
5235 #[inline(always)]
5236 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
5237 self.simd
5238 .pairwise_dot_product_i8x32(self, rhs.simd_into(self.simd))
5239 }
5240}
5241impl<S: Simd> crate::SimdSplit<S> for i8x32<S> {
5242 type Split = i8x16<S>;
5243 #[inline(always)]
5244 fn split(self) -> (Self::Split, Self::Split) {
5245 self.simd.split_i8x32(self)
5246 }
5247}
5248impl<S: Simd> crate::SimdCombine<S> for i8x32<S> {
5249 type Combined = i8x64<S>;
5250 #[inline(always)]
5251 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
5252 self.simd.combine_i8x32(self, rhs.simd_into(self.simd))
5253 }
5254}
5255impl<S: Simd> ExtractToken for u8x32<S> {
5256 type S = S;
5257 #[inline]
5258 fn token(&self) -> S {
5259 self.simd
5260 }
5261}
5262#[doc = "A SIMD vector of 32 [`u8`] elements.\n\nThis type's memory layout is identical to that of [`[u8; 32]`](prim@array), except that it is aligned to 32 bytes.\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```"]
5263#[derive(Clone, Copy)]
5264#[repr(C, align(32))]
5265pub struct u8x32<S: Simd> {
5266 pub(crate) val: S::u8x32,
5267 pub simd: S,
5268}
5269impl<S: Simd> Seal for u8x32<S> {}
5270impl<S: Simd> SimdFrom<[u8; 32], S> for u8x32<S> {
5271 #[inline(always)]
5272 fn simd_from(simd: S, val: [u8; 32]) -> Self {
5273 Self {
5274 val: crate::transmute::checked_transmute_copy(&val),
5275 simd,
5276 }
5277 }
5278}
5279impl<S: Simd> From<u8x32<S>> for [u8; 32] {
5280 #[inline(always)]
5281 fn from(value: u8x32<S>) -> Self {
5282 crate::transmute::checked_transmute_copy(&value.val)
5283 }
5284}
5285impl<S: Simd> core::ops::Deref for u8x32<S> {
5286 type Target = [u8; 32];
5287 #[inline(always)]
5288 fn deref(&self) -> &Self::Target {
5289 crate::transmute::checked_cast_ref(&self.val)
5290 }
5291}
5292impl<S: Simd> core::ops::DerefMut for u8x32<S> {
5293 #[inline(always)]
5294 fn deref_mut(&mut self) -> &mut Self::Target {
5295 crate::transmute::checked_cast_mut(&mut self.val)
5296 }
5297}
5298impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u8x32<S> {
5299 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5300 crate::support::simd_debug_impl(f, "u8x32", &self.simd, self.as_array())
5301 }
5302}
5303impl<S: Simd> SimdFrom<u8, S> for u8x32<S> {
5304 #[inline(always)]
5305 fn simd_from(simd: S, value: u8) -> Self {
5306 simd.splat_u8x32(value)
5307 }
5308}
5309impl<S: Simd> core::ops::Index<usize> for u8x32<S> {
5310 type Output = u8;
5311 #[inline(always)]
5312 fn index(&self, i: usize) -> &Self::Output {
5313 &self.as_array()[i]
5314 }
5315}
5316impl<S: Simd> core::ops::IndexMut<usize> for u8x32<S> {
5317 #[inline(always)]
5318 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
5319 &mut self.as_mut_array()[i]
5320 }
5321}
5322impl<S: Simd> Select<u8x32<S>> for mask8x32<S> {
5323 #[inline(always)]
5324 fn select(self, if_true: u8x32<S>, if_false: u8x32<S>) -> u8x32<S> {
5325 self.simd.select_u8x32(self, if_true, if_false)
5326 }
5327}
5328impl<S: Simd> Bytes for u8x32<S> {
5329 type Bytes = u8x32<S>;
5330 #[inline(always)]
5331 fn to_bytes(self) -> Self::Bytes {
5332 u8x32 {
5333 val: crate::transmute::checked_transmute_copy(&self.val),
5334 simd: self.simd,
5335 }
5336 }
5337 #[inline(always)]
5338 fn from_bytes(value: Self::Bytes) -> Self {
5339 Self {
5340 val: crate::transmute::checked_transmute_copy(&value.val),
5341 simd: value.simd,
5342 }
5343 }
5344}
5345impl<S: Simd> SimdBase<S> for u8x32<S> {
5346 type Element = u8;
5347 type ByteVector = u8x32<S>;
5348 const LEN: usize = 32;
5349 type Mask = mask8x32<S>;
5350 type Block = u8x16<S>;
5351 type Array = [u8; 32];
5352 #[inline(always)]
5353 fn as_slice(&self) -> &[u8] {
5354 self.as_array().as_slice()
5355 }
5356 #[inline(always)]
5357 fn as_mut_slice(&mut self) -> &mut [u8] {
5358 self.as_mut_array().as_mut_slice()
5359 }
5360 #[inline(always)]
5361 fn from_slice(simd: S, slice: &[u8]) -> Self {
5362 Self::load_array_ref(simd, slice.try_into().unwrap())
5363 }
5364 #[inline(always)]
5365 fn store_slice(&self, slice: &mut [u8]) {
5366 (*self).store_array(slice.try_into().unwrap());
5367 }
5368 #[inline(always)]
5369 fn splat(simd: S, val: u8) -> Self {
5370 simd.splat_u8x32(val)
5371 }
5372 #[inline(always)]
5373 fn block_splat(block: Self::Block) -> Self {
5374 block.simd.combine_u8x16(block, block)
5375 }
5376 #[inline(always)]
5377 fn from_fn(simd: S, mut f: impl FnMut(usize) -> u8) -> Self {
5378 Self::load_array(
5379 simd,
5380 [
5381 f(0usize),
5382 f(1usize),
5383 f(2usize),
5384 f(3usize),
5385 f(4usize),
5386 f(5usize),
5387 f(6usize),
5388 f(7usize),
5389 f(8usize),
5390 f(9usize),
5391 f(10usize),
5392 f(11usize),
5393 f(12usize),
5394 f(13usize),
5395 f(14usize),
5396 f(15usize),
5397 f(16usize),
5398 f(17usize),
5399 f(18usize),
5400 f(19usize),
5401 f(20usize),
5402 f(21usize),
5403 f(22usize),
5404 f(23usize),
5405 f(24usize),
5406 f(25usize),
5407 f(26usize),
5408 f(27usize),
5409 f(28usize),
5410 f(29usize),
5411 f(30usize),
5412 f(31usize),
5413 ],
5414 )
5415 }
5416 #[inline(always)]
5417 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
5418 self.simd
5419 .slide_u8x32::<SHIFT>(self, rhs.simd_into(self.simd))
5420 }
5421 #[inline(always)]
5422 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
5423 self.simd
5424 .slide_within_blocks_u8x32::<SHIFT>(self, rhs.simd_into(self.simd))
5425 }
5426 #[inline(always)]
5427 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
5428 self.simd
5429 .swizzle_dyn_within_blocks_u8x32(self, indices.simd_into(self.simd))
5430 }
5431 #[inline(always)]
5432 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
5433 self.simd
5434 .swizzle_dyn_u8x32(self, indices.simd_into(self.simd))
5435 }
5436 #[inline(always)]
5437 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
5438 self.simd
5439 .swizzle_dyn_precise_u8x32(self, indices.simd_into(self.simd))
5440 }
5441 #[inline(always)]
5442 fn abs(self) -> Self {
5443 self.simd.abs_u8x32(self)
5444 }
5445 #[inline(always)]
5446 fn reverse(self) -> Self {
5447 self.simd.reverse_u8x32(self)
5448 }
5449 #[inline(always)]
5450 fn concat_swizzle_dyn(
5451 self,
5452 rhs: impl SimdInto<Self, S>,
5453 indices: impl SimdInto<Self::Bytes, S>,
5454 ) -> Self {
5455 self.simd.concat_swizzle_dyn_u8x32(
5456 self,
5457 rhs.simd_into(self.simd),
5458 indices.simd_into(self.simd),
5459 )
5460 }
5461 #[inline(always)]
5462 fn concat_swizzle_dyn_precise(
5463 self,
5464 rhs: impl SimdInto<Self, S>,
5465 indices: impl SimdInto<Self::Bytes, S>,
5466 ) -> Self {
5467 self.simd.concat_swizzle_dyn_precise_u8x32(
5468 self,
5469 rhs.simd_into(self.simd),
5470 indices.simd_into(self.simd),
5471 )
5472 }
5473 #[inline(always)]
5474 fn compress(self, mask: Self::Mask) -> Self {
5475 self.simd.compress_u8x32(self, mask)
5476 }
5477 #[inline(always)]
5478 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
5479 self.simd
5480 .compress_merge_u8x32(self, mask, merge.simd_into(self.simd))
5481 }
5482 #[inline(always)]
5483 fn expand(self, mask: Self::Mask) -> Self {
5484 self.simd.expand_u8x32(self, mask)
5485 }
5486 #[inline(always)]
5487 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
5488 self.simd
5489 .expand_merge_u8x32(self, mask, merge.simd_into(self.simd))
5490 }
5491 #[inline(always)]
5492 fn reduce_max(self) -> Self::Element {
5493 self.simd.reduce_max_u8x32(self)
5494 }
5495 #[inline(always)]
5496 fn reduce_min(self) -> Self::Element {
5497 self.simd.reduce_min_u8x32(self)
5498 }
5499 #[inline(always)]
5500 fn reduce_max_precise(self) -> Self::Element {
5501 self.simd.reduce_max_u8x32(self)
5502 }
5503 #[inline(always)]
5504 fn reduce_min_precise(self) -> Self::Element {
5505 self.simd.reduce_min_u8x32(self)
5506 }
5507 #[inline(always)]
5508 fn reduce_sum(self) -> Self::Element {
5509 self.simd.reduce_sum_u8x32(self)
5510 }
5511 #[inline(always)]
5512 fn reduce_product(self) -> Self::Element {
5513 self.simd.reduce_product_u8x32(self)
5514 }
5515 #[inline(always)]
5516 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
5517 self.simd.max_u8x32(self, rhs.simd_into(self.simd))
5518 }
5519 #[inline(always)]
5520 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
5521 self.simd.min_u8x32(self, rhs.simd_into(self.simd))
5522 }
5523 #[inline(always)]
5524 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
5525 self.simd.max_u8x32(self, rhs.simd_into(self.simd))
5526 }
5527 #[inline(always)]
5528 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
5529 self.simd.min_u8x32(self, rhs.simd_into(self.simd))
5530 }
5531 #[inline(always)]
5532 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
5533 self.simd
5534 .clamp_u8x32(self, min.simd_into(self.simd), max.simd_into(self.simd))
5535 }
5536 #[inline(always)]
5537 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5538 self.simd.simd_eq_u8x32(self, rhs.simd_into(self.simd))
5539 }
5540 #[inline(always)]
5541 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5542 self.simd.simd_ne_u8x32(self, rhs.simd_into(self.simd))
5543 }
5544 #[inline(always)]
5545 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5546 self.simd.simd_lt_u8x32(self, rhs.simd_into(self.simd))
5547 }
5548 #[inline(always)]
5549 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5550 self.simd.simd_le_u8x32(self, rhs.simd_into(self.simd))
5551 }
5552 #[inline(always)]
5553 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5554 self.simd.simd_ge_u8x32(self, rhs.simd_into(self.simd))
5555 }
5556 #[inline(always)]
5557 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
5558 self.simd.simd_gt_u8x32(self, rhs.simd_into(self.simd))
5559 }
5560 #[inline(always)]
5561 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
5562 self.simd.zip_low_u8x32(self, rhs.simd_into(self.simd))
5563 }
5564 #[inline(always)]
5565 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
5566 self.simd.zip_high_u8x32(self, rhs.simd_into(self.simd))
5567 }
5568 #[inline(always)]
5569 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
5570 self.simd.unzip_low_u8x32(self, rhs.simd_into(self.simd))
5571 }
5572 #[inline(always)]
5573 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
5574 self.simd.unzip_high_u8x32(self, rhs.simd_into(self.simd))
5575 }
5576 #[inline(always)]
5577 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
5578 self.simd.interleave_u8x32(self, rhs.simd_into(self.simd))
5579 }
5580 #[inline(always)]
5581 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
5582 self.simd.deinterleave_u8x32(self, rhs.simd_into(self.simd))
5583 }
5584}
5585impl<S: Simd> crate::SimdInt<S> for u8x32<S> {
5586 #[inline(always)]
5587 fn count_ones(self) -> Self {
5588 self.simd.count_ones_u8x32(self)
5589 }
5590 #[inline(always)]
5591 fn count_zeros(self) -> Self {
5592 self.simd.count_zeros_u8x32(self)
5593 }
5594 #[inline(always)]
5595 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
5596 self.simd
5597 .saturating_add_u8x32(self, rhs.simd_into(self.simd))
5598 }
5599 #[inline(always)]
5600 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
5601 self.simd
5602 .saturating_sub_u8x32(self, rhs.simd_into(self.simd))
5603 }
5604}
5605impl<S: Simd> SimdWiden<S> for u8x32<S> {
5606 type Widened = u16x16<S>;
5607 #[inline(always)]
5608 fn widen(self) -> (Self::Widened, Self::Widened) {
5609 self.simd.widen_u8x32(self)
5610 }
5611}
5612impl<S: Simd> SimdIntWiden<S> for u8x32<S> {
5613 #[inline(always)]
5614 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
5615 self.simd.widening_mul_u8x32(self, rhs.simd_into(self.simd))
5616 }
5617 #[inline(always)]
5618 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
5619 self.simd.widening_add_u8x32(self, rhs.simd_into(self.simd))
5620 }
5621 #[inline(always)]
5622 fn pairwise_widening_add(self) -> Self::Widened {
5623 self.simd.pairwise_widening_add_u8x32(self)
5624 }
5625 #[inline(always)]
5626 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
5627 self.simd
5628 .pairwise_dot_product_u8x32(self, rhs.simd_into(self.simd))
5629 }
5630}
5631impl<S: Simd> crate::SimdSplit<S> for u8x32<S> {
5632 type Split = u8x16<S>;
5633 #[inline(always)]
5634 fn split(self) -> (Self::Split, Self::Split) {
5635 self.simd.split_u8x32(self)
5636 }
5637}
5638impl<S: Simd> crate::SimdCombine<S> for u8x32<S> {
5639 type Combined = u8x64<S>;
5640 #[inline(always)]
5641 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
5642 self.simd.combine_u8x32(self, rhs.simd_into(self.simd))
5643 }
5644}
5645impl<S: Simd> ExtractToken for mask8x32<S> {
5646 type S = S;
5647 #[inline]
5648 fn token(&self) -> S {
5649 self.simd
5650 }
5651}
5652#[doc = "A SIMD mask of 32 logical lanes corresponding to 8-bit vector elements.\n\nThe storage representation of this type is intentionally opaque and may vary depending on the SIMD level.\n\nYou can construct this mask type using the [`Self::splat`], [`Self::from_bitmask`], [`Self::from_slice`], and [`Self::simd_from`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, mask8x32};\nfn construct_mask<S: Simd>(simd: S) {\n // From a single boolean value:\n let a = mask8x32::splat(simd, true);\n let b = mask8x32::simd_from(simd, true);\n\n // From signed integer mask lanes:\n let c = mask8x32::from_slice(simd, &[-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);\n let d = mask8x32::simd_from(simd, [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);\n\n // From a compact bitmask (same mask as above, least significant bit maps to lane 0):\n let e = mask8x32::from_bitmask(simd, 0b0001);\n\n // By setting individual lanes:\n let mut f = mask8x32::splat(simd, false);\n f.set(0, true);\n}\n```"]
5653#[derive(Clone, Copy)]
5654pub struct mask8x32<S: Simd> {
5655 pub(crate) val: S::mask8x32,
5656 pub(crate) simd: S,
5657}
5658impl<S: Simd> Seal for mask8x32<S> {}
5659impl<S: Simd> SimdFrom<[i8; 32], S> for mask8x32<S> {
5660 #[inline(always)]
5661 fn simd_from(simd: S, val: [i8; 32]) -> Self {
5662 Self {
5663 val: <S as crate::arch_types::ArchTypes>::mask8x32_from_array(simd, val),
5664 simd,
5665 }
5666 }
5667}
5668impl<S: Simd> From<mask8x32<S>> for [i8; 32] {
5669 #[inline(always)]
5670 fn from(value: mask8x32<S>) -> Self {
5671 <S as crate::arch_types::ArchTypes>::mask8x32_to_array(value.simd, value.val)
5672 }
5673}
5674impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask8x32<S> {
5675 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5676 let lanes: [i8; 32] = (*self).into();
5677 crate::support::simd_debug_impl(f, "mask8x32", &self.simd, &lanes)
5678 }
5679}
5680impl<S: Simd> SimdFrom<bool, S> for mask8x32<S> {
5681 #[inline(always)]
5682 fn simd_from(simd: S, value: bool) -> Self {
5683 simd.splat_mask8x32(value)
5684 }
5685}
5686impl<S: Simd> Select<mask8x32<S>> for mask8x32<S> {
5687 #[inline(always)]
5688 fn select(self, if_true: mask8x32<S>, if_false: mask8x32<S>) -> mask8x32<S> {
5689 self.simd.select_mask8x32(self, if_true, if_false)
5690 }
5691}
5692impl<S: Simd> SimdMask<S> for mask8x32<S> {
5693 type Element = i8;
5694 type Ints = i8x32<S>;
5695 const LEN: usize = 32;
5696 #[inline(always)]
5697 fn splat(simd: S, val: bool) -> Self {
5698 simd.splat_mask8x32(val)
5699 }
5700 #[inline(always)]
5701 fn from_bitmask(simd: S, bits: u64) -> Self {
5702 simd.from_bitmask_mask8x32(bits)
5703 }
5704 #[inline(always)]
5705 fn to_bitmask(self) -> u64 {
5706 self.simd.to_bitmask_mask8x32(self)
5707 }
5708 #[inline(always)]
5709 fn from_vector(vector: Self::Ints) -> Self {
5710 vector.token().from_vector_mask8x32(vector)
5711 }
5712 #[inline(always)]
5713 fn to_vector(self) -> Self::Ints {
5714 self.simd.to_vector_mask8x32(self)
5715 }
5716 #[inline(always)]
5717 fn set(&mut self, index: usize, value: bool) {
5718 self.simd.set_mask8x32(self, index, value);
5719 }
5720 #[inline(always)]
5721 fn from_slice(simd: S, slice: &[i8]) -> Self {
5722 let slice: &[i8; 32] = slice.try_into().unwrap();
5723 Self::simd_from(simd, *slice)
5724 }
5725 #[inline(always)]
5726 fn store_slice(&self, slice: &mut [i8]) {
5727 let slice: &mut [i8; 32] = slice.try_into().unwrap();
5728 *slice = (*self).into();
5729 }
5730 #[inline(always)]
5731 fn rotate_elements_left<const OFFSET: usize>(self) -> Self {
5732 self.simd.rotate_elements_left_mask8x32::<OFFSET>(self)
5733 }
5734 #[inline(always)]
5735 fn rotate_elements_right<const OFFSET: usize>(self) -> Self {
5736 self.simd.rotate_elements_right_mask8x32::<OFFSET>(self)
5737 }
5738 #[inline(always)]
5739 fn reverse(self) -> Self {
5740 self.simd.reverse_mask8x32(self)
5741 }
5742 #[inline(always)]
5743 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self {
5744 self.simd.simd_eq_mask8x32(self, rhs.simd_into(self.simd))
5745 }
5746 #[inline(always)]
5747 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self {
5748 self.simd.simd_ne_mask8x32(self, rhs.simd_into(self.simd))
5749 }
5750 #[inline(always)]
5751 fn any_true(self) -> bool {
5752 self.simd.any_true_mask8x32(self)
5753 }
5754 #[inline(always)]
5755 fn all_true(self) -> bool {
5756 self.simd.all_true_mask8x32(self)
5757 }
5758 #[inline(always)]
5759 fn any_false(self) -> bool {
5760 self.simd.any_false_mask8x32(self)
5761 }
5762 #[inline(always)]
5763 fn all_false(self) -> bool {
5764 self.simd.all_false_mask8x32(self)
5765 }
5766}
5767impl<S: Simd> MaskWiden<S> for mask8x32<S> {
5768 type Widened = mask16x16<S>;
5769 #[inline(always)]
5770 fn widen(self) -> (Self::Widened, Self::Widened) {
5771 self.simd.widen_mask8x32(self)
5772 }
5773}
5774impl<S: Simd> ExtractToken for i16x16<S> {
5775 type S = S;
5776 #[inline]
5777 fn token(&self) -> S {
5778 self.simd
5779 }
5780}
5781#[doc = "A SIMD vector of 16 [`i16`] elements.\n\nThis type's memory layout is identical to that of [`[i16; 16]`](prim@array), except that it is aligned to 32 bytes.\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```"]
5782#[derive(Clone, Copy)]
5783#[repr(C, align(32))]
5784pub struct i16x16<S: Simd> {
5785 pub(crate) val: S::i16x16,
5786 pub simd: S,
5787}
5788impl<S: Simd> Seal for i16x16<S> {}
5789impl<S: Simd> SimdFrom<[i16; 16], S> for i16x16<S> {
5790 #[inline(always)]
5791 fn simd_from(simd: S, val: [i16; 16]) -> Self {
5792 Self {
5793 val: crate::transmute::checked_transmute_copy(&val),
5794 simd,
5795 }
5796 }
5797}
5798impl<S: Simd> From<i16x16<S>> for [i16; 16] {
5799 #[inline(always)]
5800 fn from(value: i16x16<S>) -> Self {
5801 crate::transmute::checked_transmute_copy(&value.val)
5802 }
5803}
5804impl<S: Simd> core::ops::Deref for i16x16<S> {
5805 type Target = [i16; 16];
5806 #[inline(always)]
5807 fn deref(&self) -> &Self::Target {
5808 crate::transmute::checked_cast_ref(&self.val)
5809 }
5810}
5811impl<S: Simd> core::ops::DerefMut for i16x16<S> {
5812 #[inline(always)]
5813 fn deref_mut(&mut self) -> &mut Self::Target {
5814 crate::transmute::checked_cast_mut(&mut self.val)
5815 }
5816}
5817impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i16x16<S> {
5818 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5819 crate::support::simd_debug_impl(f, "i16x16", &self.simd, self.as_array())
5820 }
5821}
5822impl<S: Simd> SimdFrom<i16, S> for i16x16<S> {
5823 #[inline(always)]
5824 fn simd_from(simd: S, value: i16) -> Self {
5825 simd.splat_i16x16(value)
5826 }
5827}
5828impl<S: Simd> core::ops::Index<usize> for i16x16<S> {
5829 type Output = i16;
5830 #[inline(always)]
5831 fn index(&self, i: usize) -> &Self::Output {
5832 &self.as_array()[i]
5833 }
5834}
5835impl<S: Simd> core::ops::IndexMut<usize> for i16x16<S> {
5836 #[inline(always)]
5837 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
5838 &mut self.as_mut_array()[i]
5839 }
5840}
5841impl<S: Simd> Select<i16x16<S>> for mask16x16<S> {
5842 #[inline(always)]
5843 fn select(self, if_true: i16x16<S>, if_false: i16x16<S>) -> i16x16<S> {
5844 self.simd.select_i16x16(self, if_true, if_false)
5845 }
5846}
5847impl<S: Simd> Bytes for i16x16<S> {
5848 type Bytes = u8x32<S>;
5849 #[inline(always)]
5850 fn to_bytes(self) -> Self::Bytes {
5851 u8x32 {
5852 val: crate::transmute::checked_transmute_copy(&self.val),
5853 simd: self.simd,
5854 }
5855 }
5856 #[inline(always)]
5857 fn from_bytes(value: Self::Bytes) -> Self {
5858 Self {
5859 val: crate::transmute::checked_transmute_copy(&value.val),
5860 simd: value.simd,
5861 }
5862 }
5863}
5864impl<S: Simd> SimdBase<S> for i16x16<S> {
5865 type Element = i16;
5866 type ByteVector = u8x32<S>;
5867 const LEN: usize = 16;
5868 type Mask = mask16x16<S>;
5869 type Block = i16x8<S>;
5870 type Array = [i16; 16];
5871 #[inline(always)]
5872 fn as_slice(&self) -> &[i16] {
5873 self.as_array().as_slice()
5874 }
5875 #[inline(always)]
5876 fn as_mut_slice(&mut self) -> &mut [i16] {
5877 self.as_mut_array().as_mut_slice()
5878 }
5879 #[inline(always)]
5880 fn from_slice(simd: S, slice: &[i16]) -> Self {
5881 Self::load_array_ref(simd, slice.try_into().unwrap())
5882 }
5883 #[inline(always)]
5884 fn store_slice(&self, slice: &mut [i16]) {
5885 (*self).store_array(slice.try_into().unwrap());
5886 }
5887 #[inline(always)]
5888 fn splat(simd: S, val: i16) -> Self {
5889 simd.splat_i16x16(val)
5890 }
5891 #[inline(always)]
5892 fn block_splat(block: Self::Block) -> Self {
5893 block.simd.combine_i16x8(block, block)
5894 }
5895 #[inline(always)]
5896 fn from_fn(simd: S, mut f: impl FnMut(usize) -> i16) -> Self {
5897 Self::load_array(
5898 simd,
5899 [
5900 f(0usize),
5901 f(1usize),
5902 f(2usize),
5903 f(3usize),
5904 f(4usize),
5905 f(5usize),
5906 f(6usize),
5907 f(7usize),
5908 f(8usize),
5909 f(9usize),
5910 f(10usize),
5911 f(11usize),
5912 f(12usize),
5913 f(13usize),
5914 f(14usize),
5915 f(15usize),
5916 ],
5917 )
5918 }
5919 #[inline(always)]
5920 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
5921 self.simd
5922 .slide_i16x16::<SHIFT>(self, rhs.simd_into(self.simd))
5923 }
5924 #[inline(always)]
5925 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
5926 self.simd
5927 .slide_within_blocks_i16x16::<SHIFT>(self, rhs.simd_into(self.simd))
5928 }
5929 #[inline(always)]
5930 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
5931 self.simd
5932 .swizzle_dyn_within_blocks_i16x16(self, indices.simd_into(self.simd))
5933 }
5934 #[inline(always)]
5935 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
5936 self.simd
5937 .swizzle_dyn_i16x16(self, indices.simd_into(self.simd))
5938 }
5939 #[inline(always)]
5940 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
5941 self.simd
5942 .swizzle_dyn_precise_i16x16(self, indices.simd_into(self.simd))
5943 }
5944 #[inline(always)]
5945 fn abs(self) -> Self {
5946 self.simd.abs_i16x16(self)
5947 }
5948 #[inline(always)]
5949 fn reverse(self) -> Self {
5950 self.simd.reverse_i16x16(self)
5951 }
5952 #[inline(always)]
5953 fn concat_swizzle_dyn(
5954 self,
5955 rhs: impl SimdInto<Self, S>,
5956 indices: impl SimdInto<Self::Bytes, S>,
5957 ) -> Self {
5958 self.simd.concat_swizzle_dyn_i16x16(
5959 self,
5960 rhs.simd_into(self.simd),
5961 indices.simd_into(self.simd),
5962 )
5963 }
5964 #[inline(always)]
5965 fn concat_swizzle_dyn_precise(
5966 self,
5967 rhs: impl SimdInto<Self, S>,
5968 indices: impl SimdInto<Self::Bytes, S>,
5969 ) -> Self {
5970 self.simd.concat_swizzle_dyn_precise_i16x16(
5971 self,
5972 rhs.simd_into(self.simd),
5973 indices.simd_into(self.simd),
5974 )
5975 }
5976 #[inline(always)]
5977 fn compress(self, mask: Self::Mask) -> Self {
5978 self.simd.compress_i16x16(self, mask)
5979 }
5980 #[inline(always)]
5981 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
5982 self.simd
5983 .compress_merge_i16x16(self, mask, merge.simd_into(self.simd))
5984 }
5985 #[inline(always)]
5986 fn expand(self, mask: Self::Mask) -> Self {
5987 self.simd.expand_i16x16(self, mask)
5988 }
5989 #[inline(always)]
5990 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
5991 self.simd
5992 .expand_merge_i16x16(self, mask, merge.simd_into(self.simd))
5993 }
5994 #[inline(always)]
5995 fn reduce_max(self) -> Self::Element {
5996 self.simd.reduce_max_i16x16(self)
5997 }
5998 #[inline(always)]
5999 fn reduce_min(self) -> Self::Element {
6000 self.simd.reduce_min_i16x16(self)
6001 }
6002 #[inline(always)]
6003 fn reduce_max_precise(self) -> Self::Element {
6004 self.simd.reduce_max_i16x16(self)
6005 }
6006 #[inline(always)]
6007 fn reduce_min_precise(self) -> Self::Element {
6008 self.simd.reduce_min_i16x16(self)
6009 }
6010 #[inline(always)]
6011 fn reduce_sum(self) -> Self::Element {
6012 self.simd.reduce_sum_i16x16(self)
6013 }
6014 #[inline(always)]
6015 fn reduce_product(self) -> Self::Element {
6016 self.simd.reduce_product_i16x16(self)
6017 }
6018 #[inline(always)]
6019 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
6020 self.simd.max_i16x16(self, rhs.simd_into(self.simd))
6021 }
6022 #[inline(always)]
6023 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
6024 self.simd.min_i16x16(self, rhs.simd_into(self.simd))
6025 }
6026 #[inline(always)]
6027 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
6028 self.simd.max_i16x16(self, rhs.simd_into(self.simd))
6029 }
6030 #[inline(always)]
6031 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
6032 self.simd.min_i16x16(self, rhs.simd_into(self.simd))
6033 }
6034 #[inline(always)]
6035 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
6036 self.simd
6037 .clamp_i16x16(self, min.simd_into(self.simd), max.simd_into(self.simd))
6038 }
6039 #[inline(always)]
6040 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6041 self.simd.simd_eq_i16x16(self, rhs.simd_into(self.simd))
6042 }
6043 #[inline(always)]
6044 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6045 self.simd.simd_ne_i16x16(self, rhs.simd_into(self.simd))
6046 }
6047 #[inline(always)]
6048 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6049 self.simd.simd_lt_i16x16(self, rhs.simd_into(self.simd))
6050 }
6051 #[inline(always)]
6052 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6053 self.simd.simd_le_i16x16(self, rhs.simd_into(self.simd))
6054 }
6055 #[inline(always)]
6056 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6057 self.simd.simd_ge_i16x16(self, rhs.simd_into(self.simd))
6058 }
6059 #[inline(always)]
6060 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6061 self.simd.simd_gt_i16x16(self, rhs.simd_into(self.simd))
6062 }
6063 #[inline(always)]
6064 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
6065 self.simd.zip_low_i16x16(self, rhs.simd_into(self.simd))
6066 }
6067 #[inline(always)]
6068 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
6069 self.simd.zip_high_i16x16(self, rhs.simd_into(self.simd))
6070 }
6071 #[inline(always)]
6072 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
6073 self.simd.unzip_low_i16x16(self, rhs.simd_into(self.simd))
6074 }
6075 #[inline(always)]
6076 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
6077 self.simd.unzip_high_i16x16(self, rhs.simd_into(self.simd))
6078 }
6079 #[inline(always)]
6080 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
6081 self.simd.interleave_i16x16(self, rhs.simd_into(self.simd))
6082 }
6083 #[inline(always)]
6084 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
6085 self.simd
6086 .deinterleave_i16x16(self, rhs.simd_into(self.simd))
6087 }
6088}
6089impl<S: Simd> crate::SimdInt<S> for i16x16<S> {
6090 #[inline(always)]
6091 fn count_ones(self) -> Self {
6092 self.simd.count_ones_i16x16(self)
6093 }
6094 #[inline(always)]
6095 fn count_zeros(self) -> Self {
6096 self.simd.count_zeros_i16x16(self)
6097 }
6098 #[inline(always)]
6099 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
6100 self.simd
6101 .saturating_add_i16x16(self, rhs.simd_into(self.simd))
6102 }
6103 #[inline(always)]
6104 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
6105 self.simd
6106 .saturating_sub_i16x16(self, rhs.simd_into(self.simd))
6107 }
6108}
6109impl<S: Simd> SimdWiden<S> for i16x16<S> {
6110 type Widened = i32x8<S>;
6111 #[inline(always)]
6112 fn widen(self) -> (Self::Widened, Self::Widened) {
6113 self.simd.widen_i16x16(self)
6114 }
6115}
6116impl<S: Simd> SimdIntWiden<S> for i16x16<S> {
6117 #[inline(always)]
6118 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
6119 self.simd
6120 .widening_mul_i16x16(self, rhs.simd_into(self.simd))
6121 }
6122 #[inline(always)]
6123 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
6124 self.simd
6125 .widening_add_i16x16(self, rhs.simd_into(self.simd))
6126 }
6127 #[inline(always)]
6128 fn pairwise_widening_add(self) -> Self::Widened {
6129 self.simd.pairwise_widening_add_i16x16(self)
6130 }
6131 #[inline(always)]
6132 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
6133 self.simd
6134 .pairwise_dot_product_i16x16(self, rhs.simd_into(self.simd))
6135 }
6136}
6137impl<S: Simd> SimdNarrow<S> for i16x16<S> {
6138 type Narrowed = i8x32<S>;
6139 #[inline(always)]
6140 fn narrow(self, high: Self) -> Self::Narrowed {
6141 self.simd.narrow_i16x16(self, high)
6142 }
6143 #[inline(always)]
6144 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
6145 self.simd.saturating_narrow_i16x16(self, high)
6146 }
6147 #[inline(always)]
6148 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
6149 self.simd.relaxed_narrow_i16x16(self, high)
6150 }
6151}
6152impl<S: Simd> crate::SimdSplit<S> for i16x16<S> {
6153 type Split = i16x8<S>;
6154 #[inline(always)]
6155 fn split(self) -> (Self::Split, Self::Split) {
6156 self.simd.split_i16x16(self)
6157 }
6158}
6159impl<S: Simd> crate::SimdCombine<S> for i16x16<S> {
6160 type Combined = i16x32<S>;
6161 #[inline(always)]
6162 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
6163 self.simd.combine_i16x16(self, rhs.simd_into(self.simd))
6164 }
6165}
6166impl<S: Simd> ExtractToken for u16x16<S> {
6167 type S = S;
6168 #[inline]
6169 fn token(&self) -> S {
6170 self.simd
6171 }
6172}
6173#[doc = "A SIMD vector of 16 [`u16`] elements.\n\nThis type's memory layout is identical to that of [`[u16; 16]`](prim@array), except that it is aligned to 32 bytes.\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```"]
6174#[derive(Clone, Copy)]
6175#[repr(C, align(32))]
6176pub struct u16x16<S: Simd> {
6177 pub(crate) val: S::u16x16,
6178 pub simd: S,
6179}
6180impl<S: Simd> Seal for u16x16<S> {}
6181impl<S: Simd> SimdFrom<[u16; 16], S> for u16x16<S> {
6182 #[inline(always)]
6183 fn simd_from(simd: S, val: [u16; 16]) -> Self {
6184 Self {
6185 val: crate::transmute::checked_transmute_copy(&val),
6186 simd,
6187 }
6188 }
6189}
6190impl<S: Simd> From<u16x16<S>> for [u16; 16] {
6191 #[inline(always)]
6192 fn from(value: u16x16<S>) -> Self {
6193 crate::transmute::checked_transmute_copy(&value.val)
6194 }
6195}
6196impl<S: Simd> core::ops::Deref for u16x16<S> {
6197 type Target = [u16; 16];
6198 #[inline(always)]
6199 fn deref(&self) -> &Self::Target {
6200 crate::transmute::checked_cast_ref(&self.val)
6201 }
6202}
6203impl<S: Simd> core::ops::DerefMut for u16x16<S> {
6204 #[inline(always)]
6205 fn deref_mut(&mut self) -> &mut Self::Target {
6206 crate::transmute::checked_cast_mut(&mut self.val)
6207 }
6208}
6209impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u16x16<S> {
6210 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
6211 crate::support::simd_debug_impl(f, "u16x16", &self.simd, self.as_array())
6212 }
6213}
6214impl<S: Simd> SimdFrom<u16, S> for u16x16<S> {
6215 #[inline(always)]
6216 fn simd_from(simd: S, value: u16) -> Self {
6217 simd.splat_u16x16(value)
6218 }
6219}
6220impl<S: Simd> core::ops::Index<usize> for u16x16<S> {
6221 type Output = u16;
6222 #[inline(always)]
6223 fn index(&self, i: usize) -> &Self::Output {
6224 &self.as_array()[i]
6225 }
6226}
6227impl<S: Simd> core::ops::IndexMut<usize> for u16x16<S> {
6228 #[inline(always)]
6229 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
6230 &mut self.as_mut_array()[i]
6231 }
6232}
6233impl<S: Simd> Select<u16x16<S>> for mask16x16<S> {
6234 #[inline(always)]
6235 fn select(self, if_true: u16x16<S>, if_false: u16x16<S>) -> u16x16<S> {
6236 self.simd.select_u16x16(self, if_true, if_false)
6237 }
6238}
6239impl<S: Simd> Bytes for u16x16<S> {
6240 type Bytes = u8x32<S>;
6241 #[inline(always)]
6242 fn to_bytes(self) -> Self::Bytes {
6243 u8x32 {
6244 val: crate::transmute::checked_transmute_copy(&self.val),
6245 simd: self.simd,
6246 }
6247 }
6248 #[inline(always)]
6249 fn from_bytes(value: Self::Bytes) -> Self {
6250 Self {
6251 val: crate::transmute::checked_transmute_copy(&value.val),
6252 simd: value.simd,
6253 }
6254 }
6255}
6256impl<S: Simd> SimdBase<S> for u16x16<S> {
6257 type Element = u16;
6258 type ByteVector = u8x32<S>;
6259 const LEN: usize = 16;
6260 type Mask = mask16x16<S>;
6261 type Block = u16x8<S>;
6262 type Array = [u16; 16];
6263 #[inline(always)]
6264 fn as_slice(&self) -> &[u16] {
6265 self.as_array().as_slice()
6266 }
6267 #[inline(always)]
6268 fn as_mut_slice(&mut self) -> &mut [u16] {
6269 self.as_mut_array().as_mut_slice()
6270 }
6271 #[inline(always)]
6272 fn from_slice(simd: S, slice: &[u16]) -> Self {
6273 Self::load_array_ref(simd, slice.try_into().unwrap())
6274 }
6275 #[inline(always)]
6276 fn store_slice(&self, slice: &mut [u16]) {
6277 (*self).store_array(slice.try_into().unwrap());
6278 }
6279 #[inline(always)]
6280 fn splat(simd: S, val: u16) -> Self {
6281 simd.splat_u16x16(val)
6282 }
6283 #[inline(always)]
6284 fn block_splat(block: Self::Block) -> Self {
6285 block.simd.combine_u16x8(block, block)
6286 }
6287 #[inline(always)]
6288 fn from_fn(simd: S, mut f: impl FnMut(usize) -> u16) -> Self {
6289 Self::load_array(
6290 simd,
6291 [
6292 f(0usize),
6293 f(1usize),
6294 f(2usize),
6295 f(3usize),
6296 f(4usize),
6297 f(5usize),
6298 f(6usize),
6299 f(7usize),
6300 f(8usize),
6301 f(9usize),
6302 f(10usize),
6303 f(11usize),
6304 f(12usize),
6305 f(13usize),
6306 f(14usize),
6307 f(15usize),
6308 ],
6309 )
6310 }
6311 #[inline(always)]
6312 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
6313 self.simd
6314 .slide_u16x16::<SHIFT>(self, rhs.simd_into(self.simd))
6315 }
6316 #[inline(always)]
6317 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
6318 self.simd
6319 .slide_within_blocks_u16x16::<SHIFT>(self, rhs.simd_into(self.simd))
6320 }
6321 #[inline(always)]
6322 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
6323 self.simd
6324 .swizzle_dyn_within_blocks_u16x16(self, indices.simd_into(self.simd))
6325 }
6326 #[inline(always)]
6327 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
6328 self.simd
6329 .swizzle_dyn_u16x16(self, indices.simd_into(self.simd))
6330 }
6331 #[inline(always)]
6332 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
6333 self.simd
6334 .swizzle_dyn_precise_u16x16(self, indices.simd_into(self.simd))
6335 }
6336 #[inline(always)]
6337 fn abs(self) -> Self {
6338 self.simd.abs_u16x16(self)
6339 }
6340 #[inline(always)]
6341 fn reverse(self) -> Self {
6342 self.simd.reverse_u16x16(self)
6343 }
6344 #[inline(always)]
6345 fn concat_swizzle_dyn(
6346 self,
6347 rhs: impl SimdInto<Self, S>,
6348 indices: impl SimdInto<Self::Bytes, S>,
6349 ) -> Self {
6350 self.simd.concat_swizzle_dyn_u16x16(
6351 self,
6352 rhs.simd_into(self.simd),
6353 indices.simd_into(self.simd),
6354 )
6355 }
6356 #[inline(always)]
6357 fn concat_swizzle_dyn_precise(
6358 self,
6359 rhs: impl SimdInto<Self, S>,
6360 indices: impl SimdInto<Self::Bytes, S>,
6361 ) -> Self {
6362 self.simd.concat_swizzle_dyn_precise_u16x16(
6363 self,
6364 rhs.simd_into(self.simd),
6365 indices.simd_into(self.simd),
6366 )
6367 }
6368 #[inline(always)]
6369 fn compress(self, mask: Self::Mask) -> Self {
6370 self.simd.compress_u16x16(self, mask)
6371 }
6372 #[inline(always)]
6373 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
6374 self.simd
6375 .compress_merge_u16x16(self, mask, merge.simd_into(self.simd))
6376 }
6377 #[inline(always)]
6378 fn expand(self, mask: Self::Mask) -> Self {
6379 self.simd.expand_u16x16(self, mask)
6380 }
6381 #[inline(always)]
6382 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
6383 self.simd
6384 .expand_merge_u16x16(self, mask, merge.simd_into(self.simd))
6385 }
6386 #[inline(always)]
6387 fn reduce_max(self) -> Self::Element {
6388 self.simd.reduce_max_u16x16(self)
6389 }
6390 #[inline(always)]
6391 fn reduce_min(self) -> Self::Element {
6392 self.simd.reduce_min_u16x16(self)
6393 }
6394 #[inline(always)]
6395 fn reduce_max_precise(self) -> Self::Element {
6396 self.simd.reduce_max_u16x16(self)
6397 }
6398 #[inline(always)]
6399 fn reduce_min_precise(self) -> Self::Element {
6400 self.simd.reduce_min_u16x16(self)
6401 }
6402 #[inline(always)]
6403 fn reduce_sum(self) -> Self::Element {
6404 self.simd.reduce_sum_u16x16(self)
6405 }
6406 #[inline(always)]
6407 fn reduce_product(self) -> Self::Element {
6408 self.simd.reduce_product_u16x16(self)
6409 }
6410 #[inline(always)]
6411 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
6412 self.simd.max_u16x16(self, rhs.simd_into(self.simd))
6413 }
6414 #[inline(always)]
6415 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
6416 self.simd.min_u16x16(self, rhs.simd_into(self.simd))
6417 }
6418 #[inline(always)]
6419 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
6420 self.simd.max_u16x16(self, rhs.simd_into(self.simd))
6421 }
6422 #[inline(always)]
6423 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
6424 self.simd.min_u16x16(self, rhs.simd_into(self.simd))
6425 }
6426 #[inline(always)]
6427 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
6428 self.simd
6429 .clamp_u16x16(self, min.simd_into(self.simd), max.simd_into(self.simd))
6430 }
6431 #[inline(always)]
6432 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6433 self.simd.simd_eq_u16x16(self, rhs.simd_into(self.simd))
6434 }
6435 #[inline(always)]
6436 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6437 self.simd.simd_ne_u16x16(self, rhs.simd_into(self.simd))
6438 }
6439 #[inline(always)]
6440 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6441 self.simd.simd_lt_u16x16(self, rhs.simd_into(self.simd))
6442 }
6443 #[inline(always)]
6444 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6445 self.simd.simd_le_u16x16(self, rhs.simd_into(self.simd))
6446 }
6447 #[inline(always)]
6448 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6449 self.simd.simd_ge_u16x16(self, rhs.simd_into(self.simd))
6450 }
6451 #[inline(always)]
6452 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6453 self.simd.simd_gt_u16x16(self, rhs.simd_into(self.simd))
6454 }
6455 #[inline(always)]
6456 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
6457 self.simd.zip_low_u16x16(self, rhs.simd_into(self.simd))
6458 }
6459 #[inline(always)]
6460 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
6461 self.simd.zip_high_u16x16(self, rhs.simd_into(self.simd))
6462 }
6463 #[inline(always)]
6464 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
6465 self.simd.unzip_low_u16x16(self, rhs.simd_into(self.simd))
6466 }
6467 #[inline(always)]
6468 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
6469 self.simd.unzip_high_u16x16(self, rhs.simd_into(self.simd))
6470 }
6471 #[inline(always)]
6472 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
6473 self.simd.interleave_u16x16(self, rhs.simd_into(self.simd))
6474 }
6475 #[inline(always)]
6476 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
6477 self.simd
6478 .deinterleave_u16x16(self, rhs.simd_into(self.simd))
6479 }
6480}
6481impl<S: Simd> crate::SimdInt<S> for u16x16<S> {
6482 #[inline(always)]
6483 fn count_ones(self) -> Self {
6484 self.simd.count_ones_u16x16(self)
6485 }
6486 #[inline(always)]
6487 fn count_zeros(self) -> Self {
6488 self.simd.count_zeros_u16x16(self)
6489 }
6490 #[inline(always)]
6491 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
6492 self.simd
6493 .saturating_add_u16x16(self, rhs.simd_into(self.simd))
6494 }
6495 #[inline(always)]
6496 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
6497 self.simd
6498 .saturating_sub_u16x16(self, rhs.simd_into(self.simd))
6499 }
6500}
6501impl<S: Simd> SimdWiden<S> for u16x16<S> {
6502 type Widened = u32x8<S>;
6503 #[inline(always)]
6504 fn widen(self) -> (Self::Widened, Self::Widened) {
6505 self.simd.widen_u16x16(self)
6506 }
6507}
6508impl<S: Simd> SimdIntWiden<S> for u16x16<S> {
6509 #[inline(always)]
6510 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
6511 self.simd
6512 .widening_mul_u16x16(self, rhs.simd_into(self.simd))
6513 }
6514 #[inline(always)]
6515 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
6516 self.simd
6517 .widening_add_u16x16(self, rhs.simd_into(self.simd))
6518 }
6519 #[inline(always)]
6520 fn pairwise_widening_add(self) -> Self::Widened {
6521 self.simd.pairwise_widening_add_u16x16(self)
6522 }
6523 #[inline(always)]
6524 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
6525 self.simd
6526 .pairwise_dot_product_u16x16(self, rhs.simd_into(self.simd))
6527 }
6528}
6529impl<S: Simd> SimdNarrow<S> for u16x16<S> {
6530 type Narrowed = u8x32<S>;
6531 #[inline(always)]
6532 fn narrow(self, high: Self) -> Self::Narrowed {
6533 self.simd.narrow_u16x16(self, high)
6534 }
6535 #[inline(always)]
6536 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
6537 self.simd.saturating_narrow_u16x16(self, high)
6538 }
6539 #[inline(always)]
6540 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
6541 self.simd.relaxed_narrow_u16x16(self, high)
6542 }
6543}
6544impl<S: Simd> crate::SimdSplit<S> for u16x16<S> {
6545 type Split = u16x8<S>;
6546 #[inline(always)]
6547 fn split(self) -> (Self::Split, Self::Split) {
6548 self.simd.split_u16x16(self)
6549 }
6550}
6551impl<S: Simd> crate::SimdCombine<S> for u16x16<S> {
6552 type Combined = u16x32<S>;
6553 #[inline(always)]
6554 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
6555 self.simd.combine_u16x16(self, rhs.simd_into(self.simd))
6556 }
6557}
6558impl<S: Simd> ExtractToken for mask16x16<S> {
6559 type S = S;
6560 #[inline]
6561 fn token(&self) -> S {
6562 self.simd
6563 }
6564}
6565#[doc = "A SIMD mask of 16 logical lanes corresponding to 16-bit vector elements.\n\nThe storage representation of this type is intentionally opaque and may vary depending on the SIMD level.\n\nYou can construct this mask type using the [`Self::splat`], [`Self::from_bitmask`], [`Self::from_slice`], and [`Self::simd_from`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, mask16x16};\nfn construct_mask<S: Simd>(simd: S) {\n // From a single boolean value:\n let a = mask16x16::splat(simd, true);\n let b = mask16x16::simd_from(simd, true);\n\n // From signed integer mask lanes:\n let c = mask16x16::from_slice(simd, &[-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);\n let d = mask16x16::simd_from(simd, [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);\n\n // From a compact bitmask (same mask as above, least significant bit maps to lane 0):\n let e = mask16x16::from_bitmask(simd, 0b0001);\n\n // By setting individual lanes:\n let mut f = mask16x16::splat(simd, false);\n f.set(0, true);\n}\n```"]
6566#[derive(Clone, Copy)]
6567pub struct mask16x16<S: Simd> {
6568 pub(crate) val: S::mask16x16,
6569 pub(crate) simd: S,
6570}
6571impl<S: Simd> Seal for mask16x16<S> {}
6572impl<S: Simd> SimdFrom<[i16; 16], S> for mask16x16<S> {
6573 #[inline(always)]
6574 fn simd_from(simd: S, val: [i16; 16]) -> Self {
6575 Self {
6576 val: <S as crate::arch_types::ArchTypes>::mask16x16_from_array(simd, val),
6577 simd,
6578 }
6579 }
6580}
6581impl<S: Simd> From<mask16x16<S>> for [i16; 16] {
6582 #[inline(always)]
6583 fn from(value: mask16x16<S>) -> Self {
6584 <S as crate::arch_types::ArchTypes>::mask16x16_to_array(value.simd, value.val)
6585 }
6586}
6587impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask16x16<S> {
6588 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
6589 let lanes: [i16; 16] = (*self).into();
6590 crate::support::simd_debug_impl(f, "mask16x16", &self.simd, &lanes)
6591 }
6592}
6593impl<S: Simd> SimdFrom<bool, S> for mask16x16<S> {
6594 #[inline(always)]
6595 fn simd_from(simd: S, value: bool) -> Self {
6596 simd.splat_mask16x16(value)
6597 }
6598}
6599impl<S: Simd> Select<mask16x16<S>> for mask16x16<S> {
6600 #[inline(always)]
6601 fn select(self, if_true: mask16x16<S>, if_false: mask16x16<S>) -> mask16x16<S> {
6602 self.simd.select_mask16x16(self, if_true, if_false)
6603 }
6604}
6605impl<S: Simd> SimdMask<S> for mask16x16<S> {
6606 type Element = i16;
6607 type Ints = i16x16<S>;
6608 const LEN: usize = 16;
6609 #[inline(always)]
6610 fn splat(simd: S, val: bool) -> Self {
6611 simd.splat_mask16x16(val)
6612 }
6613 #[inline(always)]
6614 fn from_bitmask(simd: S, bits: u64) -> Self {
6615 simd.from_bitmask_mask16x16(bits)
6616 }
6617 #[inline(always)]
6618 fn to_bitmask(self) -> u64 {
6619 self.simd.to_bitmask_mask16x16(self)
6620 }
6621 #[inline(always)]
6622 fn from_vector(vector: Self::Ints) -> Self {
6623 vector.token().from_vector_mask16x16(vector)
6624 }
6625 #[inline(always)]
6626 fn to_vector(self) -> Self::Ints {
6627 self.simd.to_vector_mask16x16(self)
6628 }
6629 #[inline(always)]
6630 fn set(&mut self, index: usize, value: bool) {
6631 self.simd.set_mask16x16(self, index, value);
6632 }
6633 #[inline(always)]
6634 fn from_slice(simd: S, slice: &[i16]) -> Self {
6635 let slice: &[i16; 16] = slice.try_into().unwrap();
6636 Self::simd_from(simd, *slice)
6637 }
6638 #[inline(always)]
6639 fn store_slice(&self, slice: &mut [i16]) {
6640 let slice: &mut [i16; 16] = slice.try_into().unwrap();
6641 *slice = (*self).into();
6642 }
6643 #[inline(always)]
6644 fn rotate_elements_left<const OFFSET: usize>(self) -> Self {
6645 self.simd.rotate_elements_left_mask16x16::<OFFSET>(self)
6646 }
6647 #[inline(always)]
6648 fn rotate_elements_right<const OFFSET: usize>(self) -> Self {
6649 self.simd.rotate_elements_right_mask16x16::<OFFSET>(self)
6650 }
6651 #[inline(always)]
6652 fn reverse(self) -> Self {
6653 self.simd.reverse_mask16x16(self)
6654 }
6655 #[inline(always)]
6656 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self {
6657 self.simd.simd_eq_mask16x16(self, rhs.simd_into(self.simd))
6658 }
6659 #[inline(always)]
6660 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self {
6661 self.simd.simd_ne_mask16x16(self, rhs.simd_into(self.simd))
6662 }
6663 #[inline(always)]
6664 fn any_true(self) -> bool {
6665 self.simd.any_true_mask16x16(self)
6666 }
6667 #[inline(always)]
6668 fn all_true(self) -> bool {
6669 self.simd.all_true_mask16x16(self)
6670 }
6671 #[inline(always)]
6672 fn any_false(self) -> bool {
6673 self.simd.any_false_mask16x16(self)
6674 }
6675 #[inline(always)]
6676 fn all_false(self) -> bool {
6677 self.simd.all_false_mask16x16(self)
6678 }
6679}
6680impl<S: Simd> MaskWiden<S> for mask16x16<S> {
6681 type Widened = mask32x8<S>;
6682 #[inline(always)]
6683 fn widen(self) -> (Self::Widened, Self::Widened) {
6684 self.simd.widen_mask16x16(self)
6685 }
6686}
6687impl<S: Simd> MaskNarrow<S> for mask16x16<S> {
6688 type Narrowed = mask8x32<S>;
6689 #[inline(always)]
6690 fn narrow(self, high: Self) -> Self::Narrowed {
6691 self.simd.narrow_mask16x16(self, high)
6692 }
6693}
6694impl<S: Simd> ExtractToken for i32x8<S> {
6695 type S = S;
6696 #[inline]
6697 fn token(&self) -> S {
6698 self.simd
6699 }
6700}
6701#[doc = "A SIMD vector of 8 [`i32`] elements.\n\nThis type's memory layout is identical to that of [`[i32; 8]`](prim@array), except that it is aligned to 32 bytes.\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```"]
6702#[derive(Clone, Copy)]
6703#[repr(C, align(32))]
6704pub struct i32x8<S: Simd> {
6705 pub(crate) val: S::i32x8,
6706 pub simd: S,
6707}
6708impl<S: Simd> Seal for i32x8<S> {}
6709impl<S: Simd> SimdFrom<[i32; 8], S> for i32x8<S> {
6710 #[inline(always)]
6711 fn simd_from(simd: S, val: [i32; 8]) -> Self {
6712 Self {
6713 val: crate::transmute::checked_transmute_copy(&val),
6714 simd,
6715 }
6716 }
6717}
6718impl<S: Simd> From<i32x8<S>> for [i32; 8] {
6719 #[inline(always)]
6720 fn from(value: i32x8<S>) -> Self {
6721 crate::transmute::checked_transmute_copy(&value.val)
6722 }
6723}
6724impl<S: Simd> core::ops::Deref for i32x8<S> {
6725 type Target = [i32; 8];
6726 #[inline(always)]
6727 fn deref(&self) -> &Self::Target {
6728 crate::transmute::checked_cast_ref(&self.val)
6729 }
6730}
6731impl<S: Simd> core::ops::DerefMut for i32x8<S> {
6732 #[inline(always)]
6733 fn deref_mut(&mut self) -> &mut Self::Target {
6734 crate::transmute::checked_cast_mut(&mut self.val)
6735 }
6736}
6737impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i32x8<S> {
6738 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
6739 crate::support::simd_debug_impl(f, "i32x8", &self.simd, self.as_array())
6740 }
6741}
6742impl<S: Simd> SimdFrom<i32, S> for i32x8<S> {
6743 #[inline(always)]
6744 fn simd_from(simd: S, value: i32) -> Self {
6745 simd.splat_i32x8(value)
6746 }
6747}
6748impl<S: Simd> core::ops::Index<usize> for i32x8<S> {
6749 type Output = i32;
6750 #[inline(always)]
6751 fn index(&self, i: usize) -> &Self::Output {
6752 &self.as_array()[i]
6753 }
6754}
6755impl<S: Simd> core::ops::IndexMut<usize> for i32x8<S> {
6756 #[inline(always)]
6757 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
6758 &mut self.as_mut_array()[i]
6759 }
6760}
6761impl<S: Simd> Select<i32x8<S>> for mask32x8<S> {
6762 #[inline(always)]
6763 fn select(self, if_true: i32x8<S>, if_false: i32x8<S>) -> i32x8<S> {
6764 self.simd.select_i32x8(self, if_true, if_false)
6765 }
6766}
6767impl<S: Simd> Bytes for i32x8<S> {
6768 type Bytes = u8x32<S>;
6769 #[inline(always)]
6770 fn to_bytes(self) -> Self::Bytes {
6771 u8x32 {
6772 val: crate::transmute::checked_transmute_copy(&self.val),
6773 simd: self.simd,
6774 }
6775 }
6776 #[inline(always)]
6777 fn from_bytes(value: Self::Bytes) -> Self {
6778 Self {
6779 val: crate::transmute::checked_transmute_copy(&value.val),
6780 simd: value.simd,
6781 }
6782 }
6783}
6784impl<S: Simd> SimdBase<S> for i32x8<S> {
6785 type Element = i32;
6786 type ByteVector = u8x32<S>;
6787 const LEN: usize = 8;
6788 type Mask = mask32x8<S>;
6789 type Block = i32x4<S>;
6790 type Array = [i32; 8];
6791 #[inline(always)]
6792 fn as_slice(&self) -> &[i32] {
6793 self.as_array().as_slice()
6794 }
6795 #[inline(always)]
6796 fn as_mut_slice(&mut self) -> &mut [i32] {
6797 self.as_mut_array().as_mut_slice()
6798 }
6799 #[inline(always)]
6800 fn from_slice(simd: S, slice: &[i32]) -> Self {
6801 Self::load_array_ref(simd, slice.try_into().unwrap())
6802 }
6803 #[inline(always)]
6804 fn store_slice(&self, slice: &mut [i32]) {
6805 (*self).store_array(slice.try_into().unwrap());
6806 }
6807 #[inline(always)]
6808 fn splat(simd: S, val: i32) -> Self {
6809 simd.splat_i32x8(val)
6810 }
6811 #[inline(always)]
6812 fn block_splat(block: Self::Block) -> Self {
6813 block.simd.combine_i32x4(block, block)
6814 }
6815 #[inline(always)]
6816 fn from_fn(simd: S, mut f: impl FnMut(usize) -> i32) -> Self {
6817 Self::load_array(
6818 simd,
6819 [
6820 f(0usize),
6821 f(1usize),
6822 f(2usize),
6823 f(3usize),
6824 f(4usize),
6825 f(5usize),
6826 f(6usize),
6827 f(7usize),
6828 ],
6829 )
6830 }
6831 #[inline(always)]
6832 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
6833 self.simd
6834 .slide_i32x8::<SHIFT>(self, rhs.simd_into(self.simd))
6835 }
6836 #[inline(always)]
6837 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
6838 self.simd
6839 .slide_within_blocks_i32x8::<SHIFT>(self, rhs.simd_into(self.simd))
6840 }
6841 #[inline(always)]
6842 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
6843 self.simd
6844 .swizzle_dyn_within_blocks_i32x8(self, indices.simd_into(self.simd))
6845 }
6846 #[inline(always)]
6847 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
6848 self.simd
6849 .swizzle_dyn_i32x8(self, indices.simd_into(self.simd))
6850 }
6851 #[inline(always)]
6852 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
6853 self.simd
6854 .swizzle_dyn_precise_i32x8(self, indices.simd_into(self.simd))
6855 }
6856 #[inline(always)]
6857 fn abs(self) -> Self {
6858 self.simd.abs_i32x8(self)
6859 }
6860 #[inline(always)]
6861 fn reverse(self) -> Self {
6862 self.simd.reverse_i32x8(self)
6863 }
6864 #[inline(always)]
6865 fn concat_swizzle_dyn(
6866 self,
6867 rhs: impl SimdInto<Self, S>,
6868 indices: impl SimdInto<Self::Bytes, S>,
6869 ) -> Self {
6870 self.simd.concat_swizzle_dyn_i32x8(
6871 self,
6872 rhs.simd_into(self.simd),
6873 indices.simd_into(self.simd),
6874 )
6875 }
6876 #[inline(always)]
6877 fn concat_swizzle_dyn_precise(
6878 self,
6879 rhs: impl SimdInto<Self, S>,
6880 indices: impl SimdInto<Self::Bytes, S>,
6881 ) -> Self {
6882 self.simd.concat_swizzle_dyn_precise_i32x8(
6883 self,
6884 rhs.simd_into(self.simd),
6885 indices.simd_into(self.simd),
6886 )
6887 }
6888 #[inline(always)]
6889 fn compress(self, mask: Self::Mask) -> Self {
6890 self.simd.compress_i32x8(self, mask)
6891 }
6892 #[inline(always)]
6893 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
6894 self.simd
6895 .compress_merge_i32x8(self, mask, merge.simd_into(self.simd))
6896 }
6897 #[inline(always)]
6898 fn expand(self, mask: Self::Mask) -> Self {
6899 self.simd.expand_i32x8(self, mask)
6900 }
6901 #[inline(always)]
6902 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
6903 self.simd
6904 .expand_merge_i32x8(self, mask, merge.simd_into(self.simd))
6905 }
6906 #[inline(always)]
6907 fn reduce_max(self) -> Self::Element {
6908 self.simd.reduce_max_i32x8(self)
6909 }
6910 #[inline(always)]
6911 fn reduce_min(self) -> Self::Element {
6912 self.simd.reduce_min_i32x8(self)
6913 }
6914 #[inline(always)]
6915 fn reduce_max_precise(self) -> Self::Element {
6916 self.simd.reduce_max_i32x8(self)
6917 }
6918 #[inline(always)]
6919 fn reduce_min_precise(self) -> Self::Element {
6920 self.simd.reduce_min_i32x8(self)
6921 }
6922 #[inline(always)]
6923 fn reduce_sum(self) -> Self::Element {
6924 self.simd.reduce_sum_i32x8(self)
6925 }
6926 #[inline(always)]
6927 fn reduce_product(self) -> Self::Element {
6928 self.simd.reduce_product_i32x8(self)
6929 }
6930 #[inline(always)]
6931 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
6932 self.simd.max_i32x8(self, rhs.simd_into(self.simd))
6933 }
6934 #[inline(always)]
6935 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
6936 self.simd.min_i32x8(self, rhs.simd_into(self.simd))
6937 }
6938 #[inline(always)]
6939 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
6940 self.simd.max_i32x8(self, rhs.simd_into(self.simd))
6941 }
6942 #[inline(always)]
6943 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
6944 self.simd.min_i32x8(self, rhs.simd_into(self.simd))
6945 }
6946 #[inline(always)]
6947 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
6948 self.simd
6949 .clamp_i32x8(self, min.simd_into(self.simd), max.simd_into(self.simd))
6950 }
6951 #[inline(always)]
6952 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6953 self.simd.simd_eq_i32x8(self, rhs.simd_into(self.simd))
6954 }
6955 #[inline(always)]
6956 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6957 self.simd.simd_ne_i32x8(self, rhs.simd_into(self.simd))
6958 }
6959 #[inline(always)]
6960 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6961 self.simd.simd_lt_i32x8(self, rhs.simd_into(self.simd))
6962 }
6963 #[inline(always)]
6964 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6965 self.simd.simd_le_i32x8(self, rhs.simd_into(self.simd))
6966 }
6967 #[inline(always)]
6968 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6969 self.simd.simd_ge_i32x8(self, rhs.simd_into(self.simd))
6970 }
6971 #[inline(always)]
6972 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
6973 self.simd.simd_gt_i32x8(self, rhs.simd_into(self.simd))
6974 }
6975 #[inline(always)]
6976 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
6977 self.simd.zip_low_i32x8(self, rhs.simd_into(self.simd))
6978 }
6979 #[inline(always)]
6980 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
6981 self.simd.zip_high_i32x8(self, rhs.simd_into(self.simd))
6982 }
6983 #[inline(always)]
6984 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
6985 self.simd.unzip_low_i32x8(self, rhs.simd_into(self.simd))
6986 }
6987 #[inline(always)]
6988 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
6989 self.simd.unzip_high_i32x8(self, rhs.simd_into(self.simd))
6990 }
6991 #[inline(always)]
6992 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
6993 self.simd.interleave_i32x8(self, rhs.simd_into(self.simd))
6994 }
6995 #[inline(always)]
6996 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
6997 self.simd.deinterleave_i32x8(self, rhs.simd_into(self.simd))
6998 }
6999}
7000impl<S: Simd> crate::SimdInt<S> for i32x8<S> {
7001 #[inline(always)]
7002 fn count_ones(self) -> Self {
7003 self.simd.count_ones_i32x8(self)
7004 }
7005 #[inline(always)]
7006 fn count_zeros(self) -> Self {
7007 self.simd.count_zeros_i32x8(self)
7008 }
7009 #[inline(always)]
7010 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
7011 self.simd
7012 .saturating_add_i32x8(self, rhs.simd_into(self.simd))
7013 }
7014 #[inline(always)]
7015 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
7016 self.simd
7017 .saturating_sub_i32x8(self, rhs.simd_into(self.simd))
7018 }
7019}
7020impl<S: Simd> SimdCvtTruncate<f32x8<S>> for i32x8<S> {
7021 #[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."]
7022 #[inline(always)]
7023 fn truncate_from(x: f32x8<S>) -> Self {
7024 x.simd.cvt_i32_f32x8(x)
7025 }
7026 #[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."]
7027 #[inline(always)]
7028 fn truncate_from_precise(x: f32x8<S>) -> Self {
7029 x.simd.cvt_i32_precise_f32x8(x)
7030 }
7031}
7032impl<S: Simd> SimdWiden<S> for i32x8<S> {
7033 type Widened = i64x4<S>;
7034 #[inline(always)]
7035 fn widen(self) -> (Self::Widened, Self::Widened) {
7036 self.simd.widen_i32x8(self)
7037 }
7038}
7039impl<S: Simd> SimdIntWiden<S> for i32x8<S> {
7040 #[inline(always)]
7041 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
7042 self.simd.widening_mul_i32x8(self, rhs.simd_into(self.simd))
7043 }
7044 #[inline(always)]
7045 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
7046 self.simd.widening_add_i32x8(self, rhs.simd_into(self.simd))
7047 }
7048 #[inline(always)]
7049 fn pairwise_widening_add(self) -> Self::Widened {
7050 self.simd.pairwise_widening_add_i32x8(self)
7051 }
7052 #[inline(always)]
7053 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
7054 self.simd
7055 .pairwise_dot_product_i32x8(self, rhs.simd_into(self.simd))
7056 }
7057}
7058impl<S: Simd> SimdNarrow<S> for i32x8<S> {
7059 type Narrowed = i16x16<S>;
7060 #[inline(always)]
7061 fn narrow(self, high: Self) -> Self::Narrowed {
7062 self.simd.narrow_i32x8(self, high)
7063 }
7064 #[inline(always)]
7065 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
7066 self.simd.saturating_narrow_i32x8(self, high)
7067 }
7068 #[inline(always)]
7069 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
7070 self.simd.relaxed_narrow_i32x8(self, high)
7071 }
7072}
7073impl<S: Simd> crate::SimdSplit<S> for i32x8<S> {
7074 type Split = i32x4<S>;
7075 #[inline(always)]
7076 fn split(self) -> (Self::Split, Self::Split) {
7077 self.simd.split_i32x8(self)
7078 }
7079}
7080impl<S: Simd> crate::SimdCombine<S> for i32x8<S> {
7081 type Combined = i32x16<S>;
7082 #[inline(always)]
7083 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
7084 self.simd.combine_i32x8(self, rhs.simd_into(self.simd))
7085 }
7086}
7087impl<S: Simd> ExtractToken for u32x8<S> {
7088 type S = S;
7089 #[inline]
7090 fn token(&self) -> S {
7091 self.simd
7092 }
7093}
7094#[doc = "A SIMD vector of 8 [`u32`] elements.\n\nThis type's memory layout is identical to that of [`[u32; 8]`](prim@array), except that it is aligned to 32 bytes.\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```"]
7095#[derive(Clone, Copy)]
7096#[repr(C, align(32))]
7097pub struct u32x8<S: Simd> {
7098 pub(crate) val: S::u32x8,
7099 pub simd: S,
7100}
7101impl<S: Simd> Seal for u32x8<S> {}
7102impl<S: Simd> SimdFrom<[u32; 8], S> for u32x8<S> {
7103 #[inline(always)]
7104 fn simd_from(simd: S, val: [u32; 8]) -> Self {
7105 Self {
7106 val: crate::transmute::checked_transmute_copy(&val),
7107 simd,
7108 }
7109 }
7110}
7111impl<S: Simd> From<u32x8<S>> for [u32; 8] {
7112 #[inline(always)]
7113 fn from(value: u32x8<S>) -> Self {
7114 crate::transmute::checked_transmute_copy(&value.val)
7115 }
7116}
7117impl<S: Simd> core::ops::Deref for u32x8<S> {
7118 type Target = [u32; 8];
7119 #[inline(always)]
7120 fn deref(&self) -> &Self::Target {
7121 crate::transmute::checked_cast_ref(&self.val)
7122 }
7123}
7124impl<S: Simd> core::ops::DerefMut for u32x8<S> {
7125 #[inline(always)]
7126 fn deref_mut(&mut self) -> &mut Self::Target {
7127 crate::transmute::checked_cast_mut(&mut self.val)
7128 }
7129}
7130impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u32x8<S> {
7131 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
7132 crate::support::simd_debug_impl(f, "u32x8", &self.simd, self.as_array())
7133 }
7134}
7135impl<S: Simd> SimdFrom<u32, S> for u32x8<S> {
7136 #[inline(always)]
7137 fn simd_from(simd: S, value: u32) -> Self {
7138 simd.splat_u32x8(value)
7139 }
7140}
7141impl<S: Simd> core::ops::Index<usize> for u32x8<S> {
7142 type Output = u32;
7143 #[inline(always)]
7144 fn index(&self, i: usize) -> &Self::Output {
7145 &self.as_array()[i]
7146 }
7147}
7148impl<S: Simd> core::ops::IndexMut<usize> for u32x8<S> {
7149 #[inline(always)]
7150 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
7151 &mut self.as_mut_array()[i]
7152 }
7153}
7154impl<S: Simd> Select<u32x8<S>> for mask32x8<S> {
7155 #[inline(always)]
7156 fn select(self, if_true: u32x8<S>, if_false: u32x8<S>) -> u32x8<S> {
7157 self.simd.select_u32x8(self, if_true, if_false)
7158 }
7159}
7160impl<S: Simd> Bytes for u32x8<S> {
7161 type Bytes = u8x32<S>;
7162 #[inline(always)]
7163 fn to_bytes(self) -> Self::Bytes {
7164 u8x32 {
7165 val: crate::transmute::checked_transmute_copy(&self.val),
7166 simd: self.simd,
7167 }
7168 }
7169 #[inline(always)]
7170 fn from_bytes(value: Self::Bytes) -> Self {
7171 Self {
7172 val: crate::transmute::checked_transmute_copy(&value.val),
7173 simd: value.simd,
7174 }
7175 }
7176}
7177impl<S: Simd> SimdBase<S> for u32x8<S> {
7178 type Element = u32;
7179 type ByteVector = u8x32<S>;
7180 const LEN: usize = 8;
7181 type Mask = mask32x8<S>;
7182 type Block = u32x4<S>;
7183 type Array = [u32; 8];
7184 #[inline(always)]
7185 fn as_slice(&self) -> &[u32] {
7186 self.as_array().as_slice()
7187 }
7188 #[inline(always)]
7189 fn as_mut_slice(&mut self) -> &mut [u32] {
7190 self.as_mut_array().as_mut_slice()
7191 }
7192 #[inline(always)]
7193 fn from_slice(simd: S, slice: &[u32]) -> Self {
7194 Self::load_array_ref(simd, slice.try_into().unwrap())
7195 }
7196 #[inline(always)]
7197 fn store_slice(&self, slice: &mut [u32]) {
7198 (*self).store_array(slice.try_into().unwrap());
7199 }
7200 #[inline(always)]
7201 fn splat(simd: S, val: u32) -> Self {
7202 simd.splat_u32x8(val)
7203 }
7204 #[inline(always)]
7205 fn block_splat(block: Self::Block) -> Self {
7206 block.simd.combine_u32x4(block, block)
7207 }
7208 #[inline(always)]
7209 fn from_fn(simd: S, mut f: impl FnMut(usize) -> u32) -> Self {
7210 Self::load_array(
7211 simd,
7212 [
7213 f(0usize),
7214 f(1usize),
7215 f(2usize),
7216 f(3usize),
7217 f(4usize),
7218 f(5usize),
7219 f(6usize),
7220 f(7usize),
7221 ],
7222 )
7223 }
7224 #[inline(always)]
7225 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
7226 self.simd
7227 .slide_u32x8::<SHIFT>(self, rhs.simd_into(self.simd))
7228 }
7229 #[inline(always)]
7230 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
7231 self.simd
7232 .slide_within_blocks_u32x8::<SHIFT>(self, rhs.simd_into(self.simd))
7233 }
7234 #[inline(always)]
7235 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
7236 self.simd
7237 .swizzle_dyn_within_blocks_u32x8(self, indices.simd_into(self.simd))
7238 }
7239 #[inline(always)]
7240 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
7241 self.simd
7242 .swizzle_dyn_u32x8(self, indices.simd_into(self.simd))
7243 }
7244 #[inline(always)]
7245 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
7246 self.simd
7247 .swizzle_dyn_precise_u32x8(self, indices.simd_into(self.simd))
7248 }
7249 #[inline(always)]
7250 fn abs(self) -> Self {
7251 self.simd.abs_u32x8(self)
7252 }
7253 #[inline(always)]
7254 fn reverse(self) -> Self {
7255 self.simd.reverse_u32x8(self)
7256 }
7257 #[inline(always)]
7258 fn concat_swizzle_dyn(
7259 self,
7260 rhs: impl SimdInto<Self, S>,
7261 indices: impl SimdInto<Self::Bytes, S>,
7262 ) -> Self {
7263 self.simd.concat_swizzle_dyn_u32x8(
7264 self,
7265 rhs.simd_into(self.simd),
7266 indices.simd_into(self.simd),
7267 )
7268 }
7269 #[inline(always)]
7270 fn concat_swizzle_dyn_precise(
7271 self,
7272 rhs: impl SimdInto<Self, S>,
7273 indices: impl SimdInto<Self::Bytes, S>,
7274 ) -> Self {
7275 self.simd.concat_swizzle_dyn_precise_u32x8(
7276 self,
7277 rhs.simd_into(self.simd),
7278 indices.simd_into(self.simd),
7279 )
7280 }
7281 #[inline(always)]
7282 fn compress(self, mask: Self::Mask) -> Self {
7283 self.simd.compress_u32x8(self, mask)
7284 }
7285 #[inline(always)]
7286 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
7287 self.simd
7288 .compress_merge_u32x8(self, mask, merge.simd_into(self.simd))
7289 }
7290 #[inline(always)]
7291 fn expand(self, mask: Self::Mask) -> Self {
7292 self.simd.expand_u32x8(self, mask)
7293 }
7294 #[inline(always)]
7295 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
7296 self.simd
7297 .expand_merge_u32x8(self, mask, merge.simd_into(self.simd))
7298 }
7299 #[inline(always)]
7300 fn reduce_max(self) -> Self::Element {
7301 self.simd.reduce_max_u32x8(self)
7302 }
7303 #[inline(always)]
7304 fn reduce_min(self) -> Self::Element {
7305 self.simd.reduce_min_u32x8(self)
7306 }
7307 #[inline(always)]
7308 fn reduce_max_precise(self) -> Self::Element {
7309 self.simd.reduce_max_u32x8(self)
7310 }
7311 #[inline(always)]
7312 fn reduce_min_precise(self) -> Self::Element {
7313 self.simd.reduce_min_u32x8(self)
7314 }
7315 #[inline(always)]
7316 fn reduce_sum(self) -> Self::Element {
7317 self.simd.reduce_sum_u32x8(self)
7318 }
7319 #[inline(always)]
7320 fn reduce_product(self) -> Self::Element {
7321 self.simd.reduce_product_u32x8(self)
7322 }
7323 #[inline(always)]
7324 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
7325 self.simd.max_u32x8(self, rhs.simd_into(self.simd))
7326 }
7327 #[inline(always)]
7328 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
7329 self.simd.min_u32x8(self, rhs.simd_into(self.simd))
7330 }
7331 #[inline(always)]
7332 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
7333 self.simd.max_u32x8(self, rhs.simd_into(self.simd))
7334 }
7335 #[inline(always)]
7336 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
7337 self.simd.min_u32x8(self, rhs.simd_into(self.simd))
7338 }
7339 #[inline(always)]
7340 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
7341 self.simd
7342 .clamp_u32x8(self, min.simd_into(self.simd), max.simd_into(self.simd))
7343 }
7344 #[inline(always)]
7345 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
7346 self.simd.simd_eq_u32x8(self, rhs.simd_into(self.simd))
7347 }
7348 #[inline(always)]
7349 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
7350 self.simd.simd_ne_u32x8(self, rhs.simd_into(self.simd))
7351 }
7352 #[inline(always)]
7353 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
7354 self.simd.simd_lt_u32x8(self, rhs.simd_into(self.simd))
7355 }
7356 #[inline(always)]
7357 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
7358 self.simd.simd_le_u32x8(self, rhs.simd_into(self.simd))
7359 }
7360 #[inline(always)]
7361 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
7362 self.simd.simd_ge_u32x8(self, rhs.simd_into(self.simd))
7363 }
7364 #[inline(always)]
7365 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
7366 self.simd.simd_gt_u32x8(self, rhs.simd_into(self.simd))
7367 }
7368 #[inline(always)]
7369 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
7370 self.simd.zip_low_u32x8(self, rhs.simd_into(self.simd))
7371 }
7372 #[inline(always)]
7373 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
7374 self.simd.zip_high_u32x8(self, rhs.simd_into(self.simd))
7375 }
7376 #[inline(always)]
7377 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
7378 self.simd.unzip_low_u32x8(self, rhs.simd_into(self.simd))
7379 }
7380 #[inline(always)]
7381 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
7382 self.simd.unzip_high_u32x8(self, rhs.simd_into(self.simd))
7383 }
7384 #[inline(always)]
7385 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
7386 self.simd.interleave_u32x8(self, rhs.simd_into(self.simd))
7387 }
7388 #[inline(always)]
7389 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
7390 self.simd.deinterleave_u32x8(self, rhs.simd_into(self.simd))
7391 }
7392}
7393impl<S: Simd> crate::SimdInt<S> for u32x8<S> {
7394 #[inline(always)]
7395 fn count_ones(self) -> Self {
7396 self.simd.count_ones_u32x8(self)
7397 }
7398 #[inline(always)]
7399 fn count_zeros(self) -> Self {
7400 self.simd.count_zeros_u32x8(self)
7401 }
7402 #[inline(always)]
7403 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
7404 self.simd
7405 .saturating_add_u32x8(self, rhs.simd_into(self.simd))
7406 }
7407 #[inline(always)]
7408 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
7409 self.simd
7410 .saturating_sub_u32x8(self, rhs.simd_into(self.simd))
7411 }
7412}
7413impl<S: Simd> SimdCvtTruncate<f32x8<S>> for u32x8<S> {
7414 #[doc = "Convert each floating-point element to an unsigned 32-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results.\n\nOn x86 platforms below AVX-512, this operation will still be slower than converting to `i32`, because there is no native instruction for converting to `u32`.\nIf you know your values fit within range of an `i32`, you should convert to an `i32` and cast to your desired datatype afterwards."]
7415 #[inline(always)]
7416 fn truncate_from(x: f32x8<S>) -> Self {
7417 x.simd.cvt_u32_f32x8(x)
7418 }
7419 #[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."]
7420 #[inline(always)]
7421 fn truncate_from_precise(x: f32x8<S>) -> Self {
7422 x.simd.cvt_u32_precise_f32x8(x)
7423 }
7424}
7425impl<S: Simd> SimdWiden<S> for u32x8<S> {
7426 type Widened = u64x4<S>;
7427 #[inline(always)]
7428 fn widen(self) -> (Self::Widened, Self::Widened) {
7429 self.simd.widen_u32x8(self)
7430 }
7431}
7432impl<S: Simd> SimdIntWiden<S> for u32x8<S> {
7433 #[inline(always)]
7434 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
7435 self.simd.widening_mul_u32x8(self, rhs.simd_into(self.simd))
7436 }
7437 #[inline(always)]
7438 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
7439 self.simd.widening_add_u32x8(self, rhs.simd_into(self.simd))
7440 }
7441 #[inline(always)]
7442 fn pairwise_widening_add(self) -> Self::Widened {
7443 self.simd.pairwise_widening_add_u32x8(self)
7444 }
7445 #[inline(always)]
7446 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
7447 self.simd
7448 .pairwise_dot_product_u32x8(self, rhs.simd_into(self.simd))
7449 }
7450}
7451impl<S: Simd> SimdNarrow<S> for u32x8<S> {
7452 type Narrowed = u16x16<S>;
7453 #[inline(always)]
7454 fn narrow(self, high: Self) -> Self::Narrowed {
7455 self.simd.narrow_u32x8(self, high)
7456 }
7457 #[inline(always)]
7458 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
7459 self.simd.saturating_narrow_u32x8(self, high)
7460 }
7461 #[inline(always)]
7462 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
7463 self.simd.relaxed_narrow_u32x8(self, high)
7464 }
7465}
7466impl<S: Simd> crate::SimdSplit<S> for u32x8<S> {
7467 type Split = u32x4<S>;
7468 #[inline(always)]
7469 fn split(self) -> (Self::Split, Self::Split) {
7470 self.simd.split_u32x8(self)
7471 }
7472}
7473impl<S: Simd> crate::SimdCombine<S> for u32x8<S> {
7474 type Combined = u32x16<S>;
7475 #[inline(always)]
7476 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
7477 self.simd.combine_u32x8(self, rhs.simd_into(self.simd))
7478 }
7479}
7480impl<S: Simd> ExtractToken for mask32x8<S> {
7481 type S = S;
7482 #[inline]
7483 fn token(&self) -> S {
7484 self.simd
7485 }
7486}
7487#[doc = "A SIMD mask of 8 logical lanes corresponding to 32-bit vector elements.\n\nThe storage representation of this type is intentionally opaque and may vary depending on the SIMD level.\n\nYou can construct this mask type using the [`Self::splat`], [`Self::from_bitmask`], [`Self::from_slice`], and [`Self::simd_from`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, mask32x8};\nfn construct_mask<S: Simd>(simd: S) {\n // From a single boolean value:\n let a = mask32x8::splat(simd, true);\n let b = mask32x8::simd_from(simd, true);\n\n // From signed integer mask lanes:\n let c = mask32x8::from_slice(simd, &[-1, 0, 0, 0, 0, 0, 0, 0]);\n let d = mask32x8::simd_from(simd, [-1, 0, 0, 0, 0, 0, 0, 0]);\n\n // From a compact bitmask (same mask as above, least significant bit maps to lane 0):\n let e = mask32x8::from_bitmask(simd, 0b0001);\n\n // By setting individual lanes:\n let mut f = mask32x8::splat(simd, false);\n f.set(0, true);\n}\n```"]
7488#[derive(Clone, Copy)]
7489pub struct mask32x8<S: Simd> {
7490 pub(crate) val: S::mask32x8,
7491 pub(crate) simd: S,
7492}
7493impl<S: Simd> Seal for mask32x8<S> {}
7494impl<S: Simd> SimdFrom<[i32; 8], S> for mask32x8<S> {
7495 #[inline(always)]
7496 fn simd_from(simd: S, val: [i32; 8]) -> Self {
7497 Self {
7498 val: <S as crate::arch_types::ArchTypes>::mask32x8_from_array(simd, val),
7499 simd,
7500 }
7501 }
7502}
7503impl<S: Simd> From<mask32x8<S>> for [i32; 8] {
7504 #[inline(always)]
7505 fn from(value: mask32x8<S>) -> Self {
7506 <S as crate::arch_types::ArchTypes>::mask32x8_to_array(value.simd, value.val)
7507 }
7508}
7509impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask32x8<S> {
7510 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
7511 let lanes: [i32; 8] = (*self).into();
7512 crate::support::simd_debug_impl(f, "mask32x8", &self.simd, &lanes)
7513 }
7514}
7515impl<S: Simd> SimdFrom<bool, S> for mask32x8<S> {
7516 #[inline(always)]
7517 fn simd_from(simd: S, value: bool) -> Self {
7518 simd.splat_mask32x8(value)
7519 }
7520}
7521impl<S: Simd> Select<mask32x8<S>> for mask32x8<S> {
7522 #[inline(always)]
7523 fn select(self, if_true: mask32x8<S>, if_false: mask32x8<S>) -> mask32x8<S> {
7524 self.simd.select_mask32x8(self, if_true, if_false)
7525 }
7526}
7527impl<S: Simd> SimdMask<S> for mask32x8<S> {
7528 type Element = i32;
7529 type Ints = i32x8<S>;
7530 const LEN: usize = 8;
7531 #[inline(always)]
7532 fn splat(simd: S, val: bool) -> Self {
7533 simd.splat_mask32x8(val)
7534 }
7535 #[inline(always)]
7536 fn from_bitmask(simd: S, bits: u64) -> Self {
7537 simd.from_bitmask_mask32x8(bits)
7538 }
7539 #[inline(always)]
7540 fn to_bitmask(self) -> u64 {
7541 self.simd.to_bitmask_mask32x8(self)
7542 }
7543 #[inline(always)]
7544 fn from_vector(vector: Self::Ints) -> Self {
7545 vector.token().from_vector_mask32x8(vector)
7546 }
7547 #[inline(always)]
7548 fn to_vector(self) -> Self::Ints {
7549 self.simd.to_vector_mask32x8(self)
7550 }
7551 #[inline(always)]
7552 fn set(&mut self, index: usize, value: bool) {
7553 self.simd.set_mask32x8(self, index, value);
7554 }
7555 #[inline(always)]
7556 fn from_slice(simd: S, slice: &[i32]) -> Self {
7557 let slice: &[i32; 8] = slice.try_into().unwrap();
7558 Self::simd_from(simd, *slice)
7559 }
7560 #[inline(always)]
7561 fn store_slice(&self, slice: &mut [i32]) {
7562 let slice: &mut [i32; 8] = slice.try_into().unwrap();
7563 *slice = (*self).into();
7564 }
7565 #[inline(always)]
7566 fn rotate_elements_left<const OFFSET: usize>(self) -> Self {
7567 self.simd.rotate_elements_left_mask32x8::<OFFSET>(self)
7568 }
7569 #[inline(always)]
7570 fn rotate_elements_right<const OFFSET: usize>(self) -> Self {
7571 self.simd.rotate_elements_right_mask32x8::<OFFSET>(self)
7572 }
7573 #[inline(always)]
7574 fn reverse(self) -> Self {
7575 self.simd.reverse_mask32x8(self)
7576 }
7577 #[inline(always)]
7578 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self {
7579 self.simd.simd_eq_mask32x8(self, rhs.simd_into(self.simd))
7580 }
7581 #[inline(always)]
7582 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self {
7583 self.simd.simd_ne_mask32x8(self, rhs.simd_into(self.simd))
7584 }
7585 #[inline(always)]
7586 fn any_true(self) -> bool {
7587 self.simd.any_true_mask32x8(self)
7588 }
7589 #[inline(always)]
7590 fn all_true(self) -> bool {
7591 self.simd.all_true_mask32x8(self)
7592 }
7593 #[inline(always)]
7594 fn any_false(self) -> bool {
7595 self.simd.any_false_mask32x8(self)
7596 }
7597 #[inline(always)]
7598 fn all_false(self) -> bool {
7599 self.simd.all_false_mask32x8(self)
7600 }
7601}
7602impl<S: Simd> MaskWiden<S> for mask32x8<S> {
7603 type Widened = mask64x4<S>;
7604 #[inline(always)]
7605 fn widen(self) -> (Self::Widened, Self::Widened) {
7606 self.simd.widen_mask32x8(self)
7607 }
7608}
7609impl<S: Simd> MaskNarrow<S> for mask32x8<S> {
7610 type Narrowed = mask16x16<S>;
7611 #[inline(always)]
7612 fn narrow(self, high: Self) -> Self::Narrowed {
7613 self.simd.narrow_mask32x8(self, high)
7614 }
7615}
7616impl<S: Simd> ExtractToken for f64x4<S> {
7617 type S = S;
7618 #[inline]
7619 fn token(&self) -> S {
7620 self.simd
7621 }
7622}
7623#[doc = "A SIMD vector of 4 [`f64`] elements.\n\nThis type's memory layout is identical to that of [`[f64; 4]`](prim@array), except that it is aligned to 32 bytes.\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```"]
7624#[derive(Clone, Copy)]
7625#[repr(C, align(32))]
7626pub struct f64x4<S: Simd> {
7627 pub(crate) val: S::f64x4,
7628 pub simd: S,
7629}
7630impl<S: Simd> Seal for f64x4<S> {}
7631impl<S: Simd> SimdFrom<[f64; 4], S> for f64x4<S> {
7632 #[inline(always)]
7633 fn simd_from(simd: S, val: [f64; 4]) -> Self {
7634 Self {
7635 val: crate::transmute::checked_transmute_copy(&val),
7636 simd,
7637 }
7638 }
7639}
7640impl<S: Simd> From<f64x4<S>> for [f64; 4] {
7641 #[inline(always)]
7642 fn from(value: f64x4<S>) -> Self {
7643 crate::transmute::checked_transmute_copy(&value.val)
7644 }
7645}
7646impl<S: Simd> core::ops::Deref for f64x4<S> {
7647 type Target = [f64; 4];
7648 #[inline(always)]
7649 fn deref(&self) -> &Self::Target {
7650 crate::transmute::checked_cast_ref(&self.val)
7651 }
7652}
7653impl<S: Simd> core::ops::DerefMut for f64x4<S> {
7654 #[inline(always)]
7655 fn deref_mut(&mut self) -> &mut Self::Target {
7656 crate::transmute::checked_cast_mut(&mut self.val)
7657 }
7658}
7659impl<S: Simd + core::fmt::Debug> core::fmt::Debug for f64x4<S> {
7660 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
7661 crate::support::simd_debug_impl(f, "f64x4", &self.simd, self.as_array())
7662 }
7663}
7664impl<S: Simd> SimdFrom<f64, S> for f64x4<S> {
7665 #[inline(always)]
7666 fn simd_from(simd: S, value: f64) -> Self {
7667 simd.splat_f64x4(value)
7668 }
7669}
7670impl<S: Simd> core::ops::Index<usize> for f64x4<S> {
7671 type Output = f64;
7672 #[inline(always)]
7673 fn index(&self, i: usize) -> &Self::Output {
7674 &self.as_array()[i]
7675 }
7676}
7677impl<S: Simd> core::ops::IndexMut<usize> for f64x4<S> {
7678 #[inline(always)]
7679 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
7680 &mut self.as_mut_array()[i]
7681 }
7682}
7683impl<S: Simd> Select<f64x4<S>> for mask64x4<S> {
7684 #[inline(always)]
7685 fn select(self, if_true: f64x4<S>, if_false: f64x4<S>) -> f64x4<S> {
7686 self.simd.select_f64x4(self, if_true, if_false)
7687 }
7688}
7689impl<S: Simd> Bytes for f64x4<S> {
7690 type Bytes = u8x32<S>;
7691 #[inline(always)]
7692 fn to_bytes(self) -> Self::Bytes {
7693 u8x32 {
7694 val: crate::transmute::checked_transmute_copy(&self.val),
7695 simd: self.simd,
7696 }
7697 }
7698 #[inline(always)]
7699 fn from_bytes(value: Self::Bytes) -> Self {
7700 Self {
7701 val: crate::transmute::checked_transmute_copy(&value.val),
7702 simd: value.simd,
7703 }
7704 }
7705}
7706impl<S: Simd> SimdBase<S> for f64x4<S> {
7707 type Element = f64;
7708 type ByteVector = u8x32<S>;
7709 const LEN: usize = 4;
7710 type Mask = mask64x4<S>;
7711 type Block = f64x2<S>;
7712 type Array = [f64; 4];
7713 #[inline(always)]
7714 fn as_slice(&self) -> &[f64] {
7715 self.as_array().as_slice()
7716 }
7717 #[inline(always)]
7718 fn as_mut_slice(&mut self) -> &mut [f64] {
7719 self.as_mut_array().as_mut_slice()
7720 }
7721 #[inline(always)]
7722 fn from_slice(simd: S, slice: &[f64]) -> Self {
7723 Self::load_array_ref(simd, slice.try_into().unwrap())
7724 }
7725 #[inline(always)]
7726 fn store_slice(&self, slice: &mut [f64]) {
7727 (*self).store_array(slice.try_into().unwrap());
7728 }
7729 #[inline(always)]
7730 fn splat(simd: S, val: f64) -> Self {
7731 simd.splat_f64x4(val)
7732 }
7733 #[inline(always)]
7734 fn block_splat(block: Self::Block) -> Self {
7735 block.simd.combine_f64x2(block, block)
7736 }
7737 #[inline(always)]
7738 fn from_fn(simd: S, mut f: impl FnMut(usize) -> f64) -> Self {
7739 Self::load_array(simd, [f(0usize), f(1usize), f(2usize), f(3usize)])
7740 }
7741 #[inline(always)]
7742 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
7743 self.simd
7744 .slide_f64x4::<SHIFT>(self, rhs.simd_into(self.simd))
7745 }
7746 #[inline(always)]
7747 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
7748 self.simd
7749 .slide_within_blocks_f64x4::<SHIFT>(self, rhs.simd_into(self.simd))
7750 }
7751 #[inline(always)]
7752 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
7753 self.simd
7754 .swizzle_dyn_within_blocks_f64x4(self, indices.simd_into(self.simd))
7755 }
7756 #[inline(always)]
7757 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
7758 self.simd
7759 .swizzle_dyn_f64x4(self, indices.simd_into(self.simd))
7760 }
7761 #[inline(always)]
7762 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
7763 self.simd
7764 .swizzle_dyn_precise_f64x4(self, indices.simd_into(self.simd))
7765 }
7766 #[inline(always)]
7767 fn abs(self) -> Self {
7768 self.simd.abs_f64x4(self)
7769 }
7770 #[inline(always)]
7771 fn reverse(self) -> Self {
7772 self.simd.reverse_f64x4(self)
7773 }
7774 #[inline(always)]
7775 fn concat_swizzle_dyn(
7776 self,
7777 rhs: impl SimdInto<Self, S>,
7778 indices: impl SimdInto<Self::Bytes, S>,
7779 ) -> Self {
7780 self.simd.concat_swizzle_dyn_f64x4(
7781 self,
7782 rhs.simd_into(self.simd),
7783 indices.simd_into(self.simd),
7784 )
7785 }
7786 #[inline(always)]
7787 fn concat_swizzle_dyn_precise(
7788 self,
7789 rhs: impl SimdInto<Self, S>,
7790 indices: impl SimdInto<Self::Bytes, S>,
7791 ) -> Self {
7792 self.simd.concat_swizzle_dyn_precise_f64x4(
7793 self,
7794 rhs.simd_into(self.simd),
7795 indices.simd_into(self.simd),
7796 )
7797 }
7798 #[inline(always)]
7799 fn compress(self, mask: Self::Mask) -> Self {
7800 self.simd.compress_f64x4(self, mask)
7801 }
7802 #[inline(always)]
7803 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
7804 self.simd
7805 .compress_merge_f64x4(self, mask, merge.simd_into(self.simd))
7806 }
7807 #[inline(always)]
7808 fn expand(self, mask: Self::Mask) -> Self {
7809 self.simd.expand_f64x4(self, mask)
7810 }
7811 #[inline(always)]
7812 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
7813 self.simd
7814 .expand_merge_f64x4(self, mask, merge.simd_into(self.simd))
7815 }
7816 #[inline(always)]
7817 fn reduce_max(self) -> Self::Element {
7818 self.simd.reduce_max_f64x4(self)
7819 }
7820 #[inline(always)]
7821 fn reduce_min(self) -> Self::Element {
7822 self.simd.reduce_min_f64x4(self)
7823 }
7824 #[inline(always)]
7825 fn reduce_max_precise(self) -> Self::Element {
7826 self.simd.reduce_max_precise_f64x4(self)
7827 }
7828 #[inline(always)]
7829 fn reduce_min_precise(self) -> Self::Element {
7830 self.simd.reduce_min_precise_f64x4(self)
7831 }
7832 #[inline(always)]
7833 fn reduce_sum(self) -> Self::Element {
7834 self.simd.reduce_sum_f64x4(self)
7835 }
7836 #[inline(always)]
7837 fn reduce_product(self) -> Self::Element {
7838 self.simd.reduce_product_f64x4(self)
7839 }
7840 #[inline(always)]
7841 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
7842 self.simd.max_f64x4(self, rhs.simd_into(self.simd))
7843 }
7844 #[inline(always)]
7845 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
7846 self.simd.min_f64x4(self, rhs.simd_into(self.simd))
7847 }
7848 #[inline(always)]
7849 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
7850 self.simd.max_precise_f64x4(self, rhs.simd_into(self.simd))
7851 }
7852 #[inline(always)]
7853 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
7854 self.simd.min_precise_f64x4(self, rhs.simd_into(self.simd))
7855 }
7856 #[inline(always)]
7857 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
7858 self.simd
7859 .clamp_f64x4(self, min.simd_into(self.simd), max.simd_into(self.simd))
7860 }
7861 #[inline(always)]
7862 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
7863 self.simd.simd_eq_f64x4(self, rhs.simd_into(self.simd))
7864 }
7865 #[inline(always)]
7866 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
7867 self.simd.simd_ne_f64x4(self, rhs.simd_into(self.simd))
7868 }
7869 #[inline(always)]
7870 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
7871 self.simd.simd_lt_f64x4(self, rhs.simd_into(self.simd))
7872 }
7873 #[inline(always)]
7874 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
7875 self.simd.simd_le_f64x4(self, rhs.simd_into(self.simd))
7876 }
7877 #[inline(always)]
7878 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
7879 self.simd.simd_ge_f64x4(self, rhs.simd_into(self.simd))
7880 }
7881 #[inline(always)]
7882 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
7883 self.simd.simd_gt_f64x4(self, rhs.simd_into(self.simd))
7884 }
7885 #[inline(always)]
7886 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
7887 self.simd.zip_low_f64x4(self, rhs.simd_into(self.simd))
7888 }
7889 #[inline(always)]
7890 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
7891 self.simd.zip_high_f64x4(self, rhs.simd_into(self.simd))
7892 }
7893 #[inline(always)]
7894 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
7895 self.simd.unzip_low_f64x4(self, rhs.simd_into(self.simd))
7896 }
7897 #[inline(always)]
7898 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
7899 self.simd.unzip_high_f64x4(self, rhs.simd_into(self.simd))
7900 }
7901 #[inline(always)]
7902 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
7903 self.simd.interleave_f64x4(self, rhs.simd_into(self.simd))
7904 }
7905 #[inline(always)]
7906 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
7907 self.simd.deinterleave_f64x4(self, rhs.simd_into(self.simd))
7908 }
7909}
7910impl<S: Simd> crate::SimdFloat<S> for f64x4<S> {
7911 type Bits = u64x4<S>;
7912 #[inline(always)]
7913 fn sqrt(self) -> Self {
7914 self.simd.sqrt_f64x4(self)
7915 }
7916 #[inline(always)]
7917 fn approximate_recip(self) -> Self {
7918 self.simd.approximate_recip_f64x4(self)
7919 }
7920 #[inline(always)]
7921 fn copysign(self, rhs: impl SimdInto<Self, S>) -> Self {
7922 self.simd.copysign_f64x4(self, rhs.simd_into(self.simd))
7923 }
7924 #[inline(always)]
7925 fn mul_add(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
7926 self.simd
7927 .mul_add_f64x4(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
7928 }
7929 #[inline(always)]
7930 fn mul_add_precise(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
7931 self.simd
7932 .mul_add_precise_f64x4(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
7933 }
7934 #[inline(always)]
7935 fn mul_sub(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
7936 self.simd
7937 .mul_sub_f64x4(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
7938 }
7939 #[inline(always)]
7940 fn mul_sub_precise(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
7941 self.simd
7942 .mul_sub_precise_f64x4(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
7943 }
7944 #[inline(always)]
7945 fn floor(self) -> Self {
7946 self.simd.floor_f64x4(self)
7947 }
7948 #[inline(always)]
7949 fn ceil(self) -> Self {
7950 self.simd.ceil_f64x4(self)
7951 }
7952 #[inline(always)]
7953 fn round_ties_even(self) -> Self {
7954 self.simd.round_ties_even_f64x4(self)
7955 }
7956 #[inline(always)]
7957 fn round(self) -> Self {
7958 self.simd.round_f64x4(self)
7959 }
7960 #[inline(always)]
7961 fn fract(self) -> Self {
7962 self.simd.fract_f64x4(self)
7963 }
7964 #[inline(always)]
7965 fn trunc(self) -> Self {
7966 self.simd.trunc_f64x4(self)
7967 }
7968 #[inline(always)]
7969 fn to_degrees(self) -> Self {
7970 self.simd.to_degrees_f64x4(self)
7971 }
7972 #[inline(always)]
7973 fn to_radians(self) -> Self {
7974 self.simd.to_radians_f64x4(self)
7975 }
7976 #[inline(always)]
7977 fn is_nan(self) -> Self::Mask {
7978 self.simd.is_nan_f64x4(self)
7979 }
7980 #[inline(always)]
7981 fn is_infinite(self) -> Self::Mask {
7982 self.simd.is_infinite_f64x4(self)
7983 }
7984 #[inline(always)]
7985 fn is_finite(self) -> Self::Mask {
7986 self.simd.is_finite_f64x4(self)
7987 }
7988 #[inline(always)]
7989 fn is_subnormal(self) -> Self::Mask {
7990 self.simd.is_subnormal_f64x4(self)
7991 }
7992 #[inline(always)]
7993 fn is_normal(self) -> Self::Mask {
7994 self.simd.is_normal_f64x4(self)
7995 }
7996 #[inline(always)]
7997 fn is_sign_positive(self) -> Self::Mask {
7998 self.simd.is_sign_positive_f64x4(self)
7999 }
8000 #[inline(always)]
8001 fn is_sign_negative(self) -> Self::Mask {
8002 self.simd.is_sign_negative_f64x4(self)
8003 }
8004}
8005impl<S: Simd> SimdCvtFloat<u64x4<S>> for f64x4<S> {
8006 #[doc = "Convert each unsigned 64-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
8007 #[inline(always)]
8008 fn float_from(x: u64x4<S>) -> Self {
8009 x.simd.cvt_f64_u64x4(x)
8010 }
8011}
8012impl<S: Simd> SimdCvtFloat<i64x4<S>> for f64x4<S> {
8013 #[doc = "Convert each signed 64-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
8014 #[inline(always)]
8015 fn float_from(x: i64x4<S>) -> Self {
8016 x.simd.cvt_f64_i64x4(x)
8017 }
8018}
8019impl<S: Simd> SimdNarrow<S> for f64x4<S> {
8020 type Narrowed = f32x8<S>;
8021 #[inline(always)]
8022 fn narrow(self, high: Self) -> Self::Narrowed {
8023 self.simd.narrow_f64x4(self, high)
8024 }
8025 #[inline(always)]
8026 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
8027 self.simd.saturating_narrow_f64x4(self, high)
8028 }
8029 #[inline(always)]
8030 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
8031 self.simd.relaxed_narrow_f64x4(self, high)
8032 }
8033}
8034impl<S: Simd> crate::SimdSplit<S> for f64x4<S> {
8035 type Split = f64x2<S>;
8036 #[inline(always)]
8037 fn split(self) -> (Self::Split, Self::Split) {
8038 self.simd.split_f64x4(self)
8039 }
8040}
8041impl<S: Simd> crate::SimdCombine<S> for f64x4<S> {
8042 type Combined = f64x8<S>;
8043 #[inline(always)]
8044 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
8045 self.simd.combine_f64x4(self, rhs.simd_into(self.simd))
8046 }
8047}
8048impl<S: Simd> ExtractToken for i64x4<S> {
8049 type S = S;
8050 #[inline]
8051 fn token(&self) -> S {
8052 self.simd
8053 }
8054}
8055#[doc = "A SIMD vector of 4 [`i64`] elements.\n\nThis type's memory layout is identical to that of [`[i64; 4]`](prim@array), except that it is aligned to 32 bytes.\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::*, i64x4};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = i64x4::splat(simd, 1);\n let b = i64x4::simd_from(simd, 1);\n\n // From a slice:\n let c = i64x4::from_slice(simd, &[1, 2, 3, 4]);\n\n // From an array:\n let d = i64x4::simd_from(simd, [1, 2, 3, 4]);\n\n // From an element-wise function:\n let e = i64x4::from_fn(simd, |i| i as i64);\n # use fearless_simd::i64x2;\n // From `Self::Block`:\n let f = i64x4::block_splat(i64x2::simd_from(simd, [1, 2]));\n}\n```"]
8056#[derive(Clone, Copy)]
8057#[repr(C, align(32))]
8058pub struct i64x4<S: Simd> {
8059 pub(crate) val: S::i64x4,
8060 pub simd: S,
8061}
8062impl<S: Simd> Seal for i64x4<S> {}
8063impl<S: Simd> SimdFrom<[i64; 4], S> for i64x4<S> {
8064 #[inline(always)]
8065 fn simd_from(simd: S, val: [i64; 4]) -> Self {
8066 Self {
8067 val: crate::transmute::checked_transmute_copy(&val),
8068 simd,
8069 }
8070 }
8071}
8072impl<S: Simd> From<i64x4<S>> for [i64; 4] {
8073 #[inline(always)]
8074 fn from(value: i64x4<S>) -> Self {
8075 crate::transmute::checked_transmute_copy(&value.val)
8076 }
8077}
8078impl<S: Simd> core::ops::Deref for i64x4<S> {
8079 type Target = [i64; 4];
8080 #[inline(always)]
8081 fn deref(&self) -> &Self::Target {
8082 crate::transmute::checked_cast_ref(&self.val)
8083 }
8084}
8085impl<S: Simd> core::ops::DerefMut for i64x4<S> {
8086 #[inline(always)]
8087 fn deref_mut(&mut self) -> &mut Self::Target {
8088 crate::transmute::checked_cast_mut(&mut self.val)
8089 }
8090}
8091impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i64x4<S> {
8092 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8093 crate::support::simd_debug_impl(f, "i64x4", &self.simd, self.as_array())
8094 }
8095}
8096impl<S: Simd> SimdFrom<i64, S> for i64x4<S> {
8097 #[inline(always)]
8098 fn simd_from(simd: S, value: i64) -> Self {
8099 simd.splat_i64x4(value)
8100 }
8101}
8102impl<S: Simd> core::ops::Index<usize> for i64x4<S> {
8103 type Output = i64;
8104 #[inline(always)]
8105 fn index(&self, i: usize) -> &Self::Output {
8106 &self.as_array()[i]
8107 }
8108}
8109impl<S: Simd> core::ops::IndexMut<usize> for i64x4<S> {
8110 #[inline(always)]
8111 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
8112 &mut self.as_mut_array()[i]
8113 }
8114}
8115impl<S: Simd> Select<i64x4<S>> for mask64x4<S> {
8116 #[inline(always)]
8117 fn select(self, if_true: i64x4<S>, if_false: i64x4<S>) -> i64x4<S> {
8118 self.simd.select_i64x4(self, if_true, if_false)
8119 }
8120}
8121impl<S: Simd> Bytes for i64x4<S> {
8122 type Bytes = u8x32<S>;
8123 #[inline(always)]
8124 fn to_bytes(self) -> Self::Bytes {
8125 u8x32 {
8126 val: crate::transmute::checked_transmute_copy(&self.val),
8127 simd: self.simd,
8128 }
8129 }
8130 #[inline(always)]
8131 fn from_bytes(value: Self::Bytes) -> Self {
8132 Self {
8133 val: crate::transmute::checked_transmute_copy(&value.val),
8134 simd: value.simd,
8135 }
8136 }
8137}
8138impl<S: Simd> SimdBase<S> for i64x4<S> {
8139 type Element = i64;
8140 type ByteVector = u8x32<S>;
8141 const LEN: usize = 4;
8142 type Mask = mask64x4<S>;
8143 type Block = i64x2<S>;
8144 type Array = [i64; 4];
8145 #[inline(always)]
8146 fn as_slice(&self) -> &[i64] {
8147 self.as_array().as_slice()
8148 }
8149 #[inline(always)]
8150 fn as_mut_slice(&mut self) -> &mut [i64] {
8151 self.as_mut_array().as_mut_slice()
8152 }
8153 #[inline(always)]
8154 fn from_slice(simd: S, slice: &[i64]) -> Self {
8155 Self::load_array_ref(simd, slice.try_into().unwrap())
8156 }
8157 #[inline(always)]
8158 fn store_slice(&self, slice: &mut [i64]) {
8159 (*self).store_array(slice.try_into().unwrap());
8160 }
8161 #[inline(always)]
8162 fn splat(simd: S, val: i64) -> Self {
8163 simd.splat_i64x4(val)
8164 }
8165 #[inline(always)]
8166 fn block_splat(block: Self::Block) -> Self {
8167 block.simd.combine_i64x2(block, block)
8168 }
8169 #[inline(always)]
8170 fn from_fn(simd: S, mut f: impl FnMut(usize) -> i64) -> Self {
8171 Self::load_array(simd, [f(0usize), f(1usize), f(2usize), f(3usize)])
8172 }
8173 #[inline(always)]
8174 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
8175 self.simd
8176 .slide_i64x4::<SHIFT>(self, rhs.simd_into(self.simd))
8177 }
8178 #[inline(always)]
8179 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
8180 self.simd
8181 .slide_within_blocks_i64x4::<SHIFT>(self, rhs.simd_into(self.simd))
8182 }
8183 #[inline(always)]
8184 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
8185 self.simd
8186 .swizzle_dyn_within_blocks_i64x4(self, indices.simd_into(self.simd))
8187 }
8188 #[inline(always)]
8189 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
8190 self.simd
8191 .swizzle_dyn_i64x4(self, indices.simd_into(self.simd))
8192 }
8193 #[inline(always)]
8194 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
8195 self.simd
8196 .swizzle_dyn_precise_i64x4(self, indices.simd_into(self.simd))
8197 }
8198 #[inline(always)]
8199 fn abs(self) -> Self {
8200 self.simd.abs_i64x4(self)
8201 }
8202 #[inline(always)]
8203 fn reverse(self) -> Self {
8204 self.simd.reverse_i64x4(self)
8205 }
8206 #[inline(always)]
8207 fn concat_swizzle_dyn(
8208 self,
8209 rhs: impl SimdInto<Self, S>,
8210 indices: impl SimdInto<Self::Bytes, S>,
8211 ) -> Self {
8212 self.simd.concat_swizzle_dyn_i64x4(
8213 self,
8214 rhs.simd_into(self.simd),
8215 indices.simd_into(self.simd),
8216 )
8217 }
8218 #[inline(always)]
8219 fn concat_swizzle_dyn_precise(
8220 self,
8221 rhs: impl SimdInto<Self, S>,
8222 indices: impl SimdInto<Self::Bytes, S>,
8223 ) -> Self {
8224 self.simd.concat_swizzle_dyn_precise_i64x4(
8225 self,
8226 rhs.simd_into(self.simd),
8227 indices.simd_into(self.simd),
8228 )
8229 }
8230 #[inline(always)]
8231 fn compress(self, mask: Self::Mask) -> Self {
8232 self.simd.compress_i64x4(self, mask)
8233 }
8234 #[inline(always)]
8235 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
8236 self.simd
8237 .compress_merge_i64x4(self, mask, merge.simd_into(self.simd))
8238 }
8239 #[inline(always)]
8240 fn expand(self, mask: Self::Mask) -> Self {
8241 self.simd.expand_i64x4(self, mask)
8242 }
8243 #[inline(always)]
8244 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
8245 self.simd
8246 .expand_merge_i64x4(self, mask, merge.simd_into(self.simd))
8247 }
8248 #[inline(always)]
8249 fn reduce_max(self) -> Self::Element {
8250 self.simd.reduce_max_i64x4(self)
8251 }
8252 #[inline(always)]
8253 fn reduce_min(self) -> Self::Element {
8254 self.simd.reduce_min_i64x4(self)
8255 }
8256 #[inline(always)]
8257 fn reduce_max_precise(self) -> Self::Element {
8258 self.simd.reduce_max_i64x4(self)
8259 }
8260 #[inline(always)]
8261 fn reduce_min_precise(self) -> Self::Element {
8262 self.simd.reduce_min_i64x4(self)
8263 }
8264 #[inline(always)]
8265 fn reduce_sum(self) -> Self::Element {
8266 self.simd.reduce_sum_i64x4(self)
8267 }
8268 #[inline(always)]
8269 fn reduce_product(self) -> Self::Element {
8270 self.simd.reduce_product_i64x4(self)
8271 }
8272 #[inline(always)]
8273 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
8274 self.simd.max_i64x4(self, rhs.simd_into(self.simd))
8275 }
8276 #[inline(always)]
8277 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
8278 self.simd.min_i64x4(self, rhs.simd_into(self.simd))
8279 }
8280 #[inline(always)]
8281 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
8282 self.simd.max_i64x4(self, rhs.simd_into(self.simd))
8283 }
8284 #[inline(always)]
8285 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
8286 self.simd.min_i64x4(self, rhs.simd_into(self.simd))
8287 }
8288 #[inline(always)]
8289 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
8290 self.simd
8291 .clamp_i64x4(self, min.simd_into(self.simd), max.simd_into(self.simd))
8292 }
8293 #[inline(always)]
8294 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
8295 self.simd.simd_eq_i64x4(self, rhs.simd_into(self.simd))
8296 }
8297 #[inline(always)]
8298 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
8299 self.simd.simd_ne_i64x4(self, rhs.simd_into(self.simd))
8300 }
8301 #[inline(always)]
8302 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
8303 self.simd.simd_lt_i64x4(self, rhs.simd_into(self.simd))
8304 }
8305 #[inline(always)]
8306 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
8307 self.simd.simd_le_i64x4(self, rhs.simd_into(self.simd))
8308 }
8309 #[inline(always)]
8310 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
8311 self.simd.simd_ge_i64x4(self, rhs.simd_into(self.simd))
8312 }
8313 #[inline(always)]
8314 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
8315 self.simd.simd_gt_i64x4(self, rhs.simd_into(self.simd))
8316 }
8317 #[inline(always)]
8318 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
8319 self.simd.zip_low_i64x4(self, rhs.simd_into(self.simd))
8320 }
8321 #[inline(always)]
8322 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
8323 self.simd.zip_high_i64x4(self, rhs.simd_into(self.simd))
8324 }
8325 #[inline(always)]
8326 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
8327 self.simd.unzip_low_i64x4(self, rhs.simd_into(self.simd))
8328 }
8329 #[inline(always)]
8330 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
8331 self.simd.unzip_high_i64x4(self, rhs.simd_into(self.simd))
8332 }
8333 #[inline(always)]
8334 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
8335 self.simd.interleave_i64x4(self, rhs.simd_into(self.simd))
8336 }
8337 #[inline(always)]
8338 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
8339 self.simd.deinterleave_i64x4(self, rhs.simd_into(self.simd))
8340 }
8341}
8342impl<S: Simd> crate::SimdInt<S> for i64x4<S> {
8343 #[inline(always)]
8344 fn count_ones(self) -> Self {
8345 self.simd.count_ones_i64x4(self)
8346 }
8347 #[inline(always)]
8348 fn count_zeros(self) -> Self {
8349 self.simd.count_zeros_i64x4(self)
8350 }
8351 #[inline(always)]
8352 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
8353 self.simd
8354 .saturating_add_i64x4(self, rhs.simd_into(self.simd))
8355 }
8356 #[inline(always)]
8357 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
8358 self.simd
8359 .saturating_sub_i64x4(self, rhs.simd_into(self.simd))
8360 }
8361}
8362impl<S: Simd> SimdCvtTruncate<f64x4<S>> for i64x4<S> {
8363 #[doc = "Convert each floating-point element to a signed 64-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
8364 #[inline(always)]
8365 fn truncate_from(x: f64x4<S>) -> Self {
8366 x.simd.cvt_i64_f64x4(x)
8367 }
8368 #[doc = "Convert each floating-point element to a signed 64-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
8369 #[inline(always)]
8370 fn truncate_from_precise(x: f64x4<S>) -> Self {
8371 x.simd.cvt_i64_precise_f64x4(x)
8372 }
8373}
8374impl<S: Simd> SimdNarrow<S> for i64x4<S> {
8375 type Narrowed = i32x8<S>;
8376 #[inline(always)]
8377 fn narrow(self, high: Self) -> Self::Narrowed {
8378 self.simd.narrow_i64x4(self, high)
8379 }
8380 #[inline(always)]
8381 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
8382 self.simd.saturating_narrow_i64x4(self, high)
8383 }
8384 #[inline(always)]
8385 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
8386 self.simd.relaxed_narrow_i64x4(self, high)
8387 }
8388}
8389impl<S: Simd> crate::SimdSplit<S> for i64x4<S> {
8390 type Split = i64x2<S>;
8391 #[inline(always)]
8392 fn split(self) -> (Self::Split, Self::Split) {
8393 self.simd.split_i64x4(self)
8394 }
8395}
8396impl<S: Simd> crate::SimdCombine<S> for i64x4<S> {
8397 type Combined = i64x8<S>;
8398 #[inline(always)]
8399 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
8400 self.simd.combine_i64x4(self, rhs.simd_into(self.simd))
8401 }
8402}
8403impl<S: Simd> ExtractToken for u64x4<S> {
8404 type S = S;
8405 #[inline]
8406 fn token(&self) -> S {
8407 self.simd
8408 }
8409}
8410#[doc = "A SIMD vector of 4 [`u64`] elements.\n\nThis type's memory layout is identical to that of [`[u64; 4]`](prim@array), except that it is aligned to 32 bytes.\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::*, u64x4};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = u64x4::splat(simd, 1);\n let b = u64x4::simd_from(simd, 1);\n\n // From a slice:\n let c = u64x4::from_slice(simd, &[1, 2, 3, 4]);\n\n // From an array:\n let d = u64x4::simd_from(simd, [1, 2, 3, 4]);\n\n // From an element-wise function:\n let e = u64x4::from_fn(simd, |i| i as u64);\n # use fearless_simd::u64x2;\n // From `Self::Block`:\n let f = u64x4::block_splat(u64x2::simd_from(simd, [1, 2]));\n}\n```"]
8411#[derive(Clone, Copy)]
8412#[repr(C, align(32))]
8413pub struct u64x4<S: Simd> {
8414 pub(crate) val: S::u64x4,
8415 pub simd: S,
8416}
8417impl<S: Simd> Seal for u64x4<S> {}
8418impl<S: Simd> SimdFrom<[u64; 4], S> for u64x4<S> {
8419 #[inline(always)]
8420 fn simd_from(simd: S, val: [u64; 4]) -> Self {
8421 Self {
8422 val: crate::transmute::checked_transmute_copy(&val),
8423 simd,
8424 }
8425 }
8426}
8427impl<S: Simd> From<u64x4<S>> for [u64; 4] {
8428 #[inline(always)]
8429 fn from(value: u64x4<S>) -> Self {
8430 crate::transmute::checked_transmute_copy(&value.val)
8431 }
8432}
8433impl<S: Simd> core::ops::Deref for u64x4<S> {
8434 type Target = [u64; 4];
8435 #[inline(always)]
8436 fn deref(&self) -> &Self::Target {
8437 crate::transmute::checked_cast_ref(&self.val)
8438 }
8439}
8440impl<S: Simd> core::ops::DerefMut for u64x4<S> {
8441 #[inline(always)]
8442 fn deref_mut(&mut self) -> &mut Self::Target {
8443 crate::transmute::checked_cast_mut(&mut self.val)
8444 }
8445}
8446impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u64x4<S> {
8447 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8448 crate::support::simd_debug_impl(f, "u64x4", &self.simd, self.as_array())
8449 }
8450}
8451impl<S: Simd> SimdFrom<u64, S> for u64x4<S> {
8452 #[inline(always)]
8453 fn simd_from(simd: S, value: u64) -> Self {
8454 simd.splat_u64x4(value)
8455 }
8456}
8457impl<S: Simd> core::ops::Index<usize> for u64x4<S> {
8458 type Output = u64;
8459 #[inline(always)]
8460 fn index(&self, i: usize) -> &Self::Output {
8461 &self.as_array()[i]
8462 }
8463}
8464impl<S: Simd> core::ops::IndexMut<usize> for u64x4<S> {
8465 #[inline(always)]
8466 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
8467 &mut self.as_mut_array()[i]
8468 }
8469}
8470impl<S: Simd> Select<u64x4<S>> for mask64x4<S> {
8471 #[inline(always)]
8472 fn select(self, if_true: u64x4<S>, if_false: u64x4<S>) -> u64x4<S> {
8473 self.simd.select_u64x4(self, if_true, if_false)
8474 }
8475}
8476impl<S: Simd> Bytes for u64x4<S> {
8477 type Bytes = u8x32<S>;
8478 #[inline(always)]
8479 fn to_bytes(self) -> Self::Bytes {
8480 u8x32 {
8481 val: crate::transmute::checked_transmute_copy(&self.val),
8482 simd: self.simd,
8483 }
8484 }
8485 #[inline(always)]
8486 fn from_bytes(value: Self::Bytes) -> Self {
8487 Self {
8488 val: crate::transmute::checked_transmute_copy(&value.val),
8489 simd: value.simd,
8490 }
8491 }
8492}
8493impl<S: Simd> SimdBase<S> for u64x4<S> {
8494 type Element = u64;
8495 type ByteVector = u8x32<S>;
8496 const LEN: usize = 4;
8497 type Mask = mask64x4<S>;
8498 type Block = u64x2<S>;
8499 type Array = [u64; 4];
8500 #[inline(always)]
8501 fn as_slice(&self) -> &[u64] {
8502 self.as_array().as_slice()
8503 }
8504 #[inline(always)]
8505 fn as_mut_slice(&mut self) -> &mut [u64] {
8506 self.as_mut_array().as_mut_slice()
8507 }
8508 #[inline(always)]
8509 fn from_slice(simd: S, slice: &[u64]) -> Self {
8510 Self::load_array_ref(simd, slice.try_into().unwrap())
8511 }
8512 #[inline(always)]
8513 fn store_slice(&self, slice: &mut [u64]) {
8514 (*self).store_array(slice.try_into().unwrap());
8515 }
8516 #[inline(always)]
8517 fn splat(simd: S, val: u64) -> Self {
8518 simd.splat_u64x4(val)
8519 }
8520 #[inline(always)]
8521 fn block_splat(block: Self::Block) -> Self {
8522 block.simd.combine_u64x2(block, block)
8523 }
8524 #[inline(always)]
8525 fn from_fn(simd: S, mut f: impl FnMut(usize) -> u64) -> Self {
8526 Self::load_array(simd, [f(0usize), f(1usize), f(2usize), f(3usize)])
8527 }
8528 #[inline(always)]
8529 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
8530 self.simd
8531 .slide_u64x4::<SHIFT>(self, rhs.simd_into(self.simd))
8532 }
8533 #[inline(always)]
8534 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
8535 self.simd
8536 .slide_within_blocks_u64x4::<SHIFT>(self, rhs.simd_into(self.simd))
8537 }
8538 #[inline(always)]
8539 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
8540 self.simd
8541 .swizzle_dyn_within_blocks_u64x4(self, indices.simd_into(self.simd))
8542 }
8543 #[inline(always)]
8544 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
8545 self.simd
8546 .swizzle_dyn_u64x4(self, indices.simd_into(self.simd))
8547 }
8548 #[inline(always)]
8549 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
8550 self.simd
8551 .swizzle_dyn_precise_u64x4(self, indices.simd_into(self.simd))
8552 }
8553 #[inline(always)]
8554 fn abs(self) -> Self {
8555 self.simd.abs_u64x4(self)
8556 }
8557 #[inline(always)]
8558 fn reverse(self) -> Self {
8559 self.simd.reverse_u64x4(self)
8560 }
8561 #[inline(always)]
8562 fn concat_swizzle_dyn(
8563 self,
8564 rhs: impl SimdInto<Self, S>,
8565 indices: impl SimdInto<Self::Bytes, S>,
8566 ) -> Self {
8567 self.simd.concat_swizzle_dyn_u64x4(
8568 self,
8569 rhs.simd_into(self.simd),
8570 indices.simd_into(self.simd),
8571 )
8572 }
8573 #[inline(always)]
8574 fn concat_swizzle_dyn_precise(
8575 self,
8576 rhs: impl SimdInto<Self, S>,
8577 indices: impl SimdInto<Self::Bytes, S>,
8578 ) -> Self {
8579 self.simd.concat_swizzle_dyn_precise_u64x4(
8580 self,
8581 rhs.simd_into(self.simd),
8582 indices.simd_into(self.simd),
8583 )
8584 }
8585 #[inline(always)]
8586 fn compress(self, mask: Self::Mask) -> Self {
8587 self.simd.compress_u64x4(self, mask)
8588 }
8589 #[inline(always)]
8590 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
8591 self.simd
8592 .compress_merge_u64x4(self, mask, merge.simd_into(self.simd))
8593 }
8594 #[inline(always)]
8595 fn expand(self, mask: Self::Mask) -> Self {
8596 self.simd.expand_u64x4(self, mask)
8597 }
8598 #[inline(always)]
8599 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
8600 self.simd
8601 .expand_merge_u64x4(self, mask, merge.simd_into(self.simd))
8602 }
8603 #[inline(always)]
8604 fn reduce_max(self) -> Self::Element {
8605 self.simd.reduce_max_u64x4(self)
8606 }
8607 #[inline(always)]
8608 fn reduce_min(self) -> Self::Element {
8609 self.simd.reduce_min_u64x4(self)
8610 }
8611 #[inline(always)]
8612 fn reduce_max_precise(self) -> Self::Element {
8613 self.simd.reduce_max_u64x4(self)
8614 }
8615 #[inline(always)]
8616 fn reduce_min_precise(self) -> Self::Element {
8617 self.simd.reduce_min_u64x4(self)
8618 }
8619 #[inline(always)]
8620 fn reduce_sum(self) -> Self::Element {
8621 self.simd.reduce_sum_u64x4(self)
8622 }
8623 #[inline(always)]
8624 fn reduce_product(self) -> Self::Element {
8625 self.simd.reduce_product_u64x4(self)
8626 }
8627 #[inline(always)]
8628 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
8629 self.simd.max_u64x4(self, rhs.simd_into(self.simd))
8630 }
8631 #[inline(always)]
8632 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
8633 self.simd.min_u64x4(self, rhs.simd_into(self.simd))
8634 }
8635 #[inline(always)]
8636 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
8637 self.simd.max_u64x4(self, rhs.simd_into(self.simd))
8638 }
8639 #[inline(always)]
8640 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
8641 self.simd.min_u64x4(self, rhs.simd_into(self.simd))
8642 }
8643 #[inline(always)]
8644 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
8645 self.simd
8646 .clamp_u64x4(self, min.simd_into(self.simd), max.simd_into(self.simd))
8647 }
8648 #[inline(always)]
8649 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
8650 self.simd.simd_eq_u64x4(self, rhs.simd_into(self.simd))
8651 }
8652 #[inline(always)]
8653 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
8654 self.simd.simd_ne_u64x4(self, rhs.simd_into(self.simd))
8655 }
8656 #[inline(always)]
8657 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
8658 self.simd.simd_lt_u64x4(self, rhs.simd_into(self.simd))
8659 }
8660 #[inline(always)]
8661 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
8662 self.simd.simd_le_u64x4(self, rhs.simd_into(self.simd))
8663 }
8664 #[inline(always)]
8665 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
8666 self.simd.simd_ge_u64x4(self, rhs.simd_into(self.simd))
8667 }
8668 #[inline(always)]
8669 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
8670 self.simd.simd_gt_u64x4(self, rhs.simd_into(self.simd))
8671 }
8672 #[inline(always)]
8673 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
8674 self.simd.zip_low_u64x4(self, rhs.simd_into(self.simd))
8675 }
8676 #[inline(always)]
8677 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
8678 self.simd.zip_high_u64x4(self, rhs.simd_into(self.simd))
8679 }
8680 #[inline(always)]
8681 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
8682 self.simd.unzip_low_u64x4(self, rhs.simd_into(self.simd))
8683 }
8684 #[inline(always)]
8685 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
8686 self.simd.unzip_high_u64x4(self, rhs.simd_into(self.simd))
8687 }
8688 #[inline(always)]
8689 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
8690 self.simd.interleave_u64x4(self, rhs.simd_into(self.simd))
8691 }
8692 #[inline(always)]
8693 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
8694 self.simd.deinterleave_u64x4(self, rhs.simd_into(self.simd))
8695 }
8696}
8697impl<S: Simd> crate::SimdInt<S> for u64x4<S> {
8698 #[inline(always)]
8699 fn count_ones(self) -> Self {
8700 self.simd.count_ones_u64x4(self)
8701 }
8702 #[inline(always)]
8703 fn count_zeros(self) -> Self {
8704 self.simd.count_zeros_u64x4(self)
8705 }
8706 #[inline(always)]
8707 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
8708 self.simd
8709 .saturating_add_u64x4(self, rhs.simd_into(self.simd))
8710 }
8711 #[inline(always)]
8712 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
8713 self.simd
8714 .saturating_sub_u64x4(self, rhs.simd_into(self.simd))
8715 }
8716}
8717impl<S: Simd> SimdCvtTruncate<f64x4<S>> for u64x4<S> {
8718 #[doc = "Convert each floating-point element to an unsigned 64-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
8719 #[inline(always)]
8720 fn truncate_from(x: f64x4<S>) -> Self {
8721 x.simd.cvt_u64_f64x4(x)
8722 }
8723 #[doc = "Convert each floating-point element to an unsigned 64-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
8724 #[inline(always)]
8725 fn truncate_from_precise(x: f64x4<S>) -> Self {
8726 x.simd.cvt_u64_precise_f64x4(x)
8727 }
8728}
8729impl<S: Simd> SimdNarrow<S> for u64x4<S> {
8730 type Narrowed = u32x8<S>;
8731 #[inline(always)]
8732 fn narrow(self, high: Self) -> Self::Narrowed {
8733 self.simd.narrow_u64x4(self, high)
8734 }
8735 #[inline(always)]
8736 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
8737 self.simd.saturating_narrow_u64x4(self, high)
8738 }
8739 #[inline(always)]
8740 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
8741 self.simd.relaxed_narrow_u64x4(self, high)
8742 }
8743}
8744impl<S: Simd> crate::SimdSplit<S> for u64x4<S> {
8745 type Split = u64x2<S>;
8746 #[inline(always)]
8747 fn split(self) -> (Self::Split, Self::Split) {
8748 self.simd.split_u64x4(self)
8749 }
8750}
8751impl<S: Simd> crate::SimdCombine<S> for u64x4<S> {
8752 type Combined = u64x8<S>;
8753 #[inline(always)]
8754 fn combine(self, rhs: impl SimdInto<Self, S>) -> Self::Combined {
8755 self.simd.combine_u64x4(self, rhs.simd_into(self.simd))
8756 }
8757}
8758impl<S: Simd> ExtractToken for mask64x4<S> {
8759 type S = S;
8760 #[inline]
8761 fn token(&self) -> S {
8762 self.simd
8763 }
8764}
8765#[doc = "A SIMD mask of 4 logical lanes corresponding to 64-bit vector elements.\n\nThe storage representation of this type is intentionally opaque and may vary depending on the SIMD level.\n\nYou can construct this mask type using the [`Self::splat`], [`Self::from_bitmask`], [`Self::from_slice`], and [`Self::simd_from`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, mask64x4};\nfn construct_mask<S: Simd>(simd: S) {\n // From a single boolean value:\n let a = mask64x4::splat(simd, true);\n let b = mask64x4::simd_from(simd, true);\n\n // From signed integer mask lanes:\n let c = mask64x4::from_slice(simd, &[-1, 0, 0, 0]);\n let d = mask64x4::simd_from(simd, [-1, 0, 0, 0]);\n\n // From a compact bitmask (same mask as above, least significant bit maps to lane 0):\n let e = mask64x4::from_bitmask(simd, 0b0001);\n\n // By setting individual lanes:\n let mut f = mask64x4::splat(simd, false);\n f.set(0, true);\n}\n```"]
8766#[derive(Clone, Copy)]
8767pub struct mask64x4<S: Simd> {
8768 pub(crate) val: S::mask64x4,
8769 pub(crate) simd: S,
8770}
8771impl<S: Simd> Seal for mask64x4<S> {}
8772impl<S: Simd> SimdFrom<[i64; 4], S> for mask64x4<S> {
8773 #[inline(always)]
8774 fn simd_from(simd: S, val: [i64; 4]) -> Self {
8775 Self {
8776 val: <S as crate::arch_types::ArchTypes>::mask64x4_from_array(simd, val),
8777 simd,
8778 }
8779 }
8780}
8781impl<S: Simd> From<mask64x4<S>> for [i64; 4] {
8782 #[inline(always)]
8783 fn from(value: mask64x4<S>) -> Self {
8784 <S as crate::arch_types::ArchTypes>::mask64x4_to_array(value.simd, value.val)
8785 }
8786}
8787impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask64x4<S> {
8788 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8789 let lanes: [i64; 4] = (*self).into();
8790 crate::support::simd_debug_impl(f, "mask64x4", &self.simd, &lanes)
8791 }
8792}
8793impl<S: Simd> SimdFrom<bool, S> for mask64x4<S> {
8794 #[inline(always)]
8795 fn simd_from(simd: S, value: bool) -> Self {
8796 simd.splat_mask64x4(value)
8797 }
8798}
8799impl<S: Simd> Select<mask64x4<S>> for mask64x4<S> {
8800 #[inline(always)]
8801 fn select(self, if_true: mask64x4<S>, if_false: mask64x4<S>) -> mask64x4<S> {
8802 self.simd.select_mask64x4(self, if_true, if_false)
8803 }
8804}
8805impl<S: Simd> SimdMask<S> for mask64x4<S> {
8806 type Element = i64;
8807 type Ints = i64x4<S>;
8808 const LEN: usize = 4;
8809 #[inline(always)]
8810 fn splat(simd: S, val: bool) -> Self {
8811 simd.splat_mask64x4(val)
8812 }
8813 #[inline(always)]
8814 fn from_bitmask(simd: S, bits: u64) -> Self {
8815 simd.from_bitmask_mask64x4(bits)
8816 }
8817 #[inline(always)]
8818 fn to_bitmask(self) -> u64 {
8819 self.simd.to_bitmask_mask64x4(self)
8820 }
8821 #[inline(always)]
8822 fn from_vector(vector: Self::Ints) -> Self {
8823 vector.token().from_vector_mask64x4(vector)
8824 }
8825 #[inline(always)]
8826 fn to_vector(self) -> Self::Ints {
8827 self.simd.to_vector_mask64x4(self)
8828 }
8829 #[inline(always)]
8830 fn set(&mut self, index: usize, value: bool) {
8831 self.simd.set_mask64x4(self, index, value);
8832 }
8833 #[inline(always)]
8834 fn from_slice(simd: S, slice: &[i64]) -> Self {
8835 let slice: &[i64; 4] = slice.try_into().unwrap();
8836 Self::simd_from(simd, *slice)
8837 }
8838 #[inline(always)]
8839 fn store_slice(&self, slice: &mut [i64]) {
8840 let slice: &mut [i64; 4] = slice.try_into().unwrap();
8841 *slice = (*self).into();
8842 }
8843 #[inline(always)]
8844 fn rotate_elements_left<const OFFSET: usize>(self) -> Self {
8845 self.simd.rotate_elements_left_mask64x4::<OFFSET>(self)
8846 }
8847 #[inline(always)]
8848 fn rotate_elements_right<const OFFSET: usize>(self) -> Self {
8849 self.simd.rotate_elements_right_mask64x4::<OFFSET>(self)
8850 }
8851 #[inline(always)]
8852 fn reverse(self) -> Self {
8853 self.simd.reverse_mask64x4(self)
8854 }
8855 #[inline(always)]
8856 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self {
8857 self.simd.simd_eq_mask64x4(self, rhs.simd_into(self.simd))
8858 }
8859 #[inline(always)]
8860 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self {
8861 self.simd.simd_ne_mask64x4(self, rhs.simd_into(self.simd))
8862 }
8863 #[inline(always)]
8864 fn any_true(self) -> bool {
8865 self.simd.any_true_mask64x4(self)
8866 }
8867 #[inline(always)]
8868 fn all_true(self) -> bool {
8869 self.simd.all_true_mask64x4(self)
8870 }
8871 #[inline(always)]
8872 fn any_false(self) -> bool {
8873 self.simd.any_false_mask64x4(self)
8874 }
8875 #[inline(always)]
8876 fn all_false(self) -> bool {
8877 self.simd.all_false_mask64x4(self)
8878 }
8879}
8880impl<S: Simd> MaskNarrow<S> for mask64x4<S> {
8881 type Narrowed = mask32x8<S>;
8882 #[inline(always)]
8883 fn narrow(self, high: Self) -> Self::Narrowed {
8884 self.simd.narrow_mask64x4(self, high)
8885 }
8886}
8887impl<S: Simd> ExtractToken for f32x16<S> {
8888 type S = S;
8889 #[inline]
8890 fn token(&self) -> S {
8891 self.simd
8892 }
8893}
8894#[doc = "A SIMD vector of 16 [`f32`] elements.\n\nThis type's memory layout is identical to that of [`[f32; 16]`](prim@array), except that it is aligned to 64 bytes.\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```"]
8895#[derive(Clone, Copy)]
8896#[repr(C, align(64))]
8897pub struct f32x16<S: Simd> {
8898 pub(crate) val: S::f32x16,
8899 pub simd: S,
8900}
8901impl<S: Simd> Seal for f32x16<S> {}
8902impl<S: Simd> SimdFrom<[f32; 16], S> for f32x16<S> {
8903 #[inline(always)]
8904 fn simd_from(simd: S, val: [f32; 16]) -> Self {
8905 Self {
8906 val: crate::transmute::checked_transmute_copy(&val),
8907 simd,
8908 }
8909 }
8910}
8911impl<S: Simd> From<f32x16<S>> for [f32; 16] {
8912 #[inline(always)]
8913 fn from(value: f32x16<S>) -> Self {
8914 crate::transmute::checked_transmute_copy(&value.val)
8915 }
8916}
8917impl<S: Simd> core::ops::Deref for f32x16<S> {
8918 type Target = [f32; 16];
8919 #[inline(always)]
8920 fn deref(&self) -> &Self::Target {
8921 crate::transmute::checked_cast_ref(&self.val)
8922 }
8923}
8924impl<S: Simd> core::ops::DerefMut for f32x16<S> {
8925 #[inline(always)]
8926 fn deref_mut(&mut self) -> &mut Self::Target {
8927 crate::transmute::checked_cast_mut(&mut self.val)
8928 }
8929}
8930impl<S: Simd + core::fmt::Debug> core::fmt::Debug for f32x16<S> {
8931 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8932 crate::support::simd_debug_impl(f, "f32x16", &self.simd, self.as_array())
8933 }
8934}
8935impl<S: Simd> SimdFrom<f32, S> for f32x16<S> {
8936 #[inline(always)]
8937 fn simd_from(simd: S, value: f32) -> Self {
8938 simd.splat_f32x16(value)
8939 }
8940}
8941impl<S: Simd> core::ops::Index<usize> for f32x16<S> {
8942 type Output = f32;
8943 #[inline(always)]
8944 fn index(&self, i: usize) -> &Self::Output {
8945 &self.as_array()[i]
8946 }
8947}
8948impl<S: Simd> core::ops::IndexMut<usize> for f32x16<S> {
8949 #[inline(always)]
8950 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
8951 &mut self.as_mut_array()[i]
8952 }
8953}
8954impl<S: Simd> Select<f32x16<S>> for mask32x16<S> {
8955 #[inline(always)]
8956 fn select(self, if_true: f32x16<S>, if_false: f32x16<S>) -> f32x16<S> {
8957 self.simd.select_f32x16(self, if_true, if_false)
8958 }
8959}
8960impl<S: Simd> Bytes for f32x16<S> {
8961 type Bytes = u8x64<S>;
8962 #[inline(always)]
8963 fn to_bytes(self) -> Self::Bytes {
8964 u8x64 {
8965 val: crate::transmute::checked_transmute_copy(&self.val),
8966 simd: self.simd,
8967 }
8968 }
8969 #[inline(always)]
8970 fn from_bytes(value: Self::Bytes) -> Self {
8971 Self {
8972 val: crate::transmute::checked_transmute_copy(&value.val),
8973 simd: value.simd,
8974 }
8975 }
8976}
8977impl<S: Simd> SimdBase<S> for f32x16<S> {
8978 type Element = f32;
8979 type ByteVector = u8x64<S>;
8980 const LEN: usize = 16;
8981 type Mask = mask32x16<S>;
8982 type Block = f32x4<S>;
8983 type Array = [f32; 16];
8984 #[inline(always)]
8985 fn as_slice(&self) -> &[f32] {
8986 self.as_array().as_slice()
8987 }
8988 #[inline(always)]
8989 fn as_mut_slice(&mut self) -> &mut [f32] {
8990 self.as_mut_array().as_mut_slice()
8991 }
8992 #[inline(always)]
8993 fn from_slice(simd: S, slice: &[f32]) -> Self {
8994 Self::load_array_ref(simd, slice.try_into().unwrap())
8995 }
8996 #[inline(always)]
8997 fn store_slice(&self, slice: &mut [f32]) {
8998 (*self).store_array(slice.try_into().unwrap());
8999 }
9000 #[inline(always)]
9001 fn splat(simd: S, val: f32) -> Self {
9002 simd.splat_f32x16(val)
9003 }
9004 #[inline(always)]
9005 fn block_splat(block: Self::Block) -> Self {
9006 let block2 = block.simd.combine_f32x4(block, block);
9007 block2.simd.combine_f32x8(block2, block2)
9008 }
9009 #[inline(always)]
9010 fn from_fn(simd: S, mut f: impl FnMut(usize) -> f32) -> Self {
9011 Self::load_array(
9012 simd,
9013 [
9014 f(0usize),
9015 f(1usize),
9016 f(2usize),
9017 f(3usize),
9018 f(4usize),
9019 f(5usize),
9020 f(6usize),
9021 f(7usize),
9022 f(8usize),
9023 f(9usize),
9024 f(10usize),
9025 f(11usize),
9026 f(12usize),
9027 f(13usize),
9028 f(14usize),
9029 f(15usize),
9030 ],
9031 )
9032 }
9033 #[inline(always)]
9034 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
9035 self.simd
9036 .slide_f32x16::<SHIFT>(self, rhs.simd_into(self.simd))
9037 }
9038 #[inline(always)]
9039 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
9040 self.simd
9041 .slide_within_blocks_f32x16::<SHIFT>(self, rhs.simd_into(self.simd))
9042 }
9043 #[inline(always)]
9044 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
9045 self.simd
9046 .swizzle_dyn_within_blocks_f32x16(self, indices.simd_into(self.simd))
9047 }
9048 #[inline(always)]
9049 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
9050 self.simd
9051 .swizzle_dyn_f32x16(self, indices.simd_into(self.simd))
9052 }
9053 #[inline(always)]
9054 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
9055 self.simd
9056 .swizzle_dyn_precise_f32x16(self, indices.simd_into(self.simd))
9057 }
9058 #[inline(always)]
9059 fn abs(self) -> Self {
9060 self.simd.abs_f32x16(self)
9061 }
9062 #[inline(always)]
9063 fn reverse(self) -> Self {
9064 self.simd.reverse_f32x16(self)
9065 }
9066 #[inline(always)]
9067 fn concat_swizzle_dyn(
9068 self,
9069 rhs: impl SimdInto<Self, S>,
9070 indices: impl SimdInto<Self::Bytes, S>,
9071 ) -> Self {
9072 self.simd.concat_swizzle_dyn_f32x16(
9073 self,
9074 rhs.simd_into(self.simd),
9075 indices.simd_into(self.simd),
9076 )
9077 }
9078 #[inline(always)]
9079 fn concat_swizzle_dyn_precise(
9080 self,
9081 rhs: impl SimdInto<Self, S>,
9082 indices: impl SimdInto<Self::Bytes, S>,
9083 ) -> Self {
9084 self.simd.concat_swizzle_dyn_precise_f32x16(
9085 self,
9086 rhs.simd_into(self.simd),
9087 indices.simd_into(self.simd),
9088 )
9089 }
9090 #[inline(always)]
9091 fn compress(self, mask: Self::Mask) -> Self {
9092 self.simd.compress_f32x16(self, mask)
9093 }
9094 #[inline(always)]
9095 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
9096 self.simd
9097 .compress_merge_f32x16(self, mask, merge.simd_into(self.simd))
9098 }
9099 #[inline(always)]
9100 fn expand(self, mask: Self::Mask) -> Self {
9101 self.simd.expand_f32x16(self, mask)
9102 }
9103 #[inline(always)]
9104 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
9105 self.simd
9106 .expand_merge_f32x16(self, mask, merge.simd_into(self.simd))
9107 }
9108 #[inline(always)]
9109 fn reduce_max(self) -> Self::Element {
9110 self.simd.reduce_max_f32x16(self)
9111 }
9112 #[inline(always)]
9113 fn reduce_min(self) -> Self::Element {
9114 self.simd.reduce_min_f32x16(self)
9115 }
9116 #[inline(always)]
9117 fn reduce_max_precise(self) -> Self::Element {
9118 self.simd.reduce_max_precise_f32x16(self)
9119 }
9120 #[inline(always)]
9121 fn reduce_min_precise(self) -> Self::Element {
9122 self.simd.reduce_min_precise_f32x16(self)
9123 }
9124 #[inline(always)]
9125 fn reduce_sum(self) -> Self::Element {
9126 self.simd.reduce_sum_f32x16(self)
9127 }
9128 #[inline(always)]
9129 fn reduce_product(self) -> Self::Element {
9130 self.simd.reduce_product_f32x16(self)
9131 }
9132 #[inline(always)]
9133 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
9134 self.simd.max_f32x16(self, rhs.simd_into(self.simd))
9135 }
9136 #[inline(always)]
9137 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
9138 self.simd.min_f32x16(self, rhs.simd_into(self.simd))
9139 }
9140 #[inline(always)]
9141 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
9142 self.simd.max_precise_f32x16(self, rhs.simd_into(self.simd))
9143 }
9144 #[inline(always)]
9145 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
9146 self.simd.min_precise_f32x16(self, rhs.simd_into(self.simd))
9147 }
9148 #[inline(always)]
9149 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
9150 self.simd
9151 .clamp_f32x16(self, min.simd_into(self.simd), max.simd_into(self.simd))
9152 }
9153 #[inline(always)]
9154 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
9155 self.simd.simd_eq_f32x16(self, rhs.simd_into(self.simd))
9156 }
9157 #[inline(always)]
9158 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
9159 self.simd.simd_ne_f32x16(self, rhs.simd_into(self.simd))
9160 }
9161 #[inline(always)]
9162 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
9163 self.simd.simd_lt_f32x16(self, rhs.simd_into(self.simd))
9164 }
9165 #[inline(always)]
9166 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
9167 self.simd.simd_le_f32x16(self, rhs.simd_into(self.simd))
9168 }
9169 #[inline(always)]
9170 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
9171 self.simd.simd_ge_f32x16(self, rhs.simd_into(self.simd))
9172 }
9173 #[inline(always)]
9174 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
9175 self.simd.simd_gt_f32x16(self, rhs.simd_into(self.simd))
9176 }
9177 #[inline(always)]
9178 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
9179 self.simd.zip_low_f32x16(self, rhs.simd_into(self.simd))
9180 }
9181 #[inline(always)]
9182 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
9183 self.simd.zip_high_f32x16(self, rhs.simd_into(self.simd))
9184 }
9185 #[inline(always)]
9186 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
9187 self.simd.unzip_low_f32x16(self, rhs.simd_into(self.simd))
9188 }
9189 #[inline(always)]
9190 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
9191 self.simd.unzip_high_f32x16(self, rhs.simd_into(self.simd))
9192 }
9193 #[inline(always)]
9194 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
9195 self.simd.interleave_f32x16(self, rhs.simd_into(self.simd))
9196 }
9197 #[inline(always)]
9198 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
9199 self.simd
9200 .deinterleave_f32x16(self, rhs.simd_into(self.simd))
9201 }
9202}
9203impl<S: Simd> crate::SimdFloat<S> for f32x16<S> {
9204 type Bits = u32x16<S>;
9205 #[inline(always)]
9206 fn sqrt(self) -> Self {
9207 self.simd.sqrt_f32x16(self)
9208 }
9209 #[inline(always)]
9210 fn approximate_recip(self) -> Self {
9211 self.simd.approximate_recip_f32x16(self)
9212 }
9213 #[inline(always)]
9214 fn copysign(self, rhs: impl SimdInto<Self, S>) -> Self {
9215 self.simd.copysign_f32x16(self, rhs.simd_into(self.simd))
9216 }
9217 #[inline(always)]
9218 fn mul_add(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
9219 self.simd
9220 .mul_add_f32x16(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
9221 }
9222 #[inline(always)]
9223 fn mul_add_precise(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
9224 self.simd
9225 .mul_add_precise_f32x16(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
9226 }
9227 #[inline(always)]
9228 fn mul_sub(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
9229 self.simd
9230 .mul_sub_f32x16(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
9231 }
9232 #[inline(always)]
9233 fn mul_sub_precise(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
9234 self.simd
9235 .mul_sub_precise_f32x16(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
9236 }
9237 #[inline(always)]
9238 fn floor(self) -> Self {
9239 self.simd.floor_f32x16(self)
9240 }
9241 #[inline(always)]
9242 fn ceil(self) -> Self {
9243 self.simd.ceil_f32x16(self)
9244 }
9245 #[inline(always)]
9246 fn round_ties_even(self) -> Self {
9247 self.simd.round_ties_even_f32x16(self)
9248 }
9249 #[inline(always)]
9250 fn round(self) -> Self {
9251 self.simd.round_f32x16(self)
9252 }
9253 #[inline(always)]
9254 fn fract(self) -> Self {
9255 self.simd.fract_f32x16(self)
9256 }
9257 #[inline(always)]
9258 fn trunc(self) -> Self {
9259 self.simd.trunc_f32x16(self)
9260 }
9261 #[inline(always)]
9262 fn to_degrees(self) -> Self {
9263 self.simd.to_degrees_f32x16(self)
9264 }
9265 #[inline(always)]
9266 fn to_radians(self) -> Self {
9267 self.simd.to_radians_f32x16(self)
9268 }
9269 #[inline(always)]
9270 fn is_nan(self) -> Self::Mask {
9271 self.simd.is_nan_f32x16(self)
9272 }
9273 #[inline(always)]
9274 fn is_infinite(self) -> Self::Mask {
9275 self.simd.is_infinite_f32x16(self)
9276 }
9277 #[inline(always)]
9278 fn is_finite(self) -> Self::Mask {
9279 self.simd.is_finite_f32x16(self)
9280 }
9281 #[inline(always)]
9282 fn is_subnormal(self) -> Self::Mask {
9283 self.simd.is_subnormal_f32x16(self)
9284 }
9285 #[inline(always)]
9286 fn is_normal(self) -> Self::Mask {
9287 self.simd.is_normal_f32x16(self)
9288 }
9289 #[inline(always)]
9290 fn is_sign_positive(self) -> Self::Mask {
9291 self.simd.is_sign_positive_f32x16(self)
9292 }
9293 #[inline(always)]
9294 fn is_sign_negative(self) -> Self::Mask {
9295 self.simd.is_sign_negative_f32x16(self)
9296 }
9297}
9298impl<S: Simd> SimdCvtFloat<u32x16<S>> for f32x16<S> {
9299 #[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."]
9300 #[inline(always)]
9301 fn float_from(x: u32x16<S>) -> Self {
9302 x.simd.cvt_f32_u32x16(x)
9303 }
9304}
9305impl<S: Simd> SimdCvtFloat<i32x16<S>> for f32x16<S> {
9306 #[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."]
9307 #[inline(always)]
9308 fn float_from(x: i32x16<S>) -> Self {
9309 x.simd.cvt_f32_i32x16(x)
9310 }
9311}
9312impl<S: Simd> SimdWiden<S> for f32x16<S> {
9313 type Widened = f64x8<S>;
9314 #[inline(always)]
9315 fn widen(self) -> (Self::Widened, Self::Widened) {
9316 self.simd.widen_f32x16(self)
9317 }
9318}
9319impl<S: Simd> crate::SimdSplit<S> for f32x16<S> {
9320 type Split = f32x8<S>;
9321 #[inline(always)]
9322 fn split(self) -> (Self::Split, Self::Split) {
9323 self.simd.split_f32x16(self)
9324 }
9325}
9326impl<S: Simd> ExtractToken for i8x64<S> {
9327 type S = S;
9328 #[inline]
9329 fn token(&self) -> S {
9330 self.simd
9331 }
9332}
9333#[doc = "A SIMD vector of 64 [`i8`] elements.\n\nThis type's memory layout is identical to that of [`[i8; 64]`](prim@array), except that it is aligned to 64 bytes.\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```"]
9334#[derive(Clone, Copy)]
9335#[repr(C, align(64))]
9336pub struct i8x64<S: Simd> {
9337 pub(crate) val: S::i8x64,
9338 pub simd: S,
9339}
9340impl<S: Simd> Seal for i8x64<S> {}
9341impl<S: Simd> SimdFrom<[i8; 64], S> for i8x64<S> {
9342 #[inline(always)]
9343 fn simd_from(simd: S, val: [i8; 64]) -> Self {
9344 Self {
9345 val: crate::transmute::checked_transmute_copy(&val),
9346 simd,
9347 }
9348 }
9349}
9350impl<S: Simd> From<i8x64<S>> for [i8; 64] {
9351 #[inline(always)]
9352 fn from(value: i8x64<S>) -> Self {
9353 crate::transmute::checked_transmute_copy(&value.val)
9354 }
9355}
9356impl<S: Simd> core::ops::Deref for i8x64<S> {
9357 type Target = [i8; 64];
9358 #[inline(always)]
9359 fn deref(&self) -> &Self::Target {
9360 crate::transmute::checked_cast_ref(&self.val)
9361 }
9362}
9363impl<S: Simd> core::ops::DerefMut for i8x64<S> {
9364 #[inline(always)]
9365 fn deref_mut(&mut self) -> &mut Self::Target {
9366 crate::transmute::checked_cast_mut(&mut self.val)
9367 }
9368}
9369impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i8x64<S> {
9370 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9371 crate::support::simd_debug_impl(f, "i8x64", &self.simd, self.as_array())
9372 }
9373}
9374impl<S: Simd> SimdFrom<i8, S> for i8x64<S> {
9375 #[inline(always)]
9376 fn simd_from(simd: S, value: i8) -> Self {
9377 simd.splat_i8x64(value)
9378 }
9379}
9380impl<S: Simd> core::ops::Index<usize> for i8x64<S> {
9381 type Output = i8;
9382 #[inline(always)]
9383 fn index(&self, i: usize) -> &Self::Output {
9384 &self.as_array()[i]
9385 }
9386}
9387impl<S: Simd> core::ops::IndexMut<usize> for i8x64<S> {
9388 #[inline(always)]
9389 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
9390 &mut self.as_mut_array()[i]
9391 }
9392}
9393impl<S: Simd> Select<i8x64<S>> for mask8x64<S> {
9394 #[inline(always)]
9395 fn select(self, if_true: i8x64<S>, if_false: i8x64<S>) -> i8x64<S> {
9396 self.simd.select_i8x64(self, if_true, if_false)
9397 }
9398}
9399impl<S: Simd> Bytes for i8x64<S> {
9400 type Bytes = u8x64<S>;
9401 #[inline(always)]
9402 fn to_bytes(self) -> Self::Bytes {
9403 u8x64 {
9404 val: crate::transmute::checked_transmute_copy(&self.val),
9405 simd: self.simd,
9406 }
9407 }
9408 #[inline(always)]
9409 fn from_bytes(value: Self::Bytes) -> Self {
9410 Self {
9411 val: crate::transmute::checked_transmute_copy(&value.val),
9412 simd: value.simd,
9413 }
9414 }
9415}
9416impl<S: Simd> SimdBase<S> for i8x64<S> {
9417 type Element = i8;
9418 type ByteVector = u8x64<S>;
9419 const LEN: usize = 64;
9420 type Mask = mask8x64<S>;
9421 type Block = i8x16<S>;
9422 type Array = [i8; 64];
9423 #[inline(always)]
9424 fn as_slice(&self) -> &[i8] {
9425 self.as_array().as_slice()
9426 }
9427 #[inline(always)]
9428 fn as_mut_slice(&mut self) -> &mut [i8] {
9429 self.as_mut_array().as_mut_slice()
9430 }
9431 #[inline(always)]
9432 fn from_slice(simd: S, slice: &[i8]) -> Self {
9433 Self::load_array_ref(simd, slice.try_into().unwrap())
9434 }
9435 #[inline(always)]
9436 fn store_slice(&self, slice: &mut [i8]) {
9437 (*self).store_array(slice.try_into().unwrap());
9438 }
9439 #[inline(always)]
9440 fn splat(simd: S, val: i8) -> Self {
9441 simd.splat_i8x64(val)
9442 }
9443 #[inline(always)]
9444 fn block_splat(block: Self::Block) -> Self {
9445 let block2 = block.simd.combine_i8x16(block, block);
9446 block2.simd.combine_i8x32(block2, block2)
9447 }
9448 #[inline(always)]
9449 fn from_fn(simd: S, mut f: impl FnMut(usize) -> i8) -> Self {
9450 Self::load_array(
9451 simd,
9452 [
9453 f(0usize),
9454 f(1usize),
9455 f(2usize),
9456 f(3usize),
9457 f(4usize),
9458 f(5usize),
9459 f(6usize),
9460 f(7usize),
9461 f(8usize),
9462 f(9usize),
9463 f(10usize),
9464 f(11usize),
9465 f(12usize),
9466 f(13usize),
9467 f(14usize),
9468 f(15usize),
9469 f(16usize),
9470 f(17usize),
9471 f(18usize),
9472 f(19usize),
9473 f(20usize),
9474 f(21usize),
9475 f(22usize),
9476 f(23usize),
9477 f(24usize),
9478 f(25usize),
9479 f(26usize),
9480 f(27usize),
9481 f(28usize),
9482 f(29usize),
9483 f(30usize),
9484 f(31usize),
9485 f(32usize),
9486 f(33usize),
9487 f(34usize),
9488 f(35usize),
9489 f(36usize),
9490 f(37usize),
9491 f(38usize),
9492 f(39usize),
9493 f(40usize),
9494 f(41usize),
9495 f(42usize),
9496 f(43usize),
9497 f(44usize),
9498 f(45usize),
9499 f(46usize),
9500 f(47usize),
9501 f(48usize),
9502 f(49usize),
9503 f(50usize),
9504 f(51usize),
9505 f(52usize),
9506 f(53usize),
9507 f(54usize),
9508 f(55usize),
9509 f(56usize),
9510 f(57usize),
9511 f(58usize),
9512 f(59usize),
9513 f(60usize),
9514 f(61usize),
9515 f(62usize),
9516 f(63usize),
9517 ],
9518 )
9519 }
9520 #[inline(always)]
9521 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
9522 self.simd
9523 .slide_i8x64::<SHIFT>(self, rhs.simd_into(self.simd))
9524 }
9525 #[inline(always)]
9526 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
9527 self.simd
9528 .slide_within_blocks_i8x64::<SHIFT>(self, rhs.simd_into(self.simd))
9529 }
9530 #[inline(always)]
9531 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
9532 self.simd
9533 .swizzle_dyn_within_blocks_i8x64(self, indices.simd_into(self.simd))
9534 }
9535 #[inline(always)]
9536 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
9537 self.simd
9538 .swizzle_dyn_i8x64(self, indices.simd_into(self.simd))
9539 }
9540 #[inline(always)]
9541 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
9542 self.simd
9543 .swizzle_dyn_precise_i8x64(self, indices.simd_into(self.simd))
9544 }
9545 #[inline(always)]
9546 fn abs(self) -> Self {
9547 self.simd.abs_i8x64(self)
9548 }
9549 #[inline(always)]
9550 fn reverse(self) -> Self {
9551 self.simd.reverse_i8x64(self)
9552 }
9553 #[inline(always)]
9554 fn concat_swizzle_dyn(
9555 self,
9556 rhs: impl SimdInto<Self, S>,
9557 indices: impl SimdInto<Self::Bytes, S>,
9558 ) -> Self {
9559 self.simd.concat_swizzle_dyn_i8x64(
9560 self,
9561 rhs.simd_into(self.simd),
9562 indices.simd_into(self.simd),
9563 )
9564 }
9565 #[inline(always)]
9566 fn concat_swizzle_dyn_precise(
9567 self,
9568 rhs: impl SimdInto<Self, S>,
9569 indices: impl SimdInto<Self::Bytes, S>,
9570 ) -> Self {
9571 self.simd.concat_swizzle_dyn_precise_i8x64(
9572 self,
9573 rhs.simd_into(self.simd),
9574 indices.simd_into(self.simd),
9575 )
9576 }
9577 #[inline(always)]
9578 fn compress(self, mask: Self::Mask) -> Self {
9579 self.simd.compress_i8x64(self, mask)
9580 }
9581 #[inline(always)]
9582 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
9583 self.simd
9584 .compress_merge_i8x64(self, mask, merge.simd_into(self.simd))
9585 }
9586 #[inline(always)]
9587 fn expand(self, mask: Self::Mask) -> Self {
9588 self.simd.expand_i8x64(self, mask)
9589 }
9590 #[inline(always)]
9591 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
9592 self.simd
9593 .expand_merge_i8x64(self, mask, merge.simd_into(self.simd))
9594 }
9595 #[inline(always)]
9596 fn reduce_max(self) -> Self::Element {
9597 self.simd.reduce_max_i8x64(self)
9598 }
9599 #[inline(always)]
9600 fn reduce_min(self) -> Self::Element {
9601 self.simd.reduce_min_i8x64(self)
9602 }
9603 #[inline(always)]
9604 fn reduce_max_precise(self) -> Self::Element {
9605 self.simd.reduce_max_i8x64(self)
9606 }
9607 #[inline(always)]
9608 fn reduce_min_precise(self) -> Self::Element {
9609 self.simd.reduce_min_i8x64(self)
9610 }
9611 #[inline(always)]
9612 fn reduce_sum(self) -> Self::Element {
9613 self.simd.reduce_sum_i8x64(self)
9614 }
9615 #[inline(always)]
9616 fn reduce_product(self) -> Self::Element {
9617 self.simd.reduce_product_i8x64(self)
9618 }
9619 #[inline(always)]
9620 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
9621 self.simd.max_i8x64(self, rhs.simd_into(self.simd))
9622 }
9623 #[inline(always)]
9624 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
9625 self.simd.min_i8x64(self, rhs.simd_into(self.simd))
9626 }
9627 #[inline(always)]
9628 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
9629 self.simd.max_i8x64(self, rhs.simd_into(self.simd))
9630 }
9631 #[inline(always)]
9632 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
9633 self.simd.min_i8x64(self, rhs.simd_into(self.simd))
9634 }
9635 #[inline(always)]
9636 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
9637 self.simd
9638 .clamp_i8x64(self, min.simd_into(self.simd), max.simd_into(self.simd))
9639 }
9640 #[inline(always)]
9641 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
9642 self.simd.simd_eq_i8x64(self, rhs.simd_into(self.simd))
9643 }
9644 #[inline(always)]
9645 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
9646 self.simd.simd_ne_i8x64(self, rhs.simd_into(self.simd))
9647 }
9648 #[inline(always)]
9649 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
9650 self.simd.simd_lt_i8x64(self, rhs.simd_into(self.simd))
9651 }
9652 #[inline(always)]
9653 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
9654 self.simd.simd_le_i8x64(self, rhs.simd_into(self.simd))
9655 }
9656 #[inline(always)]
9657 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
9658 self.simd.simd_ge_i8x64(self, rhs.simd_into(self.simd))
9659 }
9660 #[inline(always)]
9661 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
9662 self.simd.simd_gt_i8x64(self, rhs.simd_into(self.simd))
9663 }
9664 #[inline(always)]
9665 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
9666 self.simd.zip_low_i8x64(self, rhs.simd_into(self.simd))
9667 }
9668 #[inline(always)]
9669 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
9670 self.simd.zip_high_i8x64(self, rhs.simd_into(self.simd))
9671 }
9672 #[inline(always)]
9673 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
9674 self.simd.unzip_low_i8x64(self, rhs.simd_into(self.simd))
9675 }
9676 #[inline(always)]
9677 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
9678 self.simd.unzip_high_i8x64(self, rhs.simd_into(self.simd))
9679 }
9680 #[inline(always)]
9681 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
9682 self.simd.interleave_i8x64(self, rhs.simd_into(self.simd))
9683 }
9684 #[inline(always)]
9685 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
9686 self.simd.deinterleave_i8x64(self, rhs.simd_into(self.simd))
9687 }
9688}
9689impl<S: Simd> crate::SimdInt<S> for i8x64<S> {
9690 #[inline(always)]
9691 fn count_ones(self) -> Self {
9692 self.simd.count_ones_i8x64(self)
9693 }
9694 #[inline(always)]
9695 fn count_zeros(self) -> Self {
9696 self.simd.count_zeros_i8x64(self)
9697 }
9698 #[inline(always)]
9699 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
9700 self.simd
9701 .saturating_add_i8x64(self, rhs.simd_into(self.simd))
9702 }
9703 #[inline(always)]
9704 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
9705 self.simd
9706 .saturating_sub_i8x64(self, rhs.simd_into(self.simd))
9707 }
9708}
9709impl<S: Simd> SimdWiden<S> for i8x64<S> {
9710 type Widened = i16x32<S>;
9711 #[inline(always)]
9712 fn widen(self) -> (Self::Widened, Self::Widened) {
9713 self.simd.widen_i8x64(self)
9714 }
9715}
9716impl<S: Simd> SimdIntWiden<S> for i8x64<S> {
9717 #[inline(always)]
9718 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
9719 self.simd.widening_mul_i8x64(self, rhs.simd_into(self.simd))
9720 }
9721 #[inline(always)]
9722 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
9723 self.simd.widening_add_i8x64(self, rhs.simd_into(self.simd))
9724 }
9725 #[inline(always)]
9726 fn pairwise_widening_add(self) -> Self::Widened {
9727 self.simd.pairwise_widening_add_i8x64(self)
9728 }
9729 #[inline(always)]
9730 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
9731 self.simd
9732 .pairwise_dot_product_i8x64(self, rhs.simd_into(self.simd))
9733 }
9734}
9735impl<S: Simd> crate::SimdSplit<S> for i8x64<S> {
9736 type Split = i8x32<S>;
9737 #[inline(always)]
9738 fn split(self) -> (Self::Split, Self::Split) {
9739 self.simd.split_i8x64(self)
9740 }
9741}
9742impl<S: Simd> ExtractToken for u8x64<S> {
9743 type S = S;
9744 #[inline]
9745 fn token(&self) -> S {
9746 self.simd
9747 }
9748}
9749#[doc = "A SIMD vector of 64 [`u8`] elements.\n\nThis type's memory layout is identical to that of [`[u8; 64]`](prim@array), except that it is aligned to 64 bytes.\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```"]
9750#[derive(Clone, Copy)]
9751#[repr(C, align(64))]
9752pub struct u8x64<S: Simd> {
9753 pub(crate) val: S::u8x64,
9754 pub simd: S,
9755}
9756impl<S: Simd> Seal for u8x64<S> {}
9757impl<S: Simd> SimdFrom<[u8; 64], S> for u8x64<S> {
9758 #[inline(always)]
9759 fn simd_from(simd: S, val: [u8; 64]) -> Self {
9760 Self {
9761 val: crate::transmute::checked_transmute_copy(&val),
9762 simd,
9763 }
9764 }
9765}
9766impl<S: Simd> From<u8x64<S>> for [u8; 64] {
9767 #[inline(always)]
9768 fn from(value: u8x64<S>) -> Self {
9769 crate::transmute::checked_transmute_copy(&value.val)
9770 }
9771}
9772impl<S: Simd> core::ops::Deref for u8x64<S> {
9773 type Target = [u8; 64];
9774 #[inline(always)]
9775 fn deref(&self) -> &Self::Target {
9776 crate::transmute::checked_cast_ref(&self.val)
9777 }
9778}
9779impl<S: Simd> core::ops::DerefMut for u8x64<S> {
9780 #[inline(always)]
9781 fn deref_mut(&mut self) -> &mut Self::Target {
9782 crate::transmute::checked_cast_mut(&mut self.val)
9783 }
9784}
9785impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u8x64<S> {
9786 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9787 crate::support::simd_debug_impl(f, "u8x64", &self.simd, self.as_array())
9788 }
9789}
9790impl<S: Simd> SimdFrom<u8, S> for u8x64<S> {
9791 #[inline(always)]
9792 fn simd_from(simd: S, value: u8) -> Self {
9793 simd.splat_u8x64(value)
9794 }
9795}
9796impl<S: Simd> core::ops::Index<usize> for u8x64<S> {
9797 type Output = u8;
9798 #[inline(always)]
9799 fn index(&self, i: usize) -> &Self::Output {
9800 &self.as_array()[i]
9801 }
9802}
9803impl<S: Simd> core::ops::IndexMut<usize> for u8x64<S> {
9804 #[inline(always)]
9805 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
9806 &mut self.as_mut_array()[i]
9807 }
9808}
9809impl<S: Simd> Select<u8x64<S>> for mask8x64<S> {
9810 #[inline(always)]
9811 fn select(self, if_true: u8x64<S>, if_false: u8x64<S>) -> u8x64<S> {
9812 self.simd.select_u8x64(self, if_true, if_false)
9813 }
9814}
9815impl<S: Simd> Bytes for u8x64<S> {
9816 type Bytes = u8x64<S>;
9817 #[inline(always)]
9818 fn to_bytes(self) -> Self::Bytes {
9819 u8x64 {
9820 val: crate::transmute::checked_transmute_copy(&self.val),
9821 simd: self.simd,
9822 }
9823 }
9824 #[inline(always)]
9825 fn from_bytes(value: Self::Bytes) -> Self {
9826 Self {
9827 val: crate::transmute::checked_transmute_copy(&value.val),
9828 simd: value.simd,
9829 }
9830 }
9831}
9832impl<S: Simd> SimdBase<S> for u8x64<S> {
9833 type Element = u8;
9834 type ByteVector = u8x64<S>;
9835 const LEN: usize = 64;
9836 type Mask = mask8x64<S>;
9837 type Block = u8x16<S>;
9838 type Array = [u8; 64];
9839 #[inline(always)]
9840 fn as_slice(&self) -> &[u8] {
9841 self.as_array().as_slice()
9842 }
9843 #[inline(always)]
9844 fn as_mut_slice(&mut self) -> &mut [u8] {
9845 self.as_mut_array().as_mut_slice()
9846 }
9847 #[inline(always)]
9848 fn from_slice(simd: S, slice: &[u8]) -> Self {
9849 Self::load_array_ref(simd, slice.try_into().unwrap())
9850 }
9851 #[inline(always)]
9852 fn store_slice(&self, slice: &mut [u8]) {
9853 (*self).store_array(slice.try_into().unwrap());
9854 }
9855 #[inline(always)]
9856 fn splat(simd: S, val: u8) -> Self {
9857 simd.splat_u8x64(val)
9858 }
9859 #[inline(always)]
9860 fn block_splat(block: Self::Block) -> Self {
9861 let block2 = block.simd.combine_u8x16(block, block);
9862 block2.simd.combine_u8x32(block2, block2)
9863 }
9864 #[inline(always)]
9865 fn from_fn(simd: S, mut f: impl FnMut(usize) -> u8) -> Self {
9866 Self::load_array(
9867 simd,
9868 [
9869 f(0usize),
9870 f(1usize),
9871 f(2usize),
9872 f(3usize),
9873 f(4usize),
9874 f(5usize),
9875 f(6usize),
9876 f(7usize),
9877 f(8usize),
9878 f(9usize),
9879 f(10usize),
9880 f(11usize),
9881 f(12usize),
9882 f(13usize),
9883 f(14usize),
9884 f(15usize),
9885 f(16usize),
9886 f(17usize),
9887 f(18usize),
9888 f(19usize),
9889 f(20usize),
9890 f(21usize),
9891 f(22usize),
9892 f(23usize),
9893 f(24usize),
9894 f(25usize),
9895 f(26usize),
9896 f(27usize),
9897 f(28usize),
9898 f(29usize),
9899 f(30usize),
9900 f(31usize),
9901 f(32usize),
9902 f(33usize),
9903 f(34usize),
9904 f(35usize),
9905 f(36usize),
9906 f(37usize),
9907 f(38usize),
9908 f(39usize),
9909 f(40usize),
9910 f(41usize),
9911 f(42usize),
9912 f(43usize),
9913 f(44usize),
9914 f(45usize),
9915 f(46usize),
9916 f(47usize),
9917 f(48usize),
9918 f(49usize),
9919 f(50usize),
9920 f(51usize),
9921 f(52usize),
9922 f(53usize),
9923 f(54usize),
9924 f(55usize),
9925 f(56usize),
9926 f(57usize),
9927 f(58usize),
9928 f(59usize),
9929 f(60usize),
9930 f(61usize),
9931 f(62usize),
9932 f(63usize),
9933 ],
9934 )
9935 }
9936 #[inline(always)]
9937 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
9938 self.simd
9939 .slide_u8x64::<SHIFT>(self, rhs.simd_into(self.simd))
9940 }
9941 #[inline(always)]
9942 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
9943 self.simd
9944 .slide_within_blocks_u8x64::<SHIFT>(self, rhs.simd_into(self.simd))
9945 }
9946 #[inline(always)]
9947 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
9948 self.simd
9949 .swizzle_dyn_within_blocks_u8x64(self, indices.simd_into(self.simd))
9950 }
9951 #[inline(always)]
9952 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
9953 self.simd
9954 .swizzle_dyn_u8x64(self, indices.simd_into(self.simd))
9955 }
9956 #[inline(always)]
9957 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
9958 self.simd
9959 .swizzle_dyn_precise_u8x64(self, indices.simd_into(self.simd))
9960 }
9961 #[inline(always)]
9962 fn abs(self) -> Self {
9963 self.simd.abs_u8x64(self)
9964 }
9965 #[inline(always)]
9966 fn reverse(self) -> Self {
9967 self.simd.reverse_u8x64(self)
9968 }
9969 #[inline(always)]
9970 fn concat_swizzle_dyn(
9971 self,
9972 rhs: impl SimdInto<Self, S>,
9973 indices: impl SimdInto<Self::Bytes, S>,
9974 ) -> Self {
9975 self.simd.concat_swizzle_dyn_u8x64(
9976 self,
9977 rhs.simd_into(self.simd),
9978 indices.simd_into(self.simd),
9979 )
9980 }
9981 #[inline(always)]
9982 fn concat_swizzle_dyn_precise(
9983 self,
9984 rhs: impl SimdInto<Self, S>,
9985 indices: impl SimdInto<Self::Bytes, S>,
9986 ) -> Self {
9987 self.simd.concat_swizzle_dyn_precise_u8x64(
9988 self,
9989 rhs.simd_into(self.simd),
9990 indices.simd_into(self.simd),
9991 )
9992 }
9993 #[inline(always)]
9994 fn compress(self, mask: Self::Mask) -> Self {
9995 self.simd.compress_u8x64(self, mask)
9996 }
9997 #[inline(always)]
9998 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
9999 self.simd
10000 .compress_merge_u8x64(self, mask, merge.simd_into(self.simd))
10001 }
10002 #[inline(always)]
10003 fn expand(self, mask: Self::Mask) -> Self {
10004 self.simd.expand_u8x64(self, mask)
10005 }
10006 #[inline(always)]
10007 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
10008 self.simd
10009 .expand_merge_u8x64(self, mask, merge.simd_into(self.simd))
10010 }
10011 #[inline(always)]
10012 fn reduce_max(self) -> Self::Element {
10013 self.simd.reduce_max_u8x64(self)
10014 }
10015 #[inline(always)]
10016 fn reduce_min(self) -> Self::Element {
10017 self.simd.reduce_min_u8x64(self)
10018 }
10019 #[inline(always)]
10020 fn reduce_max_precise(self) -> Self::Element {
10021 self.simd.reduce_max_u8x64(self)
10022 }
10023 #[inline(always)]
10024 fn reduce_min_precise(self) -> Self::Element {
10025 self.simd.reduce_min_u8x64(self)
10026 }
10027 #[inline(always)]
10028 fn reduce_sum(self) -> Self::Element {
10029 self.simd.reduce_sum_u8x64(self)
10030 }
10031 #[inline(always)]
10032 fn reduce_product(self) -> Self::Element {
10033 self.simd.reduce_product_u8x64(self)
10034 }
10035 #[inline(always)]
10036 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
10037 self.simd.max_u8x64(self, rhs.simd_into(self.simd))
10038 }
10039 #[inline(always)]
10040 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
10041 self.simd.min_u8x64(self, rhs.simd_into(self.simd))
10042 }
10043 #[inline(always)]
10044 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
10045 self.simd.max_u8x64(self, rhs.simd_into(self.simd))
10046 }
10047 #[inline(always)]
10048 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
10049 self.simd.min_u8x64(self, rhs.simd_into(self.simd))
10050 }
10051 #[inline(always)]
10052 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
10053 self.simd
10054 .clamp_u8x64(self, min.simd_into(self.simd), max.simd_into(self.simd))
10055 }
10056 #[inline(always)]
10057 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10058 self.simd.simd_eq_u8x64(self, rhs.simd_into(self.simd))
10059 }
10060 #[inline(always)]
10061 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10062 self.simd.simd_ne_u8x64(self, rhs.simd_into(self.simd))
10063 }
10064 #[inline(always)]
10065 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10066 self.simd.simd_lt_u8x64(self, rhs.simd_into(self.simd))
10067 }
10068 #[inline(always)]
10069 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10070 self.simd.simd_le_u8x64(self, rhs.simd_into(self.simd))
10071 }
10072 #[inline(always)]
10073 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10074 self.simd.simd_ge_u8x64(self, rhs.simd_into(self.simd))
10075 }
10076 #[inline(always)]
10077 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10078 self.simd.simd_gt_u8x64(self, rhs.simd_into(self.simd))
10079 }
10080 #[inline(always)]
10081 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
10082 self.simd.zip_low_u8x64(self, rhs.simd_into(self.simd))
10083 }
10084 #[inline(always)]
10085 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
10086 self.simd.zip_high_u8x64(self, rhs.simd_into(self.simd))
10087 }
10088 #[inline(always)]
10089 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
10090 self.simd.unzip_low_u8x64(self, rhs.simd_into(self.simd))
10091 }
10092 #[inline(always)]
10093 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
10094 self.simd.unzip_high_u8x64(self, rhs.simd_into(self.simd))
10095 }
10096 #[inline(always)]
10097 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
10098 self.simd.interleave_u8x64(self, rhs.simd_into(self.simd))
10099 }
10100 #[inline(always)]
10101 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
10102 self.simd.deinterleave_u8x64(self, rhs.simd_into(self.simd))
10103 }
10104}
10105impl<S: Simd> crate::SimdInt<S> for u8x64<S> {
10106 #[inline(always)]
10107 fn count_ones(self) -> Self {
10108 self.simd.count_ones_u8x64(self)
10109 }
10110 #[inline(always)]
10111 fn count_zeros(self) -> Self {
10112 self.simd.count_zeros_u8x64(self)
10113 }
10114 #[inline(always)]
10115 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
10116 self.simd
10117 .saturating_add_u8x64(self, rhs.simd_into(self.simd))
10118 }
10119 #[inline(always)]
10120 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
10121 self.simd
10122 .saturating_sub_u8x64(self, rhs.simd_into(self.simd))
10123 }
10124}
10125impl<S: Simd> SimdWiden<S> for u8x64<S> {
10126 type Widened = u16x32<S>;
10127 #[inline(always)]
10128 fn widen(self) -> (Self::Widened, Self::Widened) {
10129 self.simd.widen_u8x64(self)
10130 }
10131}
10132impl<S: Simd> SimdIntWiden<S> for u8x64<S> {
10133 #[inline(always)]
10134 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
10135 self.simd.widening_mul_u8x64(self, rhs.simd_into(self.simd))
10136 }
10137 #[inline(always)]
10138 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
10139 self.simd.widening_add_u8x64(self, rhs.simd_into(self.simd))
10140 }
10141 #[inline(always)]
10142 fn pairwise_widening_add(self) -> Self::Widened {
10143 self.simd.pairwise_widening_add_u8x64(self)
10144 }
10145 #[inline(always)]
10146 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
10147 self.simd
10148 .pairwise_dot_product_u8x64(self, rhs.simd_into(self.simd))
10149 }
10150}
10151impl<S: Simd> crate::SimdSplit<S> for u8x64<S> {
10152 type Split = u8x32<S>;
10153 #[inline(always)]
10154 fn split(self) -> (Self::Split, Self::Split) {
10155 self.simd.split_u8x64(self)
10156 }
10157}
10158impl<S: Simd> ExtractToken for mask8x64<S> {
10159 type S = S;
10160 #[inline]
10161 fn token(&self) -> S {
10162 self.simd
10163 }
10164}
10165#[doc = "A SIMD mask of 64 logical lanes corresponding to 8-bit vector elements.\n\nThe storage representation of this type is intentionally opaque and may vary depending on the SIMD level.\n\nYou can construct this mask type using the [`Self::splat`], [`Self::from_bitmask`], [`Self::from_slice`], and [`Self::simd_from`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, mask8x64};\nfn construct_mask<S: Simd>(simd: S) {\n // From a single boolean value:\n let a = mask8x64::splat(simd, true);\n let b = mask8x64::simd_from(simd, true);\n\n // From signed integer mask lanes:\n let c = mask8x64::from_slice(simd, &[-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);\n let d = mask8x64::simd_from(simd, [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);\n\n // From a compact bitmask (same mask as above, least significant bit maps to lane 0):\n let e = mask8x64::from_bitmask(simd, 0b0001);\n\n // By setting individual lanes:\n let mut f = mask8x64::splat(simd, false);\n f.set(0, true);\n}\n```"]
10166#[derive(Clone, Copy)]
10167pub struct mask8x64<S: Simd> {
10168 pub(crate) val: S::mask8x64,
10169 pub(crate) simd: S,
10170}
10171impl<S: Simd> Seal for mask8x64<S> {}
10172impl<S: Simd> SimdFrom<[i8; 64], S> for mask8x64<S> {
10173 #[inline(always)]
10174 fn simd_from(simd: S, val: [i8; 64]) -> Self {
10175 Self {
10176 val: <S as crate::arch_types::ArchTypes>::mask8x64_from_array(simd, val),
10177 simd,
10178 }
10179 }
10180}
10181impl<S: Simd> From<mask8x64<S>> for [i8; 64] {
10182 #[inline(always)]
10183 fn from(value: mask8x64<S>) -> Self {
10184 <S as crate::arch_types::ArchTypes>::mask8x64_to_array(value.simd, value.val)
10185 }
10186}
10187impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask8x64<S> {
10188 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10189 let lanes: [i8; 64] = (*self).into();
10190 crate::support::simd_debug_impl(f, "mask8x64", &self.simd, &lanes)
10191 }
10192}
10193impl<S: Simd> SimdFrom<bool, S> for mask8x64<S> {
10194 #[inline(always)]
10195 fn simd_from(simd: S, value: bool) -> Self {
10196 simd.splat_mask8x64(value)
10197 }
10198}
10199impl<S: Simd> Select<mask8x64<S>> for mask8x64<S> {
10200 #[inline(always)]
10201 fn select(self, if_true: mask8x64<S>, if_false: mask8x64<S>) -> mask8x64<S> {
10202 self.simd.select_mask8x64(self, if_true, if_false)
10203 }
10204}
10205impl<S: Simd> SimdMask<S> for mask8x64<S> {
10206 type Element = i8;
10207 type Ints = i8x64<S>;
10208 const LEN: usize = 64;
10209 #[inline(always)]
10210 fn splat(simd: S, val: bool) -> Self {
10211 simd.splat_mask8x64(val)
10212 }
10213 #[inline(always)]
10214 fn from_bitmask(simd: S, bits: u64) -> Self {
10215 simd.from_bitmask_mask8x64(bits)
10216 }
10217 #[inline(always)]
10218 fn to_bitmask(self) -> u64 {
10219 self.simd.to_bitmask_mask8x64(self)
10220 }
10221 #[inline(always)]
10222 fn from_vector(vector: Self::Ints) -> Self {
10223 vector.token().from_vector_mask8x64(vector)
10224 }
10225 #[inline(always)]
10226 fn to_vector(self) -> Self::Ints {
10227 self.simd.to_vector_mask8x64(self)
10228 }
10229 #[inline(always)]
10230 fn set(&mut self, index: usize, value: bool) {
10231 self.simd.set_mask8x64(self, index, value);
10232 }
10233 #[inline(always)]
10234 fn from_slice(simd: S, slice: &[i8]) -> Self {
10235 let slice: &[i8; 64] = slice.try_into().unwrap();
10236 Self::simd_from(simd, *slice)
10237 }
10238 #[inline(always)]
10239 fn store_slice(&self, slice: &mut [i8]) {
10240 let slice: &mut [i8; 64] = slice.try_into().unwrap();
10241 *slice = (*self).into();
10242 }
10243 #[inline(always)]
10244 fn rotate_elements_left<const OFFSET: usize>(self) -> Self {
10245 self.simd.rotate_elements_left_mask8x64::<OFFSET>(self)
10246 }
10247 #[inline(always)]
10248 fn rotate_elements_right<const OFFSET: usize>(self) -> Self {
10249 self.simd.rotate_elements_right_mask8x64::<OFFSET>(self)
10250 }
10251 #[inline(always)]
10252 fn reverse(self) -> Self {
10253 self.simd.reverse_mask8x64(self)
10254 }
10255 #[inline(always)]
10256 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self {
10257 self.simd.simd_eq_mask8x64(self, rhs.simd_into(self.simd))
10258 }
10259 #[inline(always)]
10260 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self {
10261 self.simd.simd_ne_mask8x64(self, rhs.simd_into(self.simd))
10262 }
10263 #[inline(always)]
10264 fn any_true(self) -> bool {
10265 self.simd.any_true_mask8x64(self)
10266 }
10267 #[inline(always)]
10268 fn all_true(self) -> bool {
10269 self.simd.all_true_mask8x64(self)
10270 }
10271 #[inline(always)]
10272 fn any_false(self) -> bool {
10273 self.simd.any_false_mask8x64(self)
10274 }
10275 #[inline(always)]
10276 fn all_false(self) -> bool {
10277 self.simd.all_false_mask8x64(self)
10278 }
10279}
10280impl<S: Simd> MaskWiden<S> for mask8x64<S> {
10281 type Widened = mask16x32<S>;
10282 #[inline(always)]
10283 fn widen(self) -> (Self::Widened, Self::Widened) {
10284 self.simd.widen_mask8x64(self)
10285 }
10286}
10287impl<S: Simd> ExtractToken for i16x32<S> {
10288 type S = S;
10289 #[inline]
10290 fn token(&self) -> S {
10291 self.simd
10292 }
10293}
10294#[doc = "A SIMD vector of 32 [`i16`] elements.\n\nThis type's memory layout is identical to that of [`[i16; 32]`](prim@array), except that it is aligned to 64 bytes.\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```"]
10295#[derive(Clone, Copy)]
10296#[repr(C, align(64))]
10297pub struct i16x32<S: Simd> {
10298 pub(crate) val: S::i16x32,
10299 pub simd: S,
10300}
10301impl<S: Simd> Seal for i16x32<S> {}
10302impl<S: Simd> SimdFrom<[i16; 32], S> for i16x32<S> {
10303 #[inline(always)]
10304 fn simd_from(simd: S, val: [i16; 32]) -> Self {
10305 Self {
10306 val: crate::transmute::checked_transmute_copy(&val),
10307 simd,
10308 }
10309 }
10310}
10311impl<S: Simd> From<i16x32<S>> for [i16; 32] {
10312 #[inline(always)]
10313 fn from(value: i16x32<S>) -> Self {
10314 crate::transmute::checked_transmute_copy(&value.val)
10315 }
10316}
10317impl<S: Simd> core::ops::Deref for i16x32<S> {
10318 type Target = [i16; 32];
10319 #[inline(always)]
10320 fn deref(&self) -> &Self::Target {
10321 crate::transmute::checked_cast_ref(&self.val)
10322 }
10323}
10324impl<S: Simd> core::ops::DerefMut for i16x32<S> {
10325 #[inline(always)]
10326 fn deref_mut(&mut self) -> &mut Self::Target {
10327 crate::transmute::checked_cast_mut(&mut self.val)
10328 }
10329}
10330impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i16x32<S> {
10331 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10332 crate::support::simd_debug_impl(f, "i16x32", &self.simd, self.as_array())
10333 }
10334}
10335impl<S: Simd> SimdFrom<i16, S> for i16x32<S> {
10336 #[inline(always)]
10337 fn simd_from(simd: S, value: i16) -> Self {
10338 simd.splat_i16x32(value)
10339 }
10340}
10341impl<S: Simd> core::ops::Index<usize> for i16x32<S> {
10342 type Output = i16;
10343 #[inline(always)]
10344 fn index(&self, i: usize) -> &Self::Output {
10345 &self.as_array()[i]
10346 }
10347}
10348impl<S: Simd> core::ops::IndexMut<usize> for i16x32<S> {
10349 #[inline(always)]
10350 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
10351 &mut self.as_mut_array()[i]
10352 }
10353}
10354impl<S: Simd> Select<i16x32<S>> for mask16x32<S> {
10355 #[inline(always)]
10356 fn select(self, if_true: i16x32<S>, if_false: i16x32<S>) -> i16x32<S> {
10357 self.simd.select_i16x32(self, if_true, if_false)
10358 }
10359}
10360impl<S: Simd> Bytes for i16x32<S> {
10361 type Bytes = u8x64<S>;
10362 #[inline(always)]
10363 fn to_bytes(self) -> Self::Bytes {
10364 u8x64 {
10365 val: crate::transmute::checked_transmute_copy(&self.val),
10366 simd: self.simd,
10367 }
10368 }
10369 #[inline(always)]
10370 fn from_bytes(value: Self::Bytes) -> Self {
10371 Self {
10372 val: crate::transmute::checked_transmute_copy(&value.val),
10373 simd: value.simd,
10374 }
10375 }
10376}
10377impl<S: Simd> SimdBase<S> for i16x32<S> {
10378 type Element = i16;
10379 type ByteVector = u8x64<S>;
10380 const LEN: usize = 32;
10381 type Mask = mask16x32<S>;
10382 type Block = i16x8<S>;
10383 type Array = [i16; 32];
10384 #[inline(always)]
10385 fn as_slice(&self) -> &[i16] {
10386 self.as_array().as_slice()
10387 }
10388 #[inline(always)]
10389 fn as_mut_slice(&mut self) -> &mut [i16] {
10390 self.as_mut_array().as_mut_slice()
10391 }
10392 #[inline(always)]
10393 fn from_slice(simd: S, slice: &[i16]) -> Self {
10394 Self::load_array_ref(simd, slice.try_into().unwrap())
10395 }
10396 #[inline(always)]
10397 fn store_slice(&self, slice: &mut [i16]) {
10398 (*self).store_array(slice.try_into().unwrap());
10399 }
10400 #[inline(always)]
10401 fn splat(simd: S, val: i16) -> Self {
10402 simd.splat_i16x32(val)
10403 }
10404 #[inline(always)]
10405 fn block_splat(block: Self::Block) -> Self {
10406 let block2 = block.simd.combine_i16x8(block, block);
10407 block2.simd.combine_i16x16(block2, block2)
10408 }
10409 #[inline(always)]
10410 fn from_fn(simd: S, mut f: impl FnMut(usize) -> i16) -> Self {
10411 Self::load_array(
10412 simd,
10413 [
10414 f(0usize),
10415 f(1usize),
10416 f(2usize),
10417 f(3usize),
10418 f(4usize),
10419 f(5usize),
10420 f(6usize),
10421 f(7usize),
10422 f(8usize),
10423 f(9usize),
10424 f(10usize),
10425 f(11usize),
10426 f(12usize),
10427 f(13usize),
10428 f(14usize),
10429 f(15usize),
10430 f(16usize),
10431 f(17usize),
10432 f(18usize),
10433 f(19usize),
10434 f(20usize),
10435 f(21usize),
10436 f(22usize),
10437 f(23usize),
10438 f(24usize),
10439 f(25usize),
10440 f(26usize),
10441 f(27usize),
10442 f(28usize),
10443 f(29usize),
10444 f(30usize),
10445 f(31usize),
10446 ],
10447 )
10448 }
10449 #[inline(always)]
10450 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
10451 self.simd
10452 .slide_i16x32::<SHIFT>(self, rhs.simd_into(self.simd))
10453 }
10454 #[inline(always)]
10455 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
10456 self.simd
10457 .slide_within_blocks_i16x32::<SHIFT>(self, rhs.simd_into(self.simd))
10458 }
10459 #[inline(always)]
10460 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
10461 self.simd
10462 .swizzle_dyn_within_blocks_i16x32(self, indices.simd_into(self.simd))
10463 }
10464 #[inline(always)]
10465 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
10466 self.simd
10467 .swizzle_dyn_i16x32(self, indices.simd_into(self.simd))
10468 }
10469 #[inline(always)]
10470 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
10471 self.simd
10472 .swizzle_dyn_precise_i16x32(self, indices.simd_into(self.simd))
10473 }
10474 #[inline(always)]
10475 fn abs(self) -> Self {
10476 self.simd.abs_i16x32(self)
10477 }
10478 #[inline(always)]
10479 fn reverse(self) -> Self {
10480 self.simd.reverse_i16x32(self)
10481 }
10482 #[inline(always)]
10483 fn concat_swizzle_dyn(
10484 self,
10485 rhs: impl SimdInto<Self, S>,
10486 indices: impl SimdInto<Self::Bytes, S>,
10487 ) -> Self {
10488 self.simd.concat_swizzle_dyn_i16x32(
10489 self,
10490 rhs.simd_into(self.simd),
10491 indices.simd_into(self.simd),
10492 )
10493 }
10494 #[inline(always)]
10495 fn concat_swizzle_dyn_precise(
10496 self,
10497 rhs: impl SimdInto<Self, S>,
10498 indices: impl SimdInto<Self::Bytes, S>,
10499 ) -> Self {
10500 self.simd.concat_swizzle_dyn_precise_i16x32(
10501 self,
10502 rhs.simd_into(self.simd),
10503 indices.simd_into(self.simd),
10504 )
10505 }
10506 #[inline(always)]
10507 fn compress(self, mask: Self::Mask) -> Self {
10508 self.simd.compress_i16x32(self, mask)
10509 }
10510 #[inline(always)]
10511 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
10512 self.simd
10513 .compress_merge_i16x32(self, mask, merge.simd_into(self.simd))
10514 }
10515 #[inline(always)]
10516 fn expand(self, mask: Self::Mask) -> Self {
10517 self.simd.expand_i16x32(self, mask)
10518 }
10519 #[inline(always)]
10520 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
10521 self.simd
10522 .expand_merge_i16x32(self, mask, merge.simd_into(self.simd))
10523 }
10524 #[inline(always)]
10525 fn reduce_max(self) -> Self::Element {
10526 self.simd.reduce_max_i16x32(self)
10527 }
10528 #[inline(always)]
10529 fn reduce_min(self) -> Self::Element {
10530 self.simd.reduce_min_i16x32(self)
10531 }
10532 #[inline(always)]
10533 fn reduce_max_precise(self) -> Self::Element {
10534 self.simd.reduce_max_i16x32(self)
10535 }
10536 #[inline(always)]
10537 fn reduce_min_precise(self) -> Self::Element {
10538 self.simd.reduce_min_i16x32(self)
10539 }
10540 #[inline(always)]
10541 fn reduce_sum(self) -> Self::Element {
10542 self.simd.reduce_sum_i16x32(self)
10543 }
10544 #[inline(always)]
10545 fn reduce_product(self) -> Self::Element {
10546 self.simd.reduce_product_i16x32(self)
10547 }
10548 #[inline(always)]
10549 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
10550 self.simd.max_i16x32(self, rhs.simd_into(self.simd))
10551 }
10552 #[inline(always)]
10553 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
10554 self.simd.min_i16x32(self, rhs.simd_into(self.simd))
10555 }
10556 #[inline(always)]
10557 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
10558 self.simd.max_i16x32(self, rhs.simd_into(self.simd))
10559 }
10560 #[inline(always)]
10561 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
10562 self.simd.min_i16x32(self, rhs.simd_into(self.simd))
10563 }
10564 #[inline(always)]
10565 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
10566 self.simd
10567 .clamp_i16x32(self, min.simd_into(self.simd), max.simd_into(self.simd))
10568 }
10569 #[inline(always)]
10570 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10571 self.simd.simd_eq_i16x32(self, rhs.simd_into(self.simd))
10572 }
10573 #[inline(always)]
10574 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10575 self.simd.simd_ne_i16x32(self, rhs.simd_into(self.simd))
10576 }
10577 #[inline(always)]
10578 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10579 self.simd.simd_lt_i16x32(self, rhs.simd_into(self.simd))
10580 }
10581 #[inline(always)]
10582 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10583 self.simd.simd_le_i16x32(self, rhs.simd_into(self.simd))
10584 }
10585 #[inline(always)]
10586 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10587 self.simd.simd_ge_i16x32(self, rhs.simd_into(self.simd))
10588 }
10589 #[inline(always)]
10590 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10591 self.simd.simd_gt_i16x32(self, rhs.simd_into(self.simd))
10592 }
10593 #[inline(always)]
10594 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
10595 self.simd.zip_low_i16x32(self, rhs.simd_into(self.simd))
10596 }
10597 #[inline(always)]
10598 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
10599 self.simd.zip_high_i16x32(self, rhs.simd_into(self.simd))
10600 }
10601 #[inline(always)]
10602 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
10603 self.simd.unzip_low_i16x32(self, rhs.simd_into(self.simd))
10604 }
10605 #[inline(always)]
10606 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
10607 self.simd.unzip_high_i16x32(self, rhs.simd_into(self.simd))
10608 }
10609 #[inline(always)]
10610 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
10611 self.simd.interleave_i16x32(self, rhs.simd_into(self.simd))
10612 }
10613 #[inline(always)]
10614 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
10615 self.simd
10616 .deinterleave_i16x32(self, rhs.simd_into(self.simd))
10617 }
10618}
10619impl<S: Simd> crate::SimdInt<S> for i16x32<S> {
10620 #[inline(always)]
10621 fn count_ones(self) -> Self {
10622 self.simd.count_ones_i16x32(self)
10623 }
10624 #[inline(always)]
10625 fn count_zeros(self) -> Self {
10626 self.simd.count_zeros_i16x32(self)
10627 }
10628 #[inline(always)]
10629 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
10630 self.simd
10631 .saturating_add_i16x32(self, rhs.simd_into(self.simd))
10632 }
10633 #[inline(always)]
10634 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
10635 self.simd
10636 .saturating_sub_i16x32(self, rhs.simd_into(self.simd))
10637 }
10638}
10639impl<S: Simd> SimdWiden<S> for i16x32<S> {
10640 type Widened = i32x16<S>;
10641 #[inline(always)]
10642 fn widen(self) -> (Self::Widened, Self::Widened) {
10643 self.simd.widen_i16x32(self)
10644 }
10645}
10646impl<S: Simd> SimdIntWiden<S> for i16x32<S> {
10647 #[inline(always)]
10648 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
10649 self.simd
10650 .widening_mul_i16x32(self, rhs.simd_into(self.simd))
10651 }
10652 #[inline(always)]
10653 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
10654 self.simd
10655 .widening_add_i16x32(self, rhs.simd_into(self.simd))
10656 }
10657 #[inline(always)]
10658 fn pairwise_widening_add(self) -> Self::Widened {
10659 self.simd.pairwise_widening_add_i16x32(self)
10660 }
10661 #[inline(always)]
10662 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
10663 self.simd
10664 .pairwise_dot_product_i16x32(self, rhs.simd_into(self.simd))
10665 }
10666}
10667impl<S: Simd> SimdNarrow<S> for i16x32<S> {
10668 type Narrowed = i8x64<S>;
10669 #[inline(always)]
10670 fn narrow(self, high: Self) -> Self::Narrowed {
10671 self.simd.narrow_i16x32(self, high)
10672 }
10673 #[inline(always)]
10674 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
10675 self.simd.saturating_narrow_i16x32(self, high)
10676 }
10677 #[inline(always)]
10678 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
10679 self.simd.relaxed_narrow_i16x32(self, high)
10680 }
10681}
10682impl<S: Simd> crate::SimdSplit<S> for i16x32<S> {
10683 type Split = i16x16<S>;
10684 #[inline(always)]
10685 fn split(self) -> (Self::Split, Self::Split) {
10686 self.simd.split_i16x32(self)
10687 }
10688}
10689impl<S: Simd> ExtractToken for u16x32<S> {
10690 type S = S;
10691 #[inline]
10692 fn token(&self) -> S {
10693 self.simd
10694 }
10695}
10696#[doc = "A SIMD vector of 32 [`u16`] elements.\n\nThis type's memory layout is identical to that of [`[u16; 32]`](prim@array), except that it is aligned to 64 bytes.\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```"]
10697#[derive(Clone, Copy)]
10698#[repr(C, align(64))]
10699pub struct u16x32<S: Simd> {
10700 pub(crate) val: S::u16x32,
10701 pub simd: S,
10702}
10703impl<S: Simd> Seal for u16x32<S> {}
10704impl<S: Simd> SimdFrom<[u16; 32], S> for u16x32<S> {
10705 #[inline(always)]
10706 fn simd_from(simd: S, val: [u16; 32]) -> Self {
10707 Self {
10708 val: crate::transmute::checked_transmute_copy(&val),
10709 simd,
10710 }
10711 }
10712}
10713impl<S: Simd> From<u16x32<S>> for [u16; 32] {
10714 #[inline(always)]
10715 fn from(value: u16x32<S>) -> Self {
10716 crate::transmute::checked_transmute_copy(&value.val)
10717 }
10718}
10719impl<S: Simd> core::ops::Deref for u16x32<S> {
10720 type Target = [u16; 32];
10721 #[inline(always)]
10722 fn deref(&self) -> &Self::Target {
10723 crate::transmute::checked_cast_ref(&self.val)
10724 }
10725}
10726impl<S: Simd> core::ops::DerefMut for u16x32<S> {
10727 #[inline(always)]
10728 fn deref_mut(&mut self) -> &mut Self::Target {
10729 crate::transmute::checked_cast_mut(&mut self.val)
10730 }
10731}
10732impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u16x32<S> {
10733 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
10734 crate::support::simd_debug_impl(f, "u16x32", &self.simd, self.as_array())
10735 }
10736}
10737impl<S: Simd> SimdFrom<u16, S> for u16x32<S> {
10738 #[inline(always)]
10739 fn simd_from(simd: S, value: u16) -> Self {
10740 simd.splat_u16x32(value)
10741 }
10742}
10743impl<S: Simd> core::ops::Index<usize> for u16x32<S> {
10744 type Output = u16;
10745 #[inline(always)]
10746 fn index(&self, i: usize) -> &Self::Output {
10747 &self.as_array()[i]
10748 }
10749}
10750impl<S: Simd> core::ops::IndexMut<usize> for u16x32<S> {
10751 #[inline(always)]
10752 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
10753 &mut self.as_mut_array()[i]
10754 }
10755}
10756impl<S: Simd> Select<u16x32<S>> for mask16x32<S> {
10757 #[inline(always)]
10758 fn select(self, if_true: u16x32<S>, if_false: u16x32<S>) -> u16x32<S> {
10759 self.simd.select_u16x32(self, if_true, if_false)
10760 }
10761}
10762impl<S: Simd> Bytes for u16x32<S> {
10763 type Bytes = u8x64<S>;
10764 #[inline(always)]
10765 fn to_bytes(self) -> Self::Bytes {
10766 u8x64 {
10767 val: crate::transmute::checked_transmute_copy(&self.val),
10768 simd: self.simd,
10769 }
10770 }
10771 #[inline(always)]
10772 fn from_bytes(value: Self::Bytes) -> Self {
10773 Self {
10774 val: crate::transmute::checked_transmute_copy(&value.val),
10775 simd: value.simd,
10776 }
10777 }
10778}
10779impl<S: Simd> SimdBase<S> for u16x32<S> {
10780 type Element = u16;
10781 type ByteVector = u8x64<S>;
10782 const LEN: usize = 32;
10783 type Mask = mask16x32<S>;
10784 type Block = u16x8<S>;
10785 type Array = [u16; 32];
10786 #[inline(always)]
10787 fn as_slice(&self) -> &[u16] {
10788 self.as_array().as_slice()
10789 }
10790 #[inline(always)]
10791 fn as_mut_slice(&mut self) -> &mut [u16] {
10792 self.as_mut_array().as_mut_slice()
10793 }
10794 #[inline(always)]
10795 fn from_slice(simd: S, slice: &[u16]) -> Self {
10796 Self::load_array_ref(simd, slice.try_into().unwrap())
10797 }
10798 #[inline(always)]
10799 fn store_slice(&self, slice: &mut [u16]) {
10800 (*self).store_array(slice.try_into().unwrap());
10801 }
10802 #[inline(always)]
10803 fn splat(simd: S, val: u16) -> Self {
10804 simd.splat_u16x32(val)
10805 }
10806 #[inline(always)]
10807 fn block_splat(block: Self::Block) -> Self {
10808 let block2 = block.simd.combine_u16x8(block, block);
10809 block2.simd.combine_u16x16(block2, block2)
10810 }
10811 #[inline(always)]
10812 fn from_fn(simd: S, mut f: impl FnMut(usize) -> u16) -> Self {
10813 Self::load_array(
10814 simd,
10815 [
10816 f(0usize),
10817 f(1usize),
10818 f(2usize),
10819 f(3usize),
10820 f(4usize),
10821 f(5usize),
10822 f(6usize),
10823 f(7usize),
10824 f(8usize),
10825 f(9usize),
10826 f(10usize),
10827 f(11usize),
10828 f(12usize),
10829 f(13usize),
10830 f(14usize),
10831 f(15usize),
10832 f(16usize),
10833 f(17usize),
10834 f(18usize),
10835 f(19usize),
10836 f(20usize),
10837 f(21usize),
10838 f(22usize),
10839 f(23usize),
10840 f(24usize),
10841 f(25usize),
10842 f(26usize),
10843 f(27usize),
10844 f(28usize),
10845 f(29usize),
10846 f(30usize),
10847 f(31usize),
10848 ],
10849 )
10850 }
10851 #[inline(always)]
10852 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
10853 self.simd
10854 .slide_u16x32::<SHIFT>(self, rhs.simd_into(self.simd))
10855 }
10856 #[inline(always)]
10857 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
10858 self.simd
10859 .slide_within_blocks_u16x32::<SHIFT>(self, rhs.simd_into(self.simd))
10860 }
10861 #[inline(always)]
10862 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
10863 self.simd
10864 .swizzle_dyn_within_blocks_u16x32(self, indices.simd_into(self.simd))
10865 }
10866 #[inline(always)]
10867 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
10868 self.simd
10869 .swizzle_dyn_u16x32(self, indices.simd_into(self.simd))
10870 }
10871 #[inline(always)]
10872 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
10873 self.simd
10874 .swizzle_dyn_precise_u16x32(self, indices.simd_into(self.simd))
10875 }
10876 #[inline(always)]
10877 fn abs(self) -> Self {
10878 self.simd.abs_u16x32(self)
10879 }
10880 #[inline(always)]
10881 fn reverse(self) -> Self {
10882 self.simd.reverse_u16x32(self)
10883 }
10884 #[inline(always)]
10885 fn concat_swizzle_dyn(
10886 self,
10887 rhs: impl SimdInto<Self, S>,
10888 indices: impl SimdInto<Self::Bytes, S>,
10889 ) -> Self {
10890 self.simd.concat_swizzle_dyn_u16x32(
10891 self,
10892 rhs.simd_into(self.simd),
10893 indices.simd_into(self.simd),
10894 )
10895 }
10896 #[inline(always)]
10897 fn concat_swizzle_dyn_precise(
10898 self,
10899 rhs: impl SimdInto<Self, S>,
10900 indices: impl SimdInto<Self::Bytes, S>,
10901 ) -> Self {
10902 self.simd.concat_swizzle_dyn_precise_u16x32(
10903 self,
10904 rhs.simd_into(self.simd),
10905 indices.simd_into(self.simd),
10906 )
10907 }
10908 #[inline(always)]
10909 fn compress(self, mask: Self::Mask) -> Self {
10910 self.simd.compress_u16x32(self, mask)
10911 }
10912 #[inline(always)]
10913 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
10914 self.simd
10915 .compress_merge_u16x32(self, mask, merge.simd_into(self.simd))
10916 }
10917 #[inline(always)]
10918 fn expand(self, mask: Self::Mask) -> Self {
10919 self.simd.expand_u16x32(self, mask)
10920 }
10921 #[inline(always)]
10922 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
10923 self.simd
10924 .expand_merge_u16x32(self, mask, merge.simd_into(self.simd))
10925 }
10926 #[inline(always)]
10927 fn reduce_max(self) -> Self::Element {
10928 self.simd.reduce_max_u16x32(self)
10929 }
10930 #[inline(always)]
10931 fn reduce_min(self) -> Self::Element {
10932 self.simd.reduce_min_u16x32(self)
10933 }
10934 #[inline(always)]
10935 fn reduce_max_precise(self) -> Self::Element {
10936 self.simd.reduce_max_u16x32(self)
10937 }
10938 #[inline(always)]
10939 fn reduce_min_precise(self) -> Self::Element {
10940 self.simd.reduce_min_u16x32(self)
10941 }
10942 #[inline(always)]
10943 fn reduce_sum(self) -> Self::Element {
10944 self.simd.reduce_sum_u16x32(self)
10945 }
10946 #[inline(always)]
10947 fn reduce_product(self) -> Self::Element {
10948 self.simd.reduce_product_u16x32(self)
10949 }
10950 #[inline(always)]
10951 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
10952 self.simd.max_u16x32(self, rhs.simd_into(self.simd))
10953 }
10954 #[inline(always)]
10955 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
10956 self.simd.min_u16x32(self, rhs.simd_into(self.simd))
10957 }
10958 #[inline(always)]
10959 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
10960 self.simd.max_u16x32(self, rhs.simd_into(self.simd))
10961 }
10962 #[inline(always)]
10963 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
10964 self.simd.min_u16x32(self, rhs.simd_into(self.simd))
10965 }
10966 #[inline(always)]
10967 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
10968 self.simd
10969 .clamp_u16x32(self, min.simd_into(self.simd), max.simd_into(self.simd))
10970 }
10971 #[inline(always)]
10972 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10973 self.simd.simd_eq_u16x32(self, rhs.simd_into(self.simd))
10974 }
10975 #[inline(always)]
10976 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10977 self.simd.simd_ne_u16x32(self, rhs.simd_into(self.simd))
10978 }
10979 #[inline(always)]
10980 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10981 self.simd.simd_lt_u16x32(self, rhs.simd_into(self.simd))
10982 }
10983 #[inline(always)]
10984 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10985 self.simd.simd_le_u16x32(self, rhs.simd_into(self.simd))
10986 }
10987 #[inline(always)]
10988 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10989 self.simd.simd_ge_u16x32(self, rhs.simd_into(self.simd))
10990 }
10991 #[inline(always)]
10992 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
10993 self.simd.simd_gt_u16x32(self, rhs.simd_into(self.simd))
10994 }
10995 #[inline(always)]
10996 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
10997 self.simd.zip_low_u16x32(self, rhs.simd_into(self.simd))
10998 }
10999 #[inline(always)]
11000 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
11001 self.simd.zip_high_u16x32(self, rhs.simd_into(self.simd))
11002 }
11003 #[inline(always)]
11004 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
11005 self.simd.unzip_low_u16x32(self, rhs.simd_into(self.simd))
11006 }
11007 #[inline(always)]
11008 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
11009 self.simd.unzip_high_u16x32(self, rhs.simd_into(self.simd))
11010 }
11011 #[inline(always)]
11012 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
11013 self.simd.interleave_u16x32(self, rhs.simd_into(self.simd))
11014 }
11015 #[inline(always)]
11016 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
11017 self.simd
11018 .deinterleave_u16x32(self, rhs.simd_into(self.simd))
11019 }
11020}
11021impl<S: Simd> crate::SimdInt<S> for u16x32<S> {
11022 #[inline(always)]
11023 fn count_ones(self) -> Self {
11024 self.simd.count_ones_u16x32(self)
11025 }
11026 #[inline(always)]
11027 fn count_zeros(self) -> Self {
11028 self.simd.count_zeros_u16x32(self)
11029 }
11030 #[inline(always)]
11031 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
11032 self.simd
11033 .saturating_add_u16x32(self, rhs.simd_into(self.simd))
11034 }
11035 #[inline(always)]
11036 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
11037 self.simd
11038 .saturating_sub_u16x32(self, rhs.simd_into(self.simd))
11039 }
11040}
11041impl<S: Simd> SimdWiden<S> for u16x32<S> {
11042 type Widened = u32x16<S>;
11043 #[inline(always)]
11044 fn widen(self) -> (Self::Widened, Self::Widened) {
11045 self.simd.widen_u16x32(self)
11046 }
11047}
11048impl<S: Simd> SimdIntWiden<S> for u16x32<S> {
11049 #[inline(always)]
11050 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
11051 self.simd
11052 .widening_mul_u16x32(self, rhs.simd_into(self.simd))
11053 }
11054 #[inline(always)]
11055 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
11056 self.simd
11057 .widening_add_u16x32(self, rhs.simd_into(self.simd))
11058 }
11059 #[inline(always)]
11060 fn pairwise_widening_add(self) -> Self::Widened {
11061 self.simd.pairwise_widening_add_u16x32(self)
11062 }
11063 #[inline(always)]
11064 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
11065 self.simd
11066 .pairwise_dot_product_u16x32(self, rhs.simd_into(self.simd))
11067 }
11068}
11069impl<S: Simd> SimdNarrow<S> for u16x32<S> {
11070 type Narrowed = u8x64<S>;
11071 #[inline(always)]
11072 fn narrow(self, high: Self) -> Self::Narrowed {
11073 self.simd.narrow_u16x32(self, high)
11074 }
11075 #[inline(always)]
11076 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
11077 self.simd.saturating_narrow_u16x32(self, high)
11078 }
11079 #[inline(always)]
11080 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
11081 self.simd.relaxed_narrow_u16x32(self, high)
11082 }
11083}
11084impl<S: Simd> crate::SimdSplit<S> for u16x32<S> {
11085 type Split = u16x16<S>;
11086 #[inline(always)]
11087 fn split(self) -> (Self::Split, Self::Split) {
11088 self.simd.split_u16x32(self)
11089 }
11090}
11091impl<S: Simd> ExtractToken for mask16x32<S> {
11092 type S = S;
11093 #[inline]
11094 fn token(&self) -> S {
11095 self.simd
11096 }
11097}
11098#[doc = "A SIMD mask of 32 logical lanes corresponding to 16-bit vector elements.\n\nThe storage representation of this type is intentionally opaque and may vary depending on the SIMD level.\n\nYou can construct this mask type using the [`Self::splat`], [`Self::from_bitmask`], [`Self::from_slice`], and [`Self::simd_from`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, mask16x32};\nfn construct_mask<S: Simd>(simd: S) {\n // From a single boolean value:\n let a = mask16x32::splat(simd, true);\n let b = mask16x32::simd_from(simd, true);\n\n // From signed integer mask lanes:\n let c = mask16x32::from_slice(simd, &[-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);\n let d = mask16x32::simd_from(simd, [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);\n\n // From a compact bitmask (same mask as above, least significant bit maps to lane 0):\n let e = mask16x32::from_bitmask(simd, 0b0001);\n\n // By setting individual lanes:\n let mut f = mask16x32::splat(simd, false);\n f.set(0, true);\n}\n```"]
11099#[derive(Clone, Copy)]
11100pub struct mask16x32<S: Simd> {
11101 pub(crate) val: S::mask16x32,
11102 pub(crate) simd: S,
11103}
11104impl<S: Simd> Seal for mask16x32<S> {}
11105impl<S: Simd> SimdFrom<[i16; 32], S> for mask16x32<S> {
11106 #[inline(always)]
11107 fn simd_from(simd: S, val: [i16; 32]) -> Self {
11108 Self {
11109 val: <S as crate::arch_types::ArchTypes>::mask16x32_from_array(simd, val),
11110 simd,
11111 }
11112 }
11113}
11114impl<S: Simd> From<mask16x32<S>> for [i16; 32] {
11115 #[inline(always)]
11116 fn from(value: mask16x32<S>) -> Self {
11117 <S as crate::arch_types::ArchTypes>::mask16x32_to_array(value.simd, value.val)
11118 }
11119}
11120impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask16x32<S> {
11121 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11122 let lanes: [i16; 32] = (*self).into();
11123 crate::support::simd_debug_impl(f, "mask16x32", &self.simd, &lanes)
11124 }
11125}
11126impl<S: Simd> SimdFrom<bool, S> for mask16x32<S> {
11127 #[inline(always)]
11128 fn simd_from(simd: S, value: bool) -> Self {
11129 simd.splat_mask16x32(value)
11130 }
11131}
11132impl<S: Simd> Select<mask16x32<S>> for mask16x32<S> {
11133 #[inline(always)]
11134 fn select(self, if_true: mask16x32<S>, if_false: mask16x32<S>) -> mask16x32<S> {
11135 self.simd.select_mask16x32(self, if_true, if_false)
11136 }
11137}
11138impl<S: Simd> SimdMask<S> for mask16x32<S> {
11139 type Element = i16;
11140 type Ints = i16x32<S>;
11141 const LEN: usize = 32;
11142 #[inline(always)]
11143 fn splat(simd: S, val: bool) -> Self {
11144 simd.splat_mask16x32(val)
11145 }
11146 #[inline(always)]
11147 fn from_bitmask(simd: S, bits: u64) -> Self {
11148 simd.from_bitmask_mask16x32(bits)
11149 }
11150 #[inline(always)]
11151 fn to_bitmask(self) -> u64 {
11152 self.simd.to_bitmask_mask16x32(self)
11153 }
11154 #[inline(always)]
11155 fn from_vector(vector: Self::Ints) -> Self {
11156 vector.token().from_vector_mask16x32(vector)
11157 }
11158 #[inline(always)]
11159 fn to_vector(self) -> Self::Ints {
11160 self.simd.to_vector_mask16x32(self)
11161 }
11162 #[inline(always)]
11163 fn set(&mut self, index: usize, value: bool) {
11164 self.simd.set_mask16x32(self, index, value);
11165 }
11166 #[inline(always)]
11167 fn from_slice(simd: S, slice: &[i16]) -> Self {
11168 let slice: &[i16; 32] = slice.try_into().unwrap();
11169 Self::simd_from(simd, *slice)
11170 }
11171 #[inline(always)]
11172 fn store_slice(&self, slice: &mut [i16]) {
11173 let slice: &mut [i16; 32] = slice.try_into().unwrap();
11174 *slice = (*self).into();
11175 }
11176 #[inline(always)]
11177 fn rotate_elements_left<const OFFSET: usize>(self) -> Self {
11178 self.simd.rotate_elements_left_mask16x32::<OFFSET>(self)
11179 }
11180 #[inline(always)]
11181 fn rotate_elements_right<const OFFSET: usize>(self) -> Self {
11182 self.simd.rotate_elements_right_mask16x32::<OFFSET>(self)
11183 }
11184 #[inline(always)]
11185 fn reverse(self) -> Self {
11186 self.simd.reverse_mask16x32(self)
11187 }
11188 #[inline(always)]
11189 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self {
11190 self.simd.simd_eq_mask16x32(self, rhs.simd_into(self.simd))
11191 }
11192 #[inline(always)]
11193 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self {
11194 self.simd.simd_ne_mask16x32(self, rhs.simd_into(self.simd))
11195 }
11196 #[inline(always)]
11197 fn any_true(self) -> bool {
11198 self.simd.any_true_mask16x32(self)
11199 }
11200 #[inline(always)]
11201 fn all_true(self) -> bool {
11202 self.simd.all_true_mask16x32(self)
11203 }
11204 #[inline(always)]
11205 fn any_false(self) -> bool {
11206 self.simd.any_false_mask16x32(self)
11207 }
11208 #[inline(always)]
11209 fn all_false(self) -> bool {
11210 self.simd.all_false_mask16x32(self)
11211 }
11212}
11213impl<S: Simd> MaskWiden<S> for mask16x32<S> {
11214 type Widened = mask32x16<S>;
11215 #[inline(always)]
11216 fn widen(self) -> (Self::Widened, Self::Widened) {
11217 self.simd.widen_mask16x32(self)
11218 }
11219}
11220impl<S: Simd> MaskNarrow<S> for mask16x32<S> {
11221 type Narrowed = mask8x64<S>;
11222 #[inline(always)]
11223 fn narrow(self, high: Self) -> Self::Narrowed {
11224 self.simd.narrow_mask16x32(self, high)
11225 }
11226}
11227impl<S: Simd> ExtractToken for i32x16<S> {
11228 type S = S;
11229 #[inline]
11230 fn token(&self) -> S {
11231 self.simd
11232 }
11233}
11234#[doc = "A SIMD vector of 16 [`i32`] elements.\n\nThis type's memory layout is identical to that of [`[i32; 16]`](prim@array), except that it is aligned to 64 bytes.\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```"]
11235#[derive(Clone, Copy)]
11236#[repr(C, align(64))]
11237pub struct i32x16<S: Simd> {
11238 pub(crate) val: S::i32x16,
11239 pub simd: S,
11240}
11241impl<S: Simd> Seal for i32x16<S> {}
11242impl<S: Simd> SimdFrom<[i32; 16], S> for i32x16<S> {
11243 #[inline(always)]
11244 fn simd_from(simd: S, val: [i32; 16]) -> Self {
11245 Self {
11246 val: crate::transmute::checked_transmute_copy(&val),
11247 simd,
11248 }
11249 }
11250}
11251impl<S: Simd> From<i32x16<S>> for [i32; 16] {
11252 #[inline(always)]
11253 fn from(value: i32x16<S>) -> Self {
11254 crate::transmute::checked_transmute_copy(&value.val)
11255 }
11256}
11257impl<S: Simd> core::ops::Deref for i32x16<S> {
11258 type Target = [i32; 16];
11259 #[inline(always)]
11260 fn deref(&self) -> &Self::Target {
11261 crate::transmute::checked_cast_ref(&self.val)
11262 }
11263}
11264impl<S: Simd> core::ops::DerefMut for i32x16<S> {
11265 #[inline(always)]
11266 fn deref_mut(&mut self) -> &mut Self::Target {
11267 crate::transmute::checked_cast_mut(&mut self.val)
11268 }
11269}
11270impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i32x16<S> {
11271 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11272 crate::support::simd_debug_impl(f, "i32x16", &self.simd, self.as_array())
11273 }
11274}
11275impl<S: Simd> SimdFrom<i32, S> for i32x16<S> {
11276 #[inline(always)]
11277 fn simd_from(simd: S, value: i32) -> Self {
11278 simd.splat_i32x16(value)
11279 }
11280}
11281impl<S: Simd> core::ops::Index<usize> for i32x16<S> {
11282 type Output = i32;
11283 #[inline(always)]
11284 fn index(&self, i: usize) -> &Self::Output {
11285 &self.as_array()[i]
11286 }
11287}
11288impl<S: Simd> core::ops::IndexMut<usize> for i32x16<S> {
11289 #[inline(always)]
11290 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
11291 &mut self.as_mut_array()[i]
11292 }
11293}
11294impl<S: Simd> Select<i32x16<S>> for mask32x16<S> {
11295 #[inline(always)]
11296 fn select(self, if_true: i32x16<S>, if_false: i32x16<S>) -> i32x16<S> {
11297 self.simd.select_i32x16(self, if_true, if_false)
11298 }
11299}
11300impl<S: Simd> Bytes for i32x16<S> {
11301 type Bytes = u8x64<S>;
11302 #[inline(always)]
11303 fn to_bytes(self) -> Self::Bytes {
11304 u8x64 {
11305 val: crate::transmute::checked_transmute_copy(&self.val),
11306 simd: self.simd,
11307 }
11308 }
11309 #[inline(always)]
11310 fn from_bytes(value: Self::Bytes) -> Self {
11311 Self {
11312 val: crate::transmute::checked_transmute_copy(&value.val),
11313 simd: value.simd,
11314 }
11315 }
11316}
11317impl<S: Simd> SimdBase<S> for i32x16<S> {
11318 type Element = i32;
11319 type ByteVector = u8x64<S>;
11320 const LEN: usize = 16;
11321 type Mask = mask32x16<S>;
11322 type Block = i32x4<S>;
11323 type Array = [i32; 16];
11324 #[inline(always)]
11325 fn as_slice(&self) -> &[i32] {
11326 self.as_array().as_slice()
11327 }
11328 #[inline(always)]
11329 fn as_mut_slice(&mut self) -> &mut [i32] {
11330 self.as_mut_array().as_mut_slice()
11331 }
11332 #[inline(always)]
11333 fn from_slice(simd: S, slice: &[i32]) -> Self {
11334 Self::load_array_ref(simd, slice.try_into().unwrap())
11335 }
11336 #[inline(always)]
11337 fn store_slice(&self, slice: &mut [i32]) {
11338 (*self).store_array(slice.try_into().unwrap());
11339 }
11340 #[inline(always)]
11341 fn splat(simd: S, val: i32) -> Self {
11342 simd.splat_i32x16(val)
11343 }
11344 #[inline(always)]
11345 fn block_splat(block: Self::Block) -> Self {
11346 let block2 = block.simd.combine_i32x4(block, block);
11347 block2.simd.combine_i32x8(block2, block2)
11348 }
11349 #[inline(always)]
11350 fn from_fn(simd: S, mut f: impl FnMut(usize) -> i32) -> Self {
11351 Self::load_array(
11352 simd,
11353 [
11354 f(0usize),
11355 f(1usize),
11356 f(2usize),
11357 f(3usize),
11358 f(4usize),
11359 f(5usize),
11360 f(6usize),
11361 f(7usize),
11362 f(8usize),
11363 f(9usize),
11364 f(10usize),
11365 f(11usize),
11366 f(12usize),
11367 f(13usize),
11368 f(14usize),
11369 f(15usize),
11370 ],
11371 )
11372 }
11373 #[inline(always)]
11374 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
11375 self.simd
11376 .slide_i32x16::<SHIFT>(self, rhs.simd_into(self.simd))
11377 }
11378 #[inline(always)]
11379 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
11380 self.simd
11381 .slide_within_blocks_i32x16::<SHIFT>(self, rhs.simd_into(self.simd))
11382 }
11383 #[inline(always)]
11384 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
11385 self.simd
11386 .swizzle_dyn_within_blocks_i32x16(self, indices.simd_into(self.simd))
11387 }
11388 #[inline(always)]
11389 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
11390 self.simd
11391 .swizzle_dyn_i32x16(self, indices.simd_into(self.simd))
11392 }
11393 #[inline(always)]
11394 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
11395 self.simd
11396 .swizzle_dyn_precise_i32x16(self, indices.simd_into(self.simd))
11397 }
11398 #[inline(always)]
11399 fn abs(self) -> Self {
11400 self.simd.abs_i32x16(self)
11401 }
11402 #[inline(always)]
11403 fn reverse(self) -> Self {
11404 self.simd.reverse_i32x16(self)
11405 }
11406 #[inline(always)]
11407 fn concat_swizzle_dyn(
11408 self,
11409 rhs: impl SimdInto<Self, S>,
11410 indices: impl SimdInto<Self::Bytes, S>,
11411 ) -> Self {
11412 self.simd.concat_swizzle_dyn_i32x16(
11413 self,
11414 rhs.simd_into(self.simd),
11415 indices.simd_into(self.simd),
11416 )
11417 }
11418 #[inline(always)]
11419 fn concat_swizzle_dyn_precise(
11420 self,
11421 rhs: impl SimdInto<Self, S>,
11422 indices: impl SimdInto<Self::Bytes, S>,
11423 ) -> Self {
11424 self.simd.concat_swizzle_dyn_precise_i32x16(
11425 self,
11426 rhs.simd_into(self.simd),
11427 indices.simd_into(self.simd),
11428 )
11429 }
11430 #[inline(always)]
11431 fn compress(self, mask: Self::Mask) -> Self {
11432 self.simd.compress_i32x16(self, mask)
11433 }
11434 #[inline(always)]
11435 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
11436 self.simd
11437 .compress_merge_i32x16(self, mask, merge.simd_into(self.simd))
11438 }
11439 #[inline(always)]
11440 fn expand(self, mask: Self::Mask) -> Self {
11441 self.simd.expand_i32x16(self, mask)
11442 }
11443 #[inline(always)]
11444 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
11445 self.simd
11446 .expand_merge_i32x16(self, mask, merge.simd_into(self.simd))
11447 }
11448 #[inline(always)]
11449 fn reduce_max(self) -> Self::Element {
11450 self.simd.reduce_max_i32x16(self)
11451 }
11452 #[inline(always)]
11453 fn reduce_min(self) -> Self::Element {
11454 self.simd.reduce_min_i32x16(self)
11455 }
11456 #[inline(always)]
11457 fn reduce_max_precise(self) -> Self::Element {
11458 self.simd.reduce_max_i32x16(self)
11459 }
11460 #[inline(always)]
11461 fn reduce_min_precise(self) -> Self::Element {
11462 self.simd.reduce_min_i32x16(self)
11463 }
11464 #[inline(always)]
11465 fn reduce_sum(self) -> Self::Element {
11466 self.simd.reduce_sum_i32x16(self)
11467 }
11468 #[inline(always)]
11469 fn reduce_product(self) -> Self::Element {
11470 self.simd.reduce_product_i32x16(self)
11471 }
11472 #[inline(always)]
11473 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
11474 self.simd.max_i32x16(self, rhs.simd_into(self.simd))
11475 }
11476 #[inline(always)]
11477 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
11478 self.simd.min_i32x16(self, rhs.simd_into(self.simd))
11479 }
11480 #[inline(always)]
11481 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
11482 self.simd.max_i32x16(self, rhs.simd_into(self.simd))
11483 }
11484 #[inline(always)]
11485 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
11486 self.simd.min_i32x16(self, rhs.simd_into(self.simd))
11487 }
11488 #[inline(always)]
11489 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
11490 self.simd
11491 .clamp_i32x16(self, min.simd_into(self.simd), max.simd_into(self.simd))
11492 }
11493 #[inline(always)]
11494 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
11495 self.simd.simd_eq_i32x16(self, rhs.simd_into(self.simd))
11496 }
11497 #[inline(always)]
11498 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
11499 self.simd.simd_ne_i32x16(self, rhs.simd_into(self.simd))
11500 }
11501 #[inline(always)]
11502 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
11503 self.simd.simd_lt_i32x16(self, rhs.simd_into(self.simd))
11504 }
11505 #[inline(always)]
11506 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
11507 self.simd.simd_le_i32x16(self, rhs.simd_into(self.simd))
11508 }
11509 #[inline(always)]
11510 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
11511 self.simd.simd_ge_i32x16(self, rhs.simd_into(self.simd))
11512 }
11513 #[inline(always)]
11514 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
11515 self.simd.simd_gt_i32x16(self, rhs.simd_into(self.simd))
11516 }
11517 #[inline(always)]
11518 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
11519 self.simd.zip_low_i32x16(self, rhs.simd_into(self.simd))
11520 }
11521 #[inline(always)]
11522 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
11523 self.simd.zip_high_i32x16(self, rhs.simd_into(self.simd))
11524 }
11525 #[inline(always)]
11526 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
11527 self.simd.unzip_low_i32x16(self, rhs.simd_into(self.simd))
11528 }
11529 #[inline(always)]
11530 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
11531 self.simd.unzip_high_i32x16(self, rhs.simd_into(self.simd))
11532 }
11533 #[inline(always)]
11534 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
11535 self.simd.interleave_i32x16(self, rhs.simd_into(self.simd))
11536 }
11537 #[inline(always)]
11538 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
11539 self.simd
11540 .deinterleave_i32x16(self, rhs.simd_into(self.simd))
11541 }
11542}
11543impl<S: Simd> crate::SimdInt<S> for i32x16<S> {
11544 #[inline(always)]
11545 fn count_ones(self) -> Self {
11546 self.simd.count_ones_i32x16(self)
11547 }
11548 #[inline(always)]
11549 fn count_zeros(self) -> Self {
11550 self.simd.count_zeros_i32x16(self)
11551 }
11552 #[inline(always)]
11553 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
11554 self.simd
11555 .saturating_add_i32x16(self, rhs.simd_into(self.simd))
11556 }
11557 #[inline(always)]
11558 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
11559 self.simd
11560 .saturating_sub_i32x16(self, rhs.simd_into(self.simd))
11561 }
11562}
11563impl<S: Simd> SimdCvtTruncate<f32x16<S>> for i32x16<S> {
11564 #[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."]
11565 #[inline(always)]
11566 fn truncate_from(x: f32x16<S>) -> Self {
11567 x.simd.cvt_i32_f32x16(x)
11568 }
11569 #[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."]
11570 #[inline(always)]
11571 fn truncate_from_precise(x: f32x16<S>) -> Self {
11572 x.simd.cvt_i32_precise_f32x16(x)
11573 }
11574}
11575impl<S: Simd> SimdWiden<S> for i32x16<S> {
11576 type Widened = i64x8<S>;
11577 #[inline(always)]
11578 fn widen(self) -> (Self::Widened, Self::Widened) {
11579 self.simd.widen_i32x16(self)
11580 }
11581}
11582impl<S: Simd> SimdIntWiden<S> for i32x16<S> {
11583 #[inline(always)]
11584 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
11585 self.simd
11586 .widening_mul_i32x16(self, rhs.simd_into(self.simd))
11587 }
11588 #[inline(always)]
11589 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
11590 self.simd
11591 .widening_add_i32x16(self, rhs.simd_into(self.simd))
11592 }
11593 #[inline(always)]
11594 fn pairwise_widening_add(self) -> Self::Widened {
11595 self.simd.pairwise_widening_add_i32x16(self)
11596 }
11597 #[inline(always)]
11598 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
11599 self.simd
11600 .pairwise_dot_product_i32x16(self, rhs.simd_into(self.simd))
11601 }
11602}
11603impl<S: Simd> SimdNarrow<S> for i32x16<S> {
11604 type Narrowed = i16x32<S>;
11605 #[inline(always)]
11606 fn narrow(self, high: Self) -> Self::Narrowed {
11607 self.simd.narrow_i32x16(self, high)
11608 }
11609 #[inline(always)]
11610 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
11611 self.simd.saturating_narrow_i32x16(self, high)
11612 }
11613 #[inline(always)]
11614 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
11615 self.simd.relaxed_narrow_i32x16(self, high)
11616 }
11617}
11618impl<S: Simd> crate::SimdSplit<S> for i32x16<S> {
11619 type Split = i32x8<S>;
11620 #[inline(always)]
11621 fn split(self) -> (Self::Split, Self::Split) {
11622 self.simd.split_i32x16(self)
11623 }
11624}
11625impl<S: Simd> ExtractToken for u32x16<S> {
11626 type S = S;
11627 #[inline]
11628 fn token(&self) -> S {
11629 self.simd
11630 }
11631}
11632#[doc = "A SIMD vector of 16 [`u32`] elements.\n\nThis type's memory layout is identical to that of [`[u32; 16]`](prim@array), except that it is aligned to 64 bytes.\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```"]
11633#[derive(Clone, Copy)]
11634#[repr(C, align(64))]
11635pub struct u32x16<S: Simd> {
11636 pub(crate) val: S::u32x16,
11637 pub simd: S,
11638}
11639impl<S: Simd> Seal for u32x16<S> {}
11640impl<S: Simd> SimdFrom<[u32; 16], S> for u32x16<S> {
11641 #[inline(always)]
11642 fn simd_from(simd: S, val: [u32; 16]) -> Self {
11643 Self {
11644 val: crate::transmute::checked_transmute_copy(&val),
11645 simd,
11646 }
11647 }
11648}
11649impl<S: Simd> From<u32x16<S>> for [u32; 16] {
11650 #[inline(always)]
11651 fn from(value: u32x16<S>) -> Self {
11652 crate::transmute::checked_transmute_copy(&value.val)
11653 }
11654}
11655impl<S: Simd> core::ops::Deref for u32x16<S> {
11656 type Target = [u32; 16];
11657 #[inline(always)]
11658 fn deref(&self) -> &Self::Target {
11659 crate::transmute::checked_cast_ref(&self.val)
11660 }
11661}
11662impl<S: Simd> core::ops::DerefMut for u32x16<S> {
11663 #[inline(always)]
11664 fn deref_mut(&mut self) -> &mut Self::Target {
11665 crate::transmute::checked_cast_mut(&mut self.val)
11666 }
11667}
11668impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u32x16<S> {
11669 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11670 crate::support::simd_debug_impl(f, "u32x16", &self.simd, self.as_array())
11671 }
11672}
11673impl<S: Simd> SimdFrom<u32, S> for u32x16<S> {
11674 #[inline(always)]
11675 fn simd_from(simd: S, value: u32) -> Self {
11676 simd.splat_u32x16(value)
11677 }
11678}
11679impl<S: Simd> core::ops::Index<usize> for u32x16<S> {
11680 type Output = u32;
11681 #[inline(always)]
11682 fn index(&self, i: usize) -> &Self::Output {
11683 &self.as_array()[i]
11684 }
11685}
11686impl<S: Simd> core::ops::IndexMut<usize> for u32x16<S> {
11687 #[inline(always)]
11688 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
11689 &mut self.as_mut_array()[i]
11690 }
11691}
11692impl<S: Simd> Select<u32x16<S>> for mask32x16<S> {
11693 #[inline(always)]
11694 fn select(self, if_true: u32x16<S>, if_false: u32x16<S>) -> u32x16<S> {
11695 self.simd.select_u32x16(self, if_true, if_false)
11696 }
11697}
11698impl<S: Simd> Bytes for u32x16<S> {
11699 type Bytes = u8x64<S>;
11700 #[inline(always)]
11701 fn to_bytes(self) -> Self::Bytes {
11702 u8x64 {
11703 val: crate::transmute::checked_transmute_copy(&self.val),
11704 simd: self.simd,
11705 }
11706 }
11707 #[inline(always)]
11708 fn from_bytes(value: Self::Bytes) -> Self {
11709 Self {
11710 val: crate::transmute::checked_transmute_copy(&value.val),
11711 simd: value.simd,
11712 }
11713 }
11714}
11715impl<S: Simd> SimdBase<S> for u32x16<S> {
11716 type Element = u32;
11717 type ByteVector = u8x64<S>;
11718 const LEN: usize = 16;
11719 type Mask = mask32x16<S>;
11720 type Block = u32x4<S>;
11721 type Array = [u32; 16];
11722 #[inline(always)]
11723 fn as_slice(&self) -> &[u32] {
11724 self.as_array().as_slice()
11725 }
11726 #[inline(always)]
11727 fn as_mut_slice(&mut self) -> &mut [u32] {
11728 self.as_mut_array().as_mut_slice()
11729 }
11730 #[inline(always)]
11731 fn from_slice(simd: S, slice: &[u32]) -> Self {
11732 Self::load_array_ref(simd, slice.try_into().unwrap())
11733 }
11734 #[inline(always)]
11735 fn store_slice(&self, slice: &mut [u32]) {
11736 (*self).store_array(slice.try_into().unwrap());
11737 }
11738 #[inline(always)]
11739 fn splat(simd: S, val: u32) -> Self {
11740 simd.splat_u32x16(val)
11741 }
11742 #[inline(always)]
11743 fn block_splat(block: Self::Block) -> Self {
11744 let block2 = block.simd.combine_u32x4(block, block);
11745 block2.simd.combine_u32x8(block2, block2)
11746 }
11747 #[inline(always)]
11748 fn from_fn(simd: S, mut f: impl FnMut(usize) -> u32) -> Self {
11749 Self::load_array(
11750 simd,
11751 [
11752 f(0usize),
11753 f(1usize),
11754 f(2usize),
11755 f(3usize),
11756 f(4usize),
11757 f(5usize),
11758 f(6usize),
11759 f(7usize),
11760 f(8usize),
11761 f(9usize),
11762 f(10usize),
11763 f(11usize),
11764 f(12usize),
11765 f(13usize),
11766 f(14usize),
11767 f(15usize),
11768 ],
11769 )
11770 }
11771 #[inline(always)]
11772 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
11773 self.simd
11774 .slide_u32x16::<SHIFT>(self, rhs.simd_into(self.simd))
11775 }
11776 #[inline(always)]
11777 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
11778 self.simd
11779 .slide_within_blocks_u32x16::<SHIFT>(self, rhs.simd_into(self.simd))
11780 }
11781 #[inline(always)]
11782 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
11783 self.simd
11784 .swizzle_dyn_within_blocks_u32x16(self, indices.simd_into(self.simd))
11785 }
11786 #[inline(always)]
11787 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
11788 self.simd
11789 .swizzle_dyn_u32x16(self, indices.simd_into(self.simd))
11790 }
11791 #[inline(always)]
11792 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
11793 self.simd
11794 .swizzle_dyn_precise_u32x16(self, indices.simd_into(self.simd))
11795 }
11796 #[inline(always)]
11797 fn abs(self) -> Self {
11798 self.simd.abs_u32x16(self)
11799 }
11800 #[inline(always)]
11801 fn reverse(self) -> Self {
11802 self.simd.reverse_u32x16(self)
11803 }
11804 #[inline(always)]
11805 fn concat_swizzle_dyn(
11806 self,
11807 rhs: impl SimdInto<Self, S>,
11808 indices: impl SimdInto<Self::Bytes, S>,
11809 ) -> Self {
11810 self.simd.concat_swizzle_dyn_u32x16(
11811 self,
11812 rhs.simd_into(self.simd),
11813 indices.simd_into(self.simd),
11814 )
11815 }
11816 #[inline(always)]
11817 fn concat_swizzle_dyn_precise(
11818 self,
11819 rhs: impl SimdInto<Self, S>,
11820 indices: impl SimdInto<Self::Bytes, S>,
11821 ) -> Self {
11822 self.simd.concat_swizzle_dyn_precise_u32x16(
11823 self,
11824 rhs.simd_into(self.simd),
11825 indices.simd_into(self.simd),
11826 )
11827 }
11828 #[inline(always)]
11829 fn compress(self, mask: Self::Mask) -> Self {
11830 self.simd.compress_u32x16(self, mask)
11831 }
11832 #[inline(always)]
11833 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
11834 self.simd
11835 .compress_merge_u32x16(self, mask, merge.simd_into(self.simd))
11836 }
11837 #[inline(always)]
11838 fn expand(self, mask: Self::Mask) -> Self {
11839 self.simd.expand_u32x16(self, mask)
11840 }
11841 #[inline(always)]
11842 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
11843 self.simd
11844 .expand_merge_u32x16(self, mask, merge.simd_into(self.simd))
11845 }
11846 #[inline(always)]
11847 fn reduce_max(self) -> Self::Element {
11848 self.simd.reduce_max_u32x16(self)
11849 }
11850 #[inline(always)]
11851 fn reduce_min(self) -> Self::Element {
11852 self.simd.reduce_min_u32x16(self)
11853 }
11854 #[inline(always)]
11855 fn reduce_max_precise(self) -> Self::Element {
11856 self.simd.reduce_max_u32x16(self)
11857 }
11858 #[inline(always)]
11859 fn reduce_min_precise(self) -> Self::Element {
11860 self.simd.reduce_min_u32x16(self)
11861 }
11862 #[inline(always)]
11863 fn reduce_sum(self) -> Self::Element {
11864 self.simd.reduce_sum_u32x16(self)
11865 }
11866 #[inline(always)]
11867 fn reduce_product(self) -> Self::Element {
11868 self.simd.reduce_product_u32x16(self)
11869 }
11870 #[inline(always)]
11871 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
11872 self.simd.max_u32x16(self, rhs.simd_into(self.simd))
11873 }
11874 #[inline(always)]
11875 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
11876 self.simd.min_u32x16(self, rhs.simd_into(self.simd))
11877 }
11878 #[inline(always)]
11879 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
11880 self.simd.max_u32x16(self, rhs.simd_into(self.simd))
11881 }
11882 #[inline(always)]
11883 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
11884 self.simd.min_u32x16(self, rhs.simd_into(self.simd))
11885 }
11886 #[inline(always)]
11887 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
11888 self.simd
11889 .clamp_u32x16(self, min.simd_into(self.simd), max.simd_into(self.simd))
11890 }
11891 #[inline(always)]
11892 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
11893 self.simd.simd_eq_u32x16(self, rhs.simd_into(self.simd))
11894 }
11895 #[inline(always)]
11896 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
11897 self.simd.simd_ne_u32x16(self, rhs.simd_into(self.simd))
11898 }
11899 #[inline(always)]
11900 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
11901 self.simd.simd_lt_u32x16(self, rhs.simd_into(self.simd))
11902 }
11903 #[inline(always)]
11904 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
11905 self.simd.simd_le_u32x16(self, rhs.simd_into(self.simd))
11906 }
11907 #[inline(always)]
11908 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
11909 self.simd.simd_ge_u32x16(self, rhs.simd_into(self.simd))
11910 }
11911 #[inline(always)]
11912 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
11913 self.simd.simd_gt_u32x16(self, rhs.simd_into(self.simd))
11914 }
11915 #[inline(always)]
11916 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
11917 self.simd.zip_low_u32x16(self, rhs.simd_into(self.simd))
11918 }
11919 #[inline(always)]
11920 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
11921 self.simd.zip_high_u32x16(self, rhs.simd_into(self.simd))
11922 }
11923 #[inline(always)]
11924 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
11925 self.simd.unzip_low_u32x16(self, rhs.simd_into(self.simd))
11926 }
11927 #[inline(always)]
11928 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
11929 self.simd.unzip_high_u32x16(self, rhs.simd_into(self.simd))
11930 }
11931 #[inline(always)]
11932 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
11933 self.simd.interleave_u32x16(self, rhs.simd_into(self.simd))
11934 }
11935 #[inline(always)]
11936 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
11937 self.simd
11938 .deinterleave_u32x16(self, rhs.simd_into(self.simd))
11939 }
11940}
11941impl<S: Simd> crate::SimdInt<S> for u32x16<S> {
11942 #[inline(always)]
11943 fn count_ones(self) -> Self {
11944 self.simd.count_ones_u32x16(self)
11945 }
11946 #[inline(always)]
11947 fn count_zeros(self) -> Self {
11948 self.simd.count_zeros_u32x16(self)
11949 }
11950 #[inline(always)]
11951 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
11952 self.simd
11953 .saturating_add_u32x16(self, rhs.simd_into(self.simd))
11954 }
11955 #[inline(always)]
11956 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
11957 self.simd
11958 .saturating_sub_u32x16(self, rhs.simd_into(self.simd))
11959 }
11960}
11961impl<S: Simd> SimdCvtTruncate<f32x16<S>> for u32x16<S> {
11962 #[doc = "Convert each floating-point element to an unsigned 32-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results.\n\nOn x86 platforms below AVX-512, this operation will still be slower than converting to `i32`, because there is no native instruction for converting to `u32`.\nIf you know your values fit within range of an `i32`, you should convert to an `i32` and cast to your desired datatype afterwards."]
11963 #[inline(always)]
11964 fn truncate_from(x: f32x16<S>) -> Self {
11965 x.simd.cvt_u32_f32x16(x)
11966 }
11967 #[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."]
11968 #[inline(always)]
11969 fn truncate_from_precise(x: f32x16<S>) -> Self {
11970 x.simd.cvt_u32_precise_f32x16(x)
11971 }
11972}
11973impl<S: Simd> SimdWiden<S> for u32x16<S> {
11974 type Widened = u64x8<S>;
11975 #[inline(always)]
11976 fn widen(self) -> (Self::Widened, Self::Widened) {
11977 self.simd.widen_u32x16(self)
11978 }
11979}
11980impl<S: Simd> SimdIntWiden<S> for u32x16<S> {
11981 #[inline(always)]
11982 fn widening_mul(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
11983 self.simd
11984 .widening_mul_u32x16(self, rhs.simd_into(self.simd))
11985 }
11986 #[inline(always)]
11987 fn widening_add(self, rhs: impl SimdInto<Self, S>) -> (Self::Widened, Self::Widened) {
11988 self.simd
11989 .widening_add_u32x16(self, rhs.simd_into(self.simd))
11990 }
11991 #[inline(always)]
11992 fn pairwise_widening_add(self) -> Self::Widened {
11993 self.simd.pairwise_widening_add_u32x16(self)
11994 }
11995 #[inline(always)]
11996 fn pairwise_dot_product(self, rhs: impl SimdInto<Self, S>) -> Self::Widened {
11997 self.simd
11998 .pairwise_dot_product_u32x16(self, rhs.simd_into(self.simd))
11999 }
12000}
12001impl<S: Simd> SimdNarrow<S> for u32x16<S> {
12002 type Narrowed = u16x32<S>;
12003 #[inline(always)]
12004 fn narrow(self, high: Self) -> Self::Narrowed {
12005 self.simd.narrow_u32x16(self, high)
12006 }
12007 #[inline(always)]
12008 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
12009 self.simd.saturating_narrow_u32x16(self, high)
12010 }
12011 #[inline(always)]
12012 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
12013 self.simd.relaxed_narrow_u32x16(self, high)
12014 }
12015}
12016impl<S: Simd> crate::SimdSplit<S> for u32x16<S> {
12017 type Split = u32x8<S>;
12018 #[inline(always)]
12019 fn split(self) -> (Self::Split, Self::Split) {
12020 self.simd.split_u32x16(self)
12021 }
12022}
12023impl<S: Simd> ExtractToken for mask32x16<S> {
12024 type S = S;
12025 #[inline]
12026 fn token(&self) -> S {
12027 self.simd
12028 }
12029}
12030#[doc = "A SIMD mask of 16 logical lanes corresponding to 32-bit vector elements.\n\nThe storage representation of this type is intentionally opaque and may vary depending on the SIMD level.\n\nYou can construct this mask type using the [`Self::splat`], [`Self::from_bitmask`], [`Self::from_slice`], and [`Self::simd_from`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, mask32x16};\nfn construct_mask<S: Simd>(simd: S) {\n // From a single boolean value:\n let a = mask32x16::splat(simd, true);\n let b = mask32x16::simd_from(simd, true);\n\n // From signed integer mask lanes:\n let c = mask32x16::from_slice(simd, &[-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);\n let d = mask32x16::simd_from(simd, [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);\n\n // From a compact bitmask (same mask as above, least significant bit maps to lane 0):\n let e = mask32x16::from_bitmask(simd, 0b0001);\n\n // By setting individual lanes:\n let mut f = mask32x16::splat(simd, false);\n f.set(0, true);\n}\n```"]
12031#[derive(Clone, Copy)]
12032pub struct mask32x16<S: Simd> {
12033 pub(crate) val: S::mask32x16,
12034 pub(crate) simd: S,
12035}
12036impl<S: Simd> Seal for mask32x16<S> {}
12037impl<S: Simd> SimdFrom<[i32; 16], S> for mask32x16<S> {
12038 #[inline(always)]
12039 fn simd_from(simd: S, val: [i32; 16]) -> Self {
12040 Self {
12041 val: <S as crate::arch_types::ArchTypes>::mask32x16_from_array(simd, val),
12042 simd,
12043 }
12044 }
12045}
12046impl<S: Simd> From<mask32x16<S>> for [i32; 16] {
12047 #[inline(always)]
12048 fn from(value: mask32x16<S>) -> Self {
12049 <S as crate::arch_types::ArchTypes>::mask32x16_to_array(value.simd, value.val)
12050 }
12051}
12052impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask32x16<S> {
12053 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12054 let lanes: [i32; 16] = (*self).into();
12055 crate::support::simd_debug_impl(f, "mask32x16", &self.simd, &lanes)
12056 }
12057}
12058impl<S: Simd> SimdFrom<bool, S> for mask32x16<S> {
12059 #[inline(always)]
12060 fn simd_from(simd: S, value: bool) -> Self {
12061 simd.splat_mask32x16(value)
12062 }
12063}
12064impl<S: Simd> Select<mask32x16<S>> for mask32x16<S> {
12065 #[inline(always)]
12066 fn select(self, if_true: mask32x16<S>, if_false: mask32x16<S>) -> mask32x16<S> {
12067 self.simd.select_mask32x16(self, if_true, if_false)
12068 }
12069}
12070impl<S: Simd> SimdMask<S> for mask32x16<S> {
12071 type Element = i32;
12072 type Ints = i32x16<S>;
12073 const LEN: usize = 16;
12074 #[inline(always)]
12075 fn splat(simd: S, val: bool) -> Self {
12076 simd.splat_mask32x16(val)
12077 }
12078 #[inline(always)]
12079 fn from_bitmask(simd: S, bits: u64) -> Self {
12080 simd.from_bitmask_mask32x16(bits)
12081 }
12082 #[inline(always)]
12083 fn to_bitmask(self) -> u64 {
12084 self.simd.to_bitmask_mask32x16(self)
12085 }
12086 #[inline(always)]
12087 fn from_vector(vector: Self::Ints) -> Self {
12088 vector.token().from_vector_mask32x16(vector)
12089 }
12090 #[inline(always)]
12091 fn to_vector(self) -> Self::Ints {
12092 self.simd.to_vector_mask32x16(self)
12093 }
12094 #[inline(always)]
12095 fn set(&mut self, index: usize, value: bool) {
12096 self.simd.set_mask32x16(self, index, value);
12097 }
12098 #[inline(always)]
12099 fn from_slice(simd: S, slice: &[i32]) -> Self {
12100 let slice: &[i32; 16] = slice.try_into().unwrap();
12101 Self::simd_from(simd, *slice)
12102 }
12103 #[inline(always)]
12104 fn store_slice(&self, slice: &mut [i32]) {
12105 let slice: &mut [i32; 16] = slice.try_into().unwrap();
12106 *slice = (*self).into();
12107 }
12108 #[inline(always)]
12109 fn rotate_elements_left<const OFFSET: usize>(self) -> Self {
12110 self.simd.rotate_elements_left_mask32x16::<OFFSET>(self)
12111 }
12112 #[inline(always)]
12113 fn rotate_elements_right<const OFFSET: usize>(self) -> Self {
12114 self.simd.rotate_elements_right_mask32x16::<OFFSET>(self)
12115 }
12116 #[inline(always)]
12117 fn reverse(self) -> Self {
12118 self.simd.reverse_mask32x16(self)
12119 }
12120 #[inline(always)]
12121 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self {
12122 self.simd.simd_eq_mask32x16(self, rhs.simd_into(self.simd))
12123 }
12124 #[inline(always)]
12125 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self {
12126 self.simd.simd_ne_mask32x16(self, rhs.simd_into(self.simd))
12127 }
12128 #[inline(always)]
12129 fn any_true(self) -> bool {
12130 self.simd.any_true_mask32x16(self)
12131 }
12132 #[inline(always)]
12133 fn all_true(self) -> bool {
12134 self.simd.all_true_mask32x16(self)
12135 }
12136 #[inline(always)]
12137 fn any_false(self) -> bool {
12138 self.simd.any_false_mask32x16(self)
12139 }
12140 #[inline(always)]
12141 fn all_false(self) -> bool {
12142 self.simd.all_false_mask32x16(self)
12143 }
12144}
12145impl<S: Simd> MaskWiden<S> for mask32x16<S> {
12146 type Widened = mask64x8<S>;
12147 #[inline(always)]
12148 fn widen(self) -> (Self::Widened, Self::Widened) {
12149 self.simd.widen_mask32x16(self)
12150 }
12151}
12152impl<S: Simd> MaskNarrow<S> for mask32x16<S> {
12153 type Narrowed = mask16x32<S>;
12154 #[inline(always)]
12155 fn narrow(self, high: Self) -> Self::Narrowed {
12156 self.simd.narrow_mask32x16(self, high)
12157 }
12158}
12159impl<S: Simd> ExtractToken for f64x8<S> {
12160 type S = S;
12161 #[inline]
12162 fn token(&self) -> S {
12163 self.simd
12164 }
12165}
12166#[doc = "A SIMD vector of 8 [`f64`] elements.\n\nThis type's memory layout is identical to that of [`[f64; 8]`](prim@array), except that it is aligned to 64 bytes.\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```"]
12167#[derive(Clone, Copy)]
12168#[repr(C, align(64))]
12169pub struct f64x8<S: Simd> {
12170 pub(crate) val: S::f64x8,
12171 pub simd: S,
12172}
12173impl<S: Simd> Seal for f64x8<S> {}
12174impl<S: Simd> SimdFrom<[f64; 8], S> for f64x8<S> {
12175 #[inline(always)]
12176 fn simd_from(simd: S, val: [f64; 8]) -> Self {
12177 Self {
12178 val: crate::transmute::checked_transmute_copy(&val),
12179 simd,
12180 }
12181 }
12182}
12183impl<S: Simd> From<f64x8<S>> for [f64; 8] {
12184 #[inline(always)]
12185 fn from(value: f64x8<S>) -> Self {
12186 crate::transmute::checked_transmute_copy(&value.val)
12187 }
12188}
12189impl<S: Simd> core::ops::Deref for f64x8<S> {
12190 type Target = [f64; 8];
12191 #[inline(always)]
12192 fn deref(&self) -> &Self::Target {
12193 crate::transmute::checked_cast_ref(&self.val)
12194 }
12195}
12196impl<S: Simd> core::ops::DerefMut for f64x8<S> {
12197 #[inline(always)]
12198 fn deref_mut(&mut self) -> &mut Self::Target {
12199 crate::transmute::checked_cast_mut(&mut self.val)
12200 }
12201}
12202impl<S: Simd + core::fmt::Debug> core::fmt::Debug for f64x8<S> {
12203 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12204 crate::support::simd_debug_impl(f, "f64x8", &self.simd, self.as_array())
12205 }
12206}
12207impl<S: Simd> SimdFrom<f64, S> for f64x8<S> {
12208 #[inline(always)]
12209 fn simd_from(simd: S, value: f64) -> Self {
12210 simd.splat_f64x8(value)
12211 }
12212}
12213impl<S: Simd> core::ops::Index<usize> for f64x8<S> {
12214 type Output = f64;
12215 #[inline(always)]
12216 fn index(&self, i: usize) -> &Self::Output {
12217 &self.as_array()[i]
12218 }
12219}
12220impl<S: Simd> core::ops::IndexMut<usize> for f64x8<S> {
12221 #[inline(always)]
12222 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
12223 &mut self.as_mut_array()[i]
12224 }
12225}
12226impl<S: Simd> Select<f64x8<S>> for mask64x8<S> {
12227 #[inline(always)]
12228 fn select(self, if_true: f64x8<S>, if_false: f64x8<S>) -> f64x8<S> {
12229 self.simd.select_f64x8(self, if_true, if_false)
12230 }
12231}
12232impl<S: Simd> Bytes for f64x8<S> {
12233 type Bytes = u8x64<S>;
12234 #[inline(always)]
12235 fn to_bytes(self) -> Self::Bytes {
12236 u8x64 {
12237 val: crate::transmute::checked_transmute_copy(&self.val),
12238 simd: self.simd,
12239 }
12240 }
12241 #[inline(always)]
12242 fn from_bytes(value: Self::Bytes) -> Self {
12243 Self {
12244 val: crate::transmute::checked_transmute_copy(&value.val),
12245 simd: value.simd,
12246 }
12247 }
12248}
12249impl<S: Simd> SimdBase<S> for f64x8<S> {
12250 type Element = f64;
12251 type ByteVector = u8x64<S>;
12252 const LEN: usize = 8;
12253 type Mask = mask64x8<S>;
12254 type Block = f64x2<S>;
12255 type Array = [f64; 8];
12256 #[inline(always)]
12257 fn as_slice(&self) -> &[f64] {
12258 self.as_array().as_slice()
12259 }
12260 #[inline(always)]
12261 fn as_mut_slice(&mut self) -> &mut [f64] {
12262 self.as_mut_array().as_mut_slice()
12263 }
12264 #[inline(always)]
12265 fn from_slice(simd: S, slice: &[f64]) -> Self {
12266 Self::load_array_ref(simd, slice.try_into().unwrap())
12267 }
12268 #[inline(always)]
12269 fn store_slice(&self, slice: &mut [f64]) {
12270 (*self).store_array(slice.try_into().unwrap());
12271 }
12272 #[inline(always)]
12273 fn splat(simd: S, val: f64) -> Self {
12274 simd.splat_f64x8(val)
12275 }
12276 #[inline(always)]
12277 fn block_splat(block: Self::Block) -> Self {
12278 let block2 = block.simd.combine_f64x2(block, block);
12279 block2.simd.combine_f64x4(block2, block2)
12280 }
12281 #[inline(always)]
12282 fn from_fn(simd: S, mut f: impl FnMut(usize) -> f64) -> Self {
12283 Self::load_array(
12284 simd,
12285 [
12286 f(0usize),
12287 f(1usize),
12288 f(2usize),
12289 f(3usize),
12290 f(4usize),
12291 f(5usize),
12292 f(6usize),
12293 f(7usize),
12294 ],
12295 )
12296 }
12297 #[inline(always)]
12298 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
12299 self.simd
12300 .slide_f64x8::<SHIFT>(self, rhs.simd_into(self.simd))
12301 }
12302 #[inline(always)]
12303 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
12304 self.simd
12305 .slide_within_blocks_f64x8::<SHIFT>(self, rhs.simd_into(self.simd))
12306 }
12307 #[inline(always)]
12308 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
12309 self.simd
12310 .swizzle_dyn_within_blocks_f64x8(self, indices.simd_into(self.simd))
12311 }
12312 #[inline(always)]
12313 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
12314 self.simd
12315 .swizzle_dyn_f64x8(self, indices.simd_into(self.simd))
12316 }
12317 #[inline(always)]
12318 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
12319 self.simd
12320 .swizzle_dyn_precise_f64x8(self, indices.simd_into(self.simd))
12321 }
12322 #[inline(always)]
12323 fn abs(self) -> Self {
12324 self.simd.abs_f64x8(self)
12325 }
12326 #[inline(always)]
12327 fn reverse(self) -> Self {
12328 self.simd.reverse_f64x8(self)
12329 }
12330 #[inline(always)]
12331 fn concat_swizzle_dyn(
12332 self,
12333 rhs: impl SimdInto<Self, S>,
12334 indices: impl SimdInto<Self::Bytes, S>,
12335 ) -> Self {
12336 self.simd.concat_swizzle_dyn_f64x8(
12337 self,
12338 rhs.simd_into(self.simd),
12339 indices.simd_into(self.simd),
12340 )
12341 }
12342 #[inline(always)]
12343 fn concat_swizzle_dyn_precise(
12344 self,
12345 rhs: impl SimdInto<Self, S>,
12346 indices: impl SimdInto<Self::Bytes, S>,
12347 ) -> Self {
12348 self.simd.concat_swizzle_dyn_precise_f64x8(
12349 self,
12350 rhs.simd_into(self.simd),
12351 indices.simd_into(self.simd),
12352 )
12353 }
12354 #[inline(always)]
12355 fn compress(self, mask: Self::Mask) -> Self {
12356 self.simd.compress_f64x8(self, mask)
12357 }
12358 #[inline(always)]
12359 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
12360 self.simd
12361 .compress_merge_f64x8(self, mask, merge.simd_into(self.simd))
12362 }
12363 #[inline(always)]
12364 fn expand(self, mask: Self::Mask) -> Self {
12365 self.simd.expand_f64x8(self, mask)
12366 }
12367 #[inline(always)]
12368 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
12369 self.simd
12370 .expand_merge_f64x8(self, mask, merge.simd_into(self.simd))
12371 }
12372 #[inline(always)]
12373 fn reduce_max(self) -> Self::Element {
12374 self.simd.reduce_max_f64x8(self)
12375 }
12376 #[inline(always)]
12377 fn reduce_min(self) -> Self::Element {
12378 self.simd.reduce_min_f64x8(self)
12379 }
12380 #[inline(always)]
12381 fn reduce_max_precise(self) -> Self::Element {
12382 self.simd.reduce_max_precise_f64x8(self)
12383 }
12384 #[inline(always)]
12385 fn reduce_min_precise(self) -> Self::Element {
12386 self.simd.reduce_min_precise_f64x8(self)
12387 }
12388 #[inline(always)]
12389 fn reduce_sum(self) -> Self::Element {
12390 self.simd.reduce_sum_f64x8(self)
12391 }
12392 #[inline(always)]
12393 fn reduce_product(self) -> Self::Element {
12394 self.simd.reduce_product_f64x8(self)
12395 }
12396 #[inline(always)]
12397 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
12398 self.simd.max_f64x8(self, rhs.simd_into(self.simd))
12399 }
12400 #[inline(always)]
12401 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
12402 self.simd.min_f64x8(self, rhs.simd_into(self.simd))
12403 }
12404 #[inline(always)]
12405 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
12406 self.simd.max_precise_f64x8(self, rhs.simd_into(self.simd))
12407 }
12408 #[inline(always)]
12409 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
12410 self.simd.min_precise_f64x8(self, rhs.simd_into(self.simd))
12411 }
12412 #[inline(always)]
12413 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
12414 self.simd
12415 .clamp_f64x8(self, min.simd_into(self.simd), max.simd_into(self.simd))
12416 }
12417 #[inline(always)]
12418 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
12419 self.simd.simd_eq_f64x8(self, rhs.simd_into(self.simd))
12420 }
12421 #[inline(always)]
12422 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
12423 self.simd.simd_ne_f64x8(self, rhs.simd_into(self.simd))
12424 }
12425 #[inline(always)]
12426 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
12427 self.simd.simd_lt_f64x8(self, rhs.simd_into(self.simd))
12428 }
12429 #[inline(always)]
12430 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
12431 self.simd.simd_le_f64x8(self, rhs.simd_into(self.simd))
12432 }
12433 #[inline(always)]
12434 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
12435 self.simd.simd_ge_f64x8(self, rhs.simd_into(self.simd))
12436 }
12437 #[inline(always)]
12438 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
12439 self.simd.simd_gt_f64x8(self, rhs.simd_into(self.simd))
12440 }
12441 #[inline(always)]
12442 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
12443 self.simd.zip_low_f64x8(self, rhs.simd_into(self.simd))
12444 }
12445 #[inline(always)]
12446 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
12447 self.simd.zip_high_f64x8(self, rhs.simd_into(self.simd))
12448 }
12449 #[inline(always)]
12450 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
12451 self.simd.unzip_low_f64x8(self, rhs.simd_into(self.simd))
12452 }
12453 #[inline(always)]
12454 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
12455 self.simd.unzip_high_f64x8(self, rhs.simd_into(self.simd))
12456 }
12457 #[inline(always)]
12458 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
12459 self.simd.interleave_f64x8(self, rhs.simd_into(self.simd))
12460 }
12461 #[inline(always)]
12462 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
12463 self.simd.deinterleave_f64x8(self, rhs.simd_into(self.simd))
12464 }
12465}
12466impl<S: Simd> crate::SimdFloat<S> for f64x8<S> {
12467 type Bits = u64x8<S>;
12468 #[inline(always)]
12469 fn sqrt(self) -> Self {
12470 self.simd.sqrt_f64x8(self)
12471 }
12472 #[inline(always)]
12473 fn approximate_recip(self) -> Self {
12474 self.simd.approximate_recip_f64x8(self)
12475 }
12476 #[inline(always)]
12477 fn copysign(self, rhs: impl SimdInto<Self, S>) -> Self {
12478 self.simd.copysign_f64x8(self, rhs.simd_into(self.simd))
12479 }
12480 #[inline(always)]
12481 fn mul_add(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
12482 self.simd
12483 .mul_add_f64x8(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
12484 }
12485 #[inline(always)]
12486 fn mul_add_precise(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
12487 self.simd
12488 .mul_add_precise_f64x8(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
12489 }
12490 #[inline(always)]
12491 fn mul_sub(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
12492 self.simd
12493 .mul_sub_f64x8(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
12494 }
12495 #[inline(always)]
12496 fn mul_sub_precise(self, op1: impl SimdInto<Self, S>, op2: impl SimdInto<Self, S>) -> Self {
12497 self.simd
12498 .mul_sub_precise_f64x8(self, op1.simd_into(self.simd), op2.simd_into(self.simd))
12499 }
12500 #[inline(always)]
12501 fn floor(self) -> Self {
12502 self.simd.floor_f64x8(self)
12503 }
12504 #[inline(always)]
12505 fn ceil(self) -> Self {
12506 self.simd.ceil_f64x8(self)
12507 }
12508 #[inline(always)]
12509 fn round_ties_even(self) -> Self {
12510 self.simd.round_ties_even_f64x8(self)
12511 }
12512 #[inline(always)]
12513 fn round(self) -> Self {
12514 self.simd.round_f64x8(self)
12515 }
12516 #[inline(always)]
12517 fn fract(self) -> Self {
12518 self.simd.fract_f64x8(self)
12519 }
12520 #[inline(always)]
12521 fn trunc(self) -> Self {
12522 self.simd.trunc_f64x8(self)
12523 }
12524 #[inline(always)]
12525 fn to_degrees(self) -> Self {
12526 self.simd.to_degrees_f64x8(self)
12527 }
12528 #[inline(always)]
12529 fn to_radians(self) -> Self {
12530 self.simd.to_radians_f64x8(self)
12531 }
12532 #[inline(always)]
12533 fn is_nan(self) -> Self::Mask {
12534 self.simd.is_nan_f64x8(self)
12535 }
12536 #[inline(always)]
12537 fn is_infinite(self) -> Self::Mask {
12538 self.simd.is_infinite_f64x8(self)
12539 }
12540 #[inline(always)]
12541 fn is_finite(self) -> Self::Mask {
12542 self.simd.is_finite_f64x8(self)
12543 }
12544 #[inline(always)]
12545 fn is_subnormal(self) -> Self::Mask {
12546 self.simd.is_subnormal_f64x8(self)
12547 }
12548 #[inline(always)]
12549 fn is_normal(self) -> Self::Mask {
12550 self.simd.is_normal_f64x8(self)
12551 }
12552 #[inline(always)]
12553 fn is_sign_positive(self) -> Self::Mask {
12554 self.simd.is_sign_positive_f64x8(self)
12555 }
12556 #[inline(always)]
12557 fn is_sign_negative(self) -> Self::Mask {
12558 self.simd.is_sign_negative_f64x8(self)
12559 }
12560}
12561impl<S: Simd> SimdCvtFloat<u64x8<S>> for f64x8<S> {
12562 #[doc = "Convert each unsigned 64-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
12563 #[inline(always)]
12564 fn float_from(x: u64x8<S>) -> Self {
12565 x.simd.cvt_f64_u64x8(x)
12566 }
12567}
12568impl<S: Simd> SimdCvtFloat<i64x8<S>> for f64x8<S> {
12569 #[doc = "Convert each signed 64-bit integer element to a floating-point value.\n\nValues that cannot be exactly represented are rounded to the nearest representable value."]
12570 #[inline(always)]
12571 fn float_from(x: i64x8<S>) -> Self {
12572 x.simd.cvt_f64_i64x8(x)
12573 }
12574}
12575impl<S: Simd> SimdNarrow<S> for f64x8<S> {
12576 type Narrowed = f32x16<S>;
12577 #[inline(always)]
12578 fn narrow(self, high: Self) -> Self::Narrowed {
12579 self.simd.narrow_f64x8(self, high)
12580 }
12581 #[inline(always)]
12582 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
12583 self.simd.saturating_narrow_f64x8(self, high)
12584 }
12585 #[inline(always)]
12586 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
12587 self.simd.relaxed_narrow_f64x8(self, high)
12588 }
12589}
12590impl<S: Simd> crate::SimdSplit<S> for f64x8<S> {
12591 type Split = f64x4<S>;
12592 #[inline(always)]
12593 fn split(self) -> (Self::Split, Self::Split) {
12594 self.simd.split_f64x8(self)
12595 }
12596}
12597impl<S: Simd> ExtractToken for i64x8<S> {
12598 type S = S;
12599 #[inline]
12600 fn token(&self) -> S {
12601 self.simd
12602 }
12603}
12604#[doc = "A SIMD vector of 8 [`i64`] elements.\n\nThis type's memory layout is identical to that of [`[i64; 8]`](prim@array), except that it is aligned to 64 bytes.\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::*, i64x8};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = i64x8::splat(simd, 1);\n let b = i64x8::simd_from(simd, 1);\n\n // From a slice:\n let c = i64x8::from_slice(simd, &[1, 2, 3, 4, 5, 6, 7, 8]);\n\n // From an array:\n let d = i64x8::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8]);\n\n // From an element-wise function:\n let e = i64x8::from_fn(simd, |i| i as i64);\n # use fearless_simd::i64x2;\n // From `Self::Block`:\n let f = i64x8::block_splat(i64x2::simd_from(simd, [1, 2]));\n}\n```"]
12605#[derive(Clone, Copy)]
12606#[repr(C, align(64))]
12607pub struct i64x8<S: Simd> {
12608 pub(crate) val: S::i64x8,
12609 pub simd: S,
12610}
12611impl<S: Simd> Seal for i64x8<S> {}
12612impl<S: Simd> SimdFrom<[i64; 8], S> for i64x8<S> {
12613 #[inline(always)]
12614 fn simd_from(simd: S, val: [i64; 8]) -> Self {
12615 Self {
12616 val: crate::transmute::checked_transmute_copy(&val),
12617 simd,
12618 }
12619 }
12620}
12621impl<S: Simd> From<i64x8<S>> for [i64; 8] {
12622 #[inline(always)]
12623 fn from(value: i64x8<S>) -> Self {
12624 crate::transmute::checked_transmute_copy(&value.val)
12625 }
12626}
12627impl<S: Simd> core::ops::Deref for i64x8<S> {
12628 type Target = [i64; 8];
12629 #[inline(always)]
12630 fn deref(&self) -> &Self::Target {
12631 crate::transmute::checked_cast_ref(&self.val)
12632 }
12633}
12634impl<S: Simd> core::ops::DerefMut for i64x8<S> {
12635 #[inline(always)]
12636 fn deref_mut(&mut self) -> &mut Self::Target {
12637 crate::transmute::checked_cast_mut(&mut self.val)
12638 }
12639}
12640impl<S: Simd + core::fmt::Debug> core::fmt::Debug for i64x8<S> {
12641 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12642 crate::support::simd_debug_impl(f, "i64x8", &self.simd, self.as_array())
12643 }
12644}
12645impl<S: Simd> SimdFrom<i64, S> for i64x8<S> {
12646 #[inline(always)]
12647 fn simd_from(simd: S, value: i64) -> Self {
12648 simd.splat_i64x8(value)
12649 }
12650}
12651impl<S: Simd> core::ops::Index<usize> for i64x8<S> {
12652 type Output = i64;
12653 #[inline(always)]
12654 fn index(&self, i: usize) -> &Self::Output {
12655 &self.as_array()[i]
12656 }
12657}
12658impl<S: Simd> core::ops::IndexMut<usize> for i64x8<S> {
12659 #[inline(always)]
12660 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
12661 &mut self.as_mut_array()[i]
12662 }
12663}
12664impl<S: Simd> Select<i64x8<S>> for mask64x8<S> {
12665 #[inline(always)]
12666 fn select(self, if_true: i64x8<S>, if_false: i64x8<S>) -> i64x8<S> {
12667 self.simd.select_i64x8(self, if_true, if_false)
12668 }
12669}
12670impl<S: Simd> Bytes for i64x8<S> {
12671 type Bytes = u8x64<S>;
12672 #[inline(always)]
12673 fn to_bytes(self) -> Self::Bytes {
12674 u8x64 {
12675 val: crate::transmute::checked_transmute_copy(&self.val),
12676 simd: self.simd,
12677 }
12678 }
12679 #[inline(always)]
12680 fn from_bytes(value: Self::Bytes) -> Self {
12681 Self {
12682 val: crate::transmute::checked_transmute_copy(&value.val),
12683 simd: value.simd,
12684 }
12685 }
12686}
12687impl<S: Simd> SimdBase<S> for i64x8<S> {
12688 type Element = i64;
12689 type ByteVector = u8x64<S>;
12690 const LEN: usize = 8;
12691 type Mask = mask64x8<S>;
12692 type Block = i64x2<S>;
12693 type Array = [i64; 8];
12694 #[inline(always)]
12695 fn as_slice(&self) -> &[i64] {
12696 self.as_array().as_slice()
12697 }
12698 #[inline(always)]
12699 fn as_mut_slice(&mut self) -> &mut [i64] {
12700 self.as_mut_array().as_mut_slice()
12701 }
12702 #[inline(always)]
12703 fn from_slice(simd: S, slice: &[i64]) -> Self {
12704 Self::load_array_ref(simd, slice.try_into().unwrap())
12705 }
12706 #[inline(always)]
12707 fn store_slice(&self, slice: &mut [i64]) {
12708 (*self).store_array(slice.try_into().unwrap());
12709 }
12710 #[inline(always)]
12711 fn splat(simd: S, val: i64) -> Self {
12712 simd.splat_i64x8(val)
12713 }
12714 #[inline(always)]
12715 fn block_splat(block: Self::Block) -> Self {
12716 let block2 = block.simd.combine_i64x2(block, block);
12717 block2.simd.combine_i64x4(block2, block2)
12718 }
12719 #[inline(always)]
12720 fn from_fn(simd: S, mut f: impl FnMut(usize) -> i64) -> Self {
12721 Self::load_array(
12722 simd,
12723 [
12724 f(0usize),
12725 f(1usize),
12726 f(2usize),
12727 f(3usize),
12728 f(4usize),
12729 f(5usize),
12730 f(6usize),
12731 f(7usize),
12732 ],
12733 )
12734 }
12735 #[inline(always)]
12736 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
12737 self.simd
12738 .slide_i64x8::<SHIFT>(self, rhs.simd_into(self.simd))
12739 }
12740 #[inline(always)]
12741 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
12742 self.simd
12743 .slide_within_blocks_i64x8::<SHIFT>(self, rhs.simd_into(self.simd))
12744 }
12745 #[inline(always)]
12746 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
12747 self.simd
12748 .swizzle_dyn_within_blocks_i64x8(self, indices.simd_into(self.simd))
12749 }
12750 #[inline(always)]
12751 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
12752 self.simd
12753 .swizzle_dyn_i64x8(self, indices.simd_into(self.simd))
12754 }
12755 #[inline(always)]
12756 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
12757 self.simd
12758 .swizzle_dyn_precise_i64x8(self, indices.simd_into(self.simd))
12759 }
12760 #[inline(always)]
12761 fn abs(self) -> Self {
12762 self.simd.abs_i64x8(self)
12763 }
12764 #[inline(always)]
12765 fn reverse(self) -> Self {
12766 self.simd.reverse_i64x8(self)
12767 }
12768 #[inline(always)]
12769 fn concat_swizzle_dyn(
12770 self,
12771 rhs: impl SimdInto<Self, S>,
12772 indices: impl SimdInto<Self::Bytes, S>,
12773 ) -> Self {
12774 self.simd.concat_swizzle_dyn_i64x8(
12775 self,
12776 rhs.simd_into(self.simd),
12777 indices.simd_into(self.simd),
12778 )
12779 }
12780 #[inline(always)]
12781 fn concat_swizzle_dyn_precise(
12782 self,
12783 rhs: impl SimdInto<Self, S>,
12784 indices: impl SimdInto<Self::Bytes, S>,
12785 ) -> Self {
12786 self.simd.concat_swizzle_dyn_precise_i64x8(
12787 self,
12788 rhs.simd_into(self.simd),
12789 indices.simd_into(self.simd),
12790 )
12791 }
12792 #[inline(always)]
12793 fn compress(self, mask: Self::Mask) -> Self {
12794 self.simd.compress_i64x8(self, mask)
12795 }
12796 #[inline(always)]
12797 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
12798 self.simd
12799 .compress_merge_i64x8(self, mask, merge.simd_into(self.simd))
12800 }
12801 #[inline(always)]
12802 fn expand(self, mask: Self::Mask) -> Self {
12803 self.simd.expand_i64x8(self, mask)
12804 }
12805 #[inline(always)]
12806 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
12807 self.simd
12808 .expand_merge_i64x8(self, mask, merge.simd_into(self.simd))
12809 }
12810 #[inline(always)]
12811 fn reduce_max(self) -> Self::Element {
12812 self.simd.reduce_max_i64x8(self)
12813 }
12814 #[inline(always)]
12815 fn reduce_min(self) -> Self::Element {
12816 self.simd.reduce_min_i64x8(self)
12817 }
12818 #[inline(always)]
12819 fn reduce_max_precise(self) -> Self::Element {
12820 self.simd.reduce_max_i64x8(self)
12821 }
12822 #[inline(always)]
12823 fn reduce_min_precise(self) -> Self::Element {
12824 self.simd.reduce_min_i64x8(self)
12825 }
12826 #[inline(always)]
12827 fn reduce_sum(self) -> Self::Element {
12828 self.simd.reduce_sum_i64x8(self)
12829 }
12830 #[inline(always)]
12831 fn reduce_product(self) -> Self::Element {
12832 self.simd.reduce_product_i64x8(self)
12833 }
12834 #[inline(always)]
12835 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
12836 self.simd.max_i64x8(self, rhs.simd_into(self.simd))
12837 }
12838 #[inline(always)]
12839 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
12840 self.simd.min_i64x8(self, rhs.simd_into(self.simd))
12841 }
12842 #[inline(always)]
12843 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
12844 self.simd.max_i64x8(self, rhs.simd_into(self.simd))
12845 }
12846 #[inline(always)]
12847 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
12848 self.simd.min_i64x8(self, rhs.simd_into(self.simd))
12849 }
12850 #[inline(always)]
12851 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
12852 self.simd
12853 .clamp_i64x8(self, min.simd_into(self.simd), max.simd_into(self.simd))
12854 }
12855 #[inline(always)]
12856 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
12857 self.simd.simd_eq_i64x8(self, rhs.simd_into(self.simd))
12858 }
12859 #[inline(always)]
12860 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
12861 self.simd.simd_ne_i64x8(self, rhs.simd_into(self.simd))
12862 }
12863 #[inline(always)]
12864 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
12865 self.simd.simd_lt_i64x8(self, rhs.simd_into(self.simd))
12866 }
12867 #[inline(always)]
12868 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
12869 self.simd.simd_le_i64x8(self, rhs.simd_into(self.simd))
12870 }
12871 #[inline(always)]
12872 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
12873 self.simd.simd_ge_i64x8(self, rhs.simd_into(self.simd))
12874 }
12875 #[inline(always)]
12876 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
12877 self.simd.simd_gt_i64x8(self, rhs.simd_into(self.simd))
12878 }
12879 #[inline(always)]
12880 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
12881 self.simd.zip_low_i64x8(self, rhs.simd_into(self.simd))
12882 }
12883 #[inline(always)]
12884 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
12885 self.simd.zip_high_i64x8(self, rhs.simd_into(self.simd))
12886 }
12887 #[inline(always)]
12888 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
12889 self.simd.unzip_low_i64x8(self, rhs.simd_into(self.simd))
12890 }
12891 #[inline(always)]
12892 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
12893 self.simd.unzip_high_i64x8(self, rhs.simd_into(self.simd))
12894 }
12895 #[inline(always)]
12896 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
12897 self.simd.interleave_i64x8(self, rhs.simd_into(self.simd))
12898 }
12899 #[inline(always)]
12900 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
12901 self.simd.deinterleave_i64x8(self, rhs.simd_into(self.simd))
12902 }
12903}
12904impl<S: Simd> crate::SimdInt<S> for i64x8<S> {
12905 #[inline(always)]
12906 fn count_ones(self) -> Self {
12907 self.simd.count_ones_i64x8(self)
12908 }
12909 #[inline(always)]
12910 fn count_zeros(self) -> Self {
12911 self.simd.count_zeros_i64x8(self)
12912 }
12913 #[inline(always)]
12914 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
12915 self.simd
12916 .saturating_add_i64x8(self, rhs.simd_into(self.simd))
12917 }
12918 #[inline(always)]
12919 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
12920 self.simd
12921 .saturating_sub_i64x8(self, rhs.simd_into(self.simd))
12922 }
12923}
12924impl<S: Simd> SimdCvtTruncate<f64x8<S>> for i64x8<S> {
12925 #[doc = "Convert each floating-point element to a signed 64-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
12926 #[inline(always)]
12927 fn truncate_from(x: f64x8<S>) -> Self {
12928 x.simd.cvt_i64_f64x8(x)
12929 }
12930 #[doc = "Convert each floating-point element to a signed 64-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
12931 #[inline(always)]
12932 fn truncate_from_precise(x: f64x8<S>) -> Self {
12933 x.simd.cvt_i64_precise_f64x8(x)
12934 }
12935}
12936impl<S: Simd> SimdNarrow<S> for i64x8<S> {
12937 type Narrowed = i32x16<S>;
12938 #[inline(always)]
12939 fn narrow(self, high: Self) -> Self::Narrowed {
12940 self.simd.narrow_i64x8(self, high)
12941 }
12942 #[inline(always)]
12943 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
12944 self.simd.saturating_narrow_i64x8(self, high)
12945 }
12946 #[inline(always)]
12947 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
12948 self.simd.relaxed_narrow_i64x8(self, high)
12949 }
12950}
12951impl<S: Simd> crate::SimdSplit<S> for i64x8<S> {
12952 type Split = i64x4<S>;
12953 #[inline(always)]
12954 fn split(self) -> (Self::Split, Self::Split) {
12955 self.simd.split_i64x8(self)
12956 }
12957}
12958impl<S: Simd> ExtractToken for u64x8<S> {
12959 type S = S;
12960 #[inline]
12961 fn token(&self) -> S {
12962 self.simd
12963 }
12964}
12965#[doc = "A SIMD vector of 8 [`u64`] elements.\n\nThis type's memory layout is identical to that of [`[u64; 8]`](prim@array), except that it is aligned to 64 bytes.\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::*, u64x8};\nfn construct_simd<S: Simd>(simd: S) {\n // From a single scalar value:\n let a = u64x8::splat(simd, 1);\n let b = u64x8::simd_from(simd, 1);\n\n // From a slice:\n let c = u64x8::from_slice(simd, &[1, 2, 3, 4, 5, 6, 7, 8]);\n\n // From an array:\n let d = u64x8::simd_from(simd, [1, 2, 3, 4, 5, 6, 7, 8]);\n\n // From an element-wise function:\n let e = u64x8::from_fn(simd, |i| i as u64);\n # use fearless_simd::u64x2;\n // From `Self::Block`:\n let f = u64x8::block_splat(u64x2::simd_from(simd, [1, 2]));\n}\n```"]
12966#[derive(Clone, Copy)]
12967#[repr(C, align(64))]
12968pub struct u64x8<S: Simd> {
12969 pub(crate) val: S::u64x8,
12970 pub simd: S,
12971}
12972impl<S: Simd> Seal for u64x8<S> {}
12973impl<S: Simd> SimdFrom<[u64; 8], S> for u64x8<S> {
12974 #[inline(always)]
12975 fn simd_from(simd: S, val: [u64; 8]) -> Self {
12976 Self {
12977 val: crate::transmute::checked_transmute_copy(&val),
12978 simd,
12979 }
12980 }
12981}
12982impl<S: Simd> From<u64x8<S>> for [u64; 8] {
12983 #[inline(always)]
12984 fn from(value: u64x8<S>) -> Self {
12985 crate::transmute::checked_transmute_copy(&value.val)
12986 }
12987}
12988impl<S: Simd> core::ops::Deref for u64x8<S> {
12989 type Target = [u64; 8];
12990 #[inline(always)]
12991 fn deref(&self) -> &Self::Target {
12992 crate::transmute::checked_cast_ref(&self.val)
12993 }
12994}
12995impl<S: Simd> core::ops::DerefMut for u64x8<S> {
12996 #[inline(always)]
12997 fn deref_mut(&mut self) -> &mut Self::Target {
12998 crate::transmute::checked_cast_mut(&mut self.val)
12999 }
13000}
13001impl<S: Simd + core::fmt::Debug> core::fmt::Debug for u64x8<S> {
13002 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
13003 crate::support::simd_debug_impl(f, "u64x8", &self.simd, self.as_array())
13004 }
13005}
13006impl<S: Simd> SimdFrom<u64, S> for u64x8<S> {
13007 #[inline(always)]
13008 fn simd_from(simd: S, value: u64) -> Self {
13009 simd.splat_u64x8(value)
13010 }
13011}
13012impl<S: Simd> core::ops::Index<usize> for u64x8<S> {
13013 type Output = u64;
13014 #[inline(always)]
13015 fn index(&self, i: usize) -> &Self::Output {
13016 &self.as_array()[i]
13017 }
13018}
13019impl<S: Simd> core::ops::IndexMut<usize> for u64x8<S> {
13020 #[inline(always)]
13021 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
13022 &mut self.as_mut_array()[i]
13023 }
13024}
13025impl<S: Simd> Select<u64x8<S>> for mask64x8<S> {
13026 #[inline(always)]
13027 fn select(self, if_true: u64x8<S>, if_false: u64x8<S>) -> u64x8<S> {
13028 self.simd.select_u64x8(self, if_true, if_false)
13029 }
13030}
13031impl<S: Simd> Bytes for u64x8<S> {
13032 type Bytes = u8x64<S>;
13033 #[inline(always)]
13034 fn to_bytes(self) -> Self::Bytes {
13035 u8x64 {
13036 val: crate::transmute::checked_transmute_copy(&self.val),
13037 simd: self.simd,
13038 }
13039 }
13040 #[inline(always)]
13041 fn from_bytes(value: Self::Bytes) -> Self {
13042 Self {
13043 val: crate::transmute::checked_transmute_copy(&value.val),
13044 simd: value.simd,
13045 }
13046 }
13047}
13048impl<S: Simd> SimdBase<S> for u64x8<S> {
13049 type Element = u64;
13050 type ByteVector = u8x64<S>;
13051 const LEN: usize = 8;
13052 type Mask = mask64x8<S>;
13053 type Block = u64x2<S>;
13054 type Array = [u64; 8];
13055 #[inline(always)]
13056 fn as_slice(&self) -> &[u64] {
13057 self.as_array().as_slice()
13058 }
13059 #[inline(always)]
13060 fn as_mut_slice(&mut self) -> &mut [u64] {
13061 self.as_mut_array().as_mut_slice()
13062 }
13063 #[inline(always)]
13064 fn from_slice(simd: S, slice: &[u64]) -> Self {
13065 Self::load_array_ref(simd, slice.try_into().unwrap())
13066 }
13067 #[inline(always)]
13068 fn store_slice(&self, slice: &mut [u64]) {
13069 (*self).store_array(slice.try_into().unwrap());
13070 }
13071 #[inline(always)]
13072 fn splat(simd: S, val: u64) -> Self {
13073 simd.splat_u64x8(val)
13074 }
13075 #[inline(always)]
13076 fn block_splat(block: Self::Block) -> Self {
13077 let block2 = block.simd.combine_u64x2(block, block);
13078 block2.simd.combine_u64x4(block2, block2)
13079 }
13080 #[inline(always)]
13081 fn from_fn(simd: S, mut f: impl FnMut(usize) -> u64) -> Self {
13082 Self::load_array(
13083 simd,
13084 [
13085 f(0usize),
13086 f(1usize),
13087 f(2usize),
13088 f(3usize),
13089 f(4usize),
13090 f(5usize),
13091 f(6usize),
13092 f(7usize),
13093 ],
13094 )
13095 }
13096 #[inline(always)]
13097 fn slide<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
13098 self.simd
13099 .slide_u64x8::<SHIFT>(self, rhs.simd_into(self.simd))
13100 }
13101 #[inline(always)]
13102 fn slide_within_blocks<const SHIFT: usize>(self, rhs: impl SimdInto<Self, S>) -> Self {
13103 self.simd
13104 .slide_within_blocks_u64x8::<SHIFT>(self, rhs.simd_into(self.simd))
13105 }
13106 #[inline(always)]
13107 fn swizzle_dyn_within_blocks(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
13108 self.simd
13109 .swizzle_dyn_within_blocks_u64x8(self, indices.simd_into(self.simd))
13110 }
13111 #[inline(always)]
13112 fn swizzle_dyn(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
13113 self.simd
13114 .swizzle_dyn_u64x8(self, indices.simd_into(self.simd))
13115 }
13116 #[inline(always)]
13117 fn swizzle_dyn_precise(self, indices: impl SimdInto<Self::Bytes, S>) -> Self {
13118 self.simd
13119 .swizzle_dyn_precise_u64x8(self, indices.simd_into(self.simd))
13120 }
13121 #[inline(always)]
13122 fn abs(self) -> Self {
13123 self.simd.abs_u64x8(self)
13124 }
13125 #[inline(always)]
13126 fn reverse(self) -> Self {
13127 self.simd.reverse_u64x8(self)
13128 }
13129 #[inline(always)]
13130 fn concat_swizzle_dyn(
13131 self,
13132 rhs: impl SimdInto<Self, S>,
13133 indices: impl SimdInto<Self::Bytes, S>,
13134 ) -> Self {
13135 self.simd.concat_swizzle_dyn_u64x8(
13136 self,
13137 rhs.simd_into(self.simd),
13138 indices.simd_into(self.simd),
13139 )
13140 }
13141 #[inline(always)]
13142 fn concat_swizzle_dyn_precise(
13143 self,
13144 rhs: impl SimdInto<Self, S>,
13145 indices: impl SimdInto<Self::Bytes, S>,
13146 ) -> Self {
13147 self.simd.concat_swizzle_dyn_precise_u64x8(
13148 self,
13149 rhs.simd_into(self.simd),
13150 indices.simd_into(self.simd),
13151 )
13152 }
13153 #[inline(always)]
13154 fn compress(self, mask: Self::Mask) -> Self {
13155 self.simd.compress_u64x8(self, mask)
13156 }
13157 #[inline(always)]
13158 fn compress_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
13159 self.simd
13160 .compress_merge_u64x8(self, mask, merge.simd_into(self.simd))
13161 }
13162 #[inline(always)]
13163 fn expand(self, mask: Self::Mask) -> Self {
13164 self.simd.expand_u64x8(self, mask)
13165 }
13166 #[inline(always)]
13167 fn expand_merge(self, mask: Self::Mask, merge: impl SimdInto<Self, S>) -> Self {
13168 self.simd
13169 .expand_merge_u64x8(self, mask, merge.simd_into(self.simd))
13170 }
13171 #[inline(always)]
13172 fn reduce_max(self) -> Self::Element {
13173 self.simd.reduce_max_u64x8(self)
13174 }
13175 #[inline(always)]
13176 fn reduce_min(self) -> Self::Element {
13177 self.simd.reduce_min_u64x8(self)
13178 }
13179 #[inline(always)]
13180 fn reduce_max_precise(self) -> Self::Element {
13181 self.simd.reduce_max_u64x8(self)
13182 }
13183 #[inline(always)]
13184 fn reduce_min_precise(self) -> Self::Element {
13185 self.simd.reduce_min_u64x8(self)
13186 }
13187 #[inline(always)]
13188 fn reduce_sum(self) -> Self::Element {
13189 self.simd.reduce_sum_u64x8(self)
13190 }
13191 #[inline(always)]
13192 fn reduce_product(self) -> Self::Element {
13193 self.simd.reduce_product_u64x8(self)
13194 }
13195 #[inline(always)]
13196 fn max(self, rhs: impl SimdInto<Self, S>) -> Self {
13197 self.simd.max_u64x8(self, rhs.simd_into(self.simd))
13198 }
13199 #[inline(always)]
13200 fn min(self, rhs: impl SimdInto<Self, S>) -> Self {
13201 self.simd.min_u64x8(self, rhs.simd_into(self.simd))
13202 }
13203 #[inline(always)]
13204 fn max_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
13205 self.simd.max_u64x8(self, rhs.simd_into(self.simd))
13206 }
13207 #[inline(always)]
13208 fn min_precise(self, rhs: impl SimdInto<Self, S>) -> Self {
13209 self.simd.min_u64x8(self, rhs.simd_into(self.simd))
13210 }
13211 #[inline(always)]
13212 fn clamp(self, min: impl SimdInto<Self, S>, max: impl SimdInto<Self, S>) -> Self {
13213 self.simd
13214 .clamp_u64x8(self, min.simd_into(self.simd), max.simd_into(self.simd))
13215 }
13216 #[inline(always)]
13217 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
13218 self.simd.simd_eq_u64x8(self, rhs.simd_into(self.simd))
13219 }
13220 #[inline(always)]
13221 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
13222 self.simd.simd_ne_u64x8(self, rhs.simd_into(self.simd))
13223 }
13224 #[inline(always)]
13225 fn simd_lt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
13226 self.simd.simd_lt_u64x8(self, rhs.simd_into(self.simd))
13227 }
13228 #[inline(always)]
13229 fn simd_le(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
13230 self.simd.simd_le_u64x8(self, rhs.simd_into(self.simd))
13231 }
13232 #[inline(always)]
13233 fn simd_ge(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
13234 self.simd.simd_ge_u64x8(self, rhs.simd_into(self.simd))
13235 }
13236 #[inline(always)]
13237 fn simd_gt(self, rhs: impl SimdInto<Self, S>) -> Self::Mask {
13238 self.simd.simd_gt_u64x8(self, rhs.simd_into(self.simd))
13239 }
13240 #[inline(always)]
13241 fn zip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
13242 self.simd.zip_low_u64x8(self, rhs.simd_into(self.simd))
13243 }
13244 #[inline(always)]
13245 fn zip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
13246 self.simd.zip_high_u64x8(self, rhs.simd_into(self.simd))
13247 }
13248 #[inline(always)]
13249 fn unzip_low(self, rhs: impl SimdInto<Self, S>) -> Self {
13250 self.simd.unzip_low_u64x8(self, rhs.simd_into(self.simd))
13251 }
13252 #[inline(always)]
13253 fn unzip_high(self, rhs: impl SimdInto<Self, S>) -> Self {
13254 self.simd.unzip_high_u64x8(self, rhs.simd_into(self.simd))
13255 }
13256 #[inline(always)]
13257 fn interleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
13258 self.simd.interleave_u64x8(self, rhs.simd_into(self.simd))
13259 }
13260 #[inline(always)]
13261 fn deinterleave(self, rhs: impl SimdInto<Self, S>) -> (Self, Self) {
13262 self.simd.deinterleave_u64x8(self, rhs.simd_into(self.simd))
13263 }
13264}
13265impl<S: Simd> crate::SimdInt<S> for u64x8<S> {
13266 #[inline(always)]
13267 fn count_ones(self) -> Self {
13268 self.simd.count_ones_u64x8(self)
13269 }
13270 #[inline(always)]
13271 fn count_zeros(self) -> Self {
13272 self.simd.count_zeros_u64x8(self)
13273 }
13274 #[inline(always)]
13275 fn saturating_add(self, rhs: impl SimdInto<Self, S>) -> Self {
13276 self.simd
13277 .saturating_add_u64x8(self, rhs.simd_into(self.simd))
13278 }
13279 #[inline(always)]
13280 fn saturating_sub(self, rhs: impl SimdInto<Self, S>) -> Self {
13281 self.simd
13282 .saturating_sub_u64x8(self, rhs.simd_into(self.simd))
13283 }
13284}
13285impl<S: Simd> SimdCvtTruncate<f64x8<S>> for u64x8<S> {
13286 #[doc = "Convert each floating-point element to an unsigned 64-bit integer, truncating towards zero.\n\nOut-of-range values or NaN will produce implementation-defined results."]
13287 #[inline(always)]
13288 fn truncate_from(x: f64x8<S>) -> Self {
13289 x.simd.cvt_u64_f64x8(x)
13290 }
13291 #[doc = "Convert each floating-point element to an unsigned 64-bit integer, truncating towards zero.\n\nOut-of-range values are saturated to the closest in-range value. NaN becomes 0."]
13292 #[inline(always)]
13293 fn truncate_from_precise(x: f64x8<S>) -> Self {
13294 x.simd.cvt_u64_precise_f64x8(x)
13295 }
13296}
13297impl<S: Simd> SimdNarrow<S> for u64x8<S> {
13298 type Narrowed = u32x16<S>;
13299 #[inline(always)]
13300 fn narrow(self, high: Self) -> Self::Narrowed {
13301 self.simd.narrow_u64x8(self, high)
13302 }
13303 #[inline(always)]
13304 fn saturating_narrow(self, high: Self) -> Self::Narrowed {
13305 self.simd.saturating_narrow_u64x8(self, high)
13306 }
13307 #[inline(always)]
13308 fn relaxed_narrow(self, high: Self) -> Self::Narrowed {
13309 self.simd.relaxed_narrow_u64x8(self, high)
13310 }
13311}
13312impl<S: Simd> crate::SimdSplit<S> for u64x8<S> {
13313 type Split = u64x4<S>;
13314 #[inline(always)]
13315 fn split(self) -> (Self::Split, Self::Split) {
13316 self.simd.split_u64x8(self)
13317 }
13318}
13319impl<S: Simd> ExtractToken for mask64x8<S> {
13320 type S = S;
13321 #[inline]
13322 fn token(&self) -> S {
13323 self.simd
13324 }
13325}
13326#[doc = "A SIMD mask of 8 logical lanes corresponding to 64-bit vector elements.\n\nThe storage representation of this type is intentionally opaque and may vary depending on the SIMD level.\n\nYou can construct this mask type using the [`Self::splat`], [`Self::from_bitmask`], [`Self::from_slice`], and [`Self::simd_from`] methods.\n\n```rust\n# use fearless_simd::{prelude::*, mask64x8};\nfn construct_mask<S: Simd>(simd: S) {\n // From a single boolean value:\n let a = mask64x8::splat(simd, true);\n let b = mask64x8::simd_from(simd, true);\n\n // From signed integer mask lanes:\n let c = mask64x8::from_slice(simd, &[-1, 0, 0, 0, 0, 0, 0, 0]);\n let d = mask64x8::simd_from(simd, [-1, 0, 0, 0, 0, 0, 0, 0]);\n\n // From a compact bitmask (same mask as above, least significant bit maps to lane 0):\n let e = mask64x8::from_bitmask(simd, 0b0001);\n\n // By setting individual lanes:\n let mut f = mask64x8::splat(simd, false);\n f.set(0, true);\n}\n```"]
13327#[derive(Clone, Copy)]
13328pub struct mask64x8<S: Simd> {
13329 pub(crate) val: S::mask64x8,
13330 pub(crate) simd: S,
13331}
13332impl<S: Simd> Seal for mask64x8<S> {}
13333impl<S: Simd> SimdFrom<[i64; 8], S> for mask64x8<S> {
13334 #[inline(always)]
13335 fn simd_from(simd: S, val: [i64; 8]) -> Self {
13336 Self {
13337 val: <S as crate::arch_types::ArchTypes>::mask64x8_from_array(simd, val),
13338 simd,
13339 }
13340 }
13341}
13342impl<S: Simd> From<mask64x8<S>> for [i64; 8] {
13343 #[inline(always)]
13344 fn from(value: mask64x8<S>) -> Self {
13345 <S as crate::arch_types::ArchTypes>::mask64x8_to_array(value.simd, value.val)
13346 }
13347}
13348impl<S: Simd + core::fmt::Debug> core::fmt::Debug for mask64x8<S> {
13349 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
13350 let lanes: [i64; 8] = (*self).into();
13351 crate::support::simd_debug_impl(f, "mask64x8", &self.simd, &lanes)
13352 }
13353}
13354impl<S: Simd> SimdFrom<bool, S> for mask64x8<S> {
13355 #[inline(always)]
13356 fn simd_from(simd: S, value: bool) -> Self {
13357 simd.splat_mask64x8(value)
13358 }
13359}
13360impl<S: Simd> Select<mask64x8<S>> for mask64x8<S> {
13361 #[inline(always)]
13362 fn select(self, if_true: mask64x8<S>, if_false: mask64x8<S>) -> mask64x8<S> {
13363 self.simd.select_mask64x8(self, if_true, if_false)
13364 }
13365}
13366impl<S: Simd> SimdMask<S> for mask64x8<S> {
13367 type Element = i64;
13368 type Ints = i64x8<S>;
13369 const LEN: usize = 8;
13370 #[inline(always)]
13371 fn splat(simd: S, val: bool) -> Self {
13372 simd.splat_mask64x8(val)
13373 }
13374 #[inline(always)]
13375 fn from_bitmask(simd: S, bits: u64) -> Self {
13376 simd.from_bitmask_mask64x8(bits)
13377 }
13378 #[inline(always)]
13379 fn to_bitmask(self) -> u64 {
13380 self.simd.to_bitmask_mask64x8(self)
13381 }
13382 #[inline(always)]
13383 fn from_vector(vector: Self::Ints) -> Self {
13384 vector.token().from_vector_mask64x8(vector)
13385 }
13386 #[inline(always)]
13387 fn to_vector(self) -> Self::Ints {
13388 self.simd.to_vector_mask64x8(self)
13389 }
13390 #[inline(always)]
13391 fn set(&mut self, index: usize, value: bool) {
13392 self.simd.set_mask64x8(self, index, value);
13393 }
13394 #[inline(always)]
13395 fn from_slice(simd: S, slice: &[i64]) -> Self {
13396 let slice: &[i64; 8] = slice.try_into().unwrap();
13397 Self::simd_from(simd, *slice)
13398 }
13399 #[inline(always)]
13400 fn store_slice(&self, slice: &mut [i64]) {
13401 let slice: &mut [i64; 8] = slice.try_into().unwrap();
13402 *slice = (*self).into();
13403 }
13404 #[inline(always)]
13405 fn rotate_elements_left<const OFFSET: usize>(self) -> Self {
13406 self.simd.rotate_elements_left_mask64x8::<OFFSET>(self)
13407 }
13408 #[inline(always)]
13409 fn rotate_elements_right<const OFFSET: usize>(self) -> Self {
13410 self.simd.rotate_elements_right_mask64x8::<OFFSET>(self)
13411 }
13412 #[inline(always)]
13413 fn reverse(self) -> Self {
13414 self.simd.reverse_mask64x8(self)
13415 }
13416 #[inline(always)]
13417 fn simd_eq(self, rhs: impl SimdInto<Self, S>) -> Self {
13418 self.simd.simd_eq_mask64x8(self, rhs.simd_into(self.simd))
13419 }
13420 #[inline(always)]
13421 fn simd_ne(self, rhs: impl SimdInto<Self, S>) -> Self {
13422 self.simd.simd_ne_mask64x8(self, rhs.simd_into(self.simd))
13423 }
13424 #[inline(always)]
13425 fn any_true(self) -> bool {
13426 self.simd.any_true_mask64x8(self)
13427 }
13428 #[inline(always)]
13429 fn all_true(self) -> bool {
13430 self.simd.all_true_mask64x8(self)
13431 }
13432 #[inline(always)]
13433 fn any_false(self) -> bool {
13434 self.simd.any_false_mask64x8(self)
13435 }
13436 #[inline(always)]
13437 fn all_false(self) -> bool {
13438 self.simd.all_false_mask64x8(self)
13439 }
13440}
13441impl<S: Simd> MaskNarrow<S> for mask64x8<S> {
13442 type Narrowed = mask32x16<S>;
13443 #[inline(always)]
13444 fn narrow(self, high: Self) -> Self::Narrowed {
13445 self.simd.narrow_mask64x8(self, high)
13446 }
13447}