1use std::ops::{
6 Add, AddAssign, BitAnd, BitOr, BitOrAssign, BitXor, Div, Mul, MulAssign, Neg, Not, Sub,
7};
8
9#[derive(Clone, Copy, Debug, Default)]
10pub struct m8x16([u8; 16]);
11
12impl m8x16 {
13 pub fn all(self) -> bool {
14 self.0.iter().all(|&val| val == u8::MAX)
15 }
16}
17
18#[derive(Clone, Copy, Debug, Default)]
19pub struct m32x4([u32; 4]);
20
21#[derive(Clone, Copy, Debug, Default)]
22pub struct m32x8([u32; 8]);
23
24impl m32x8 {
25 pub fn all(self) -> bool {
26 self.0.iter().all(|&val| val == u32::MAX)
27 }
28
29 pub fn any(self) -> bool {
30 self.0.contains(&u32::MAX)
31 }
32}
33
34impl Not for m32x8 {
35 type Output = Self;
36
37 fn not(mut self) -> Self::Output {
38 self.0.iter_mut().for_each(|t| *t = !*t);
39 self
40 }
41}
42
43impl BitOr for m32x8 {
44 type Output = Self;
45
46 fn bitor(mut self, rhs: Self) -> Self::Output {
47 self.0.iter_mut().zip(rhs.0.iter()).for_each(|(t, &o)| *t |= o);
48 self
49 }
50}
51
52impl BitOrAssign for m32x8 {
53 fn bitor_assign(&mut self, rhs: Self) {
54 *self = *self | rhs;
55 }
56}
57
58impl BitXor for m32x8 {
59 type Output = Self;
60
61 fn bitxor(mut self, rhs: Self) -> Self::Output {
62 self.0.iter_mut().zip(rhs.0.iter()).for_each(|(t, &o)| *t ^= o);
63 self
64 }
65}
66
67#[derive(Clone, Copy, Debug, Default)]
68#[allow(dead_code)]
70pub struct u8x8([u8; 8]);
71
72impl From<f32x8> for u8x8 {
73 fn from(val: f32x8) -> Self {
74 Self([
75 val.0[0].round() as u8,
76 val.0[1].round() as u8,
77 val.0[2].round() as u8,
78 val.0[3].round() as u8,
79 val.0[4].round() as u8,
80 val.0[5].round() as u8,
81 val.0[6].round() as u8,
82 val.0[7].round() as u8,
83 ])
84 }
85}
86
87#[derive(Clone, Copy, Debug, Default)]
88#[allow(dead_code)]
90pub struct u8x32([u8; 32]);
91
92impl u8x32 {
93 pub fn splat(val: u8) -> Self {
94 Self([
95 val, val, val, val, val, val, val, val, val, val, val, val, val, val, val, val, val,
96 val, val, val, val, val, val, val, val, val, val, val, val, val, val, val,
97 ])
98 }
99
100 pub fn from_u32_interleaved(vals: [u32x8; 4]) -> Self {
101 Self([
102 vals[0].0[0] as u8,
103 vals[1].0[0] as u8,
104 vals[2].0[0] as u8,
105 vals[3].0[0] as u8,
106 vals[0].0[1] as u8,
107 vals[1].0[1] as u8,
108 vals[2].0[1] as u8,
109 vals[3].0[1] as u8,
110 vals[0].0[2] as u8,
111 vals[1].0[2] as u8,
112 vals[2].0[2] as u8,
113 vals[3].0[2] as u8,
114 vals[0].0[3] as u8,
115 vals[1].0[3] as u8,
116 vals[2].0[3] as u8,
117 vals[3].0[3] as u8,
118 vals[0].0[4] as u8,
119 vals[1].0[4] as u8,
120 vals[2].0[4] as u8,
121 vals[3].0[4] as u8,
122 vals[0].0[5] as u8,
123 vals[1].0[5] as u8,
124 vals[2].0[5] as u8,
125 vals[3].0[5] as u8,
126 vals[0].0[6] as u8,
127 vals[1].0[6] as u8,
128 vals[2].0[6] as u8,
129 vals[3].0[6] as u8,
130 vals[0].0[7] as u8,
131 vals[1].0[7] as u8,
132 vals[2].0[7] as u8,
133 vals[3].0[7] as u8,
134 ])
135 }
136}
137
138#[derive(Clone, Copy, Debug, Default)]
139pub struct i8x16([i8; 16]);
140
141impl i8x16 {
142 pub fn splat(val: i8) -> Self {
143 Self([val, val, val, val, val, val, val, val, val, val, val, val, val, val, val, val])
144 }
145
146 #[cfg(test)]
147 pub fn as_mut_array(&mut self) -> &mut [i8; 16] {
148 &mut self.0
149 }
150
151 pub fn eq(self, other: Self) -> m8x16 {
152 m8x16([
153 if self.0[0] == other.0[0] { u8::MAX } else { 0 },
154 if self.0[1] == other.0[1] { u8::MAX } else { 0 },
155 if self.0[2] == other.0[2] { u8::MAX } else { 0 },
156 if self.0[3] == other.0[3] { u8::MAX } else { 0 },
157 if self.0[4] == other.0[4] { u8::MAX } else { 0 },
158 if self.0[5] == other.0[5] { u8::MAX } else { 0 },
159 if self.0[6] == other.0[6] { u8::MAX } else { 0 },
160 if self.0[7] == other.0[7] { u8::MAX } else { 0 },
161 if self.0[8] == other.0[8] { u8::MAX } else { 0 },
162 if self.0[9] == other.0[9] { u8::MAX } else { 0 },
163 if self.0[10] == other.0[10] { u8::MAX } else { 0 },
164 if self.0[11] == other.0[11] { u8::MAX } else { 0 },
165 if self.0[12] == other.0[12] { u8::MAX } else { 0 },
166 if self.0[13] == other.0[13] { u8::MAX } else { 0 },
167 if self.0[14] == other.0[14] { u8::MAX } else { 0 },
168 if self.0[15] == other.0[15] { u8::MAX } else { 0 },
169 ])
170 }
171
172 pub fn abs(mut self) -> Self {
173 self.0.iter_mut().for_each(|val| *val = val.abs());
174 self
175 }
176}
177
178impl Add for i8x16 {
179 type Output = Self;
180
181 fn add(mut self, rhs: Self) -> Self::Output {
182 self.0.iter_mut().zip(rhs.0.iter()).for_each(|(t, &o)| *t += o);
183 self
184 }
185}
186
187impl AddAssign for i8x16 {
188 fn add_assign(&mut self, rhs: Self) {
189 *self = *self + rhs;
190 }
191}
192
193impl BitAnd for i8x16 {
194 type Output = Self;
195
196 fn bitand(mut self, rhs: Self) -> Self::Output {
197 self.0.iter_mut().zip(rhs.0.iter()).for_each(|(t, &o)| *t &= o);
198 self
199 }
200}
201
202impl From<i8x16> for [i32x8; 2] {
203 fn from(val: i8x16) -> Self {
204 [
205 i32x8([
206 val.0[0] as i32,
207 val.0[1] as i32,
208 val.0[2] as i32,
209 val.0[3] as i32,
210 val.0[4] as i32,
211 val.0[5] as i32,
212 val.0[6] as i32,
213 val.0[7] as i32,
214 ]),
215 i32x8([
216 val.0[8] as i32,
217 val.0[9] as i32,
218 val.0[10] as i32,
219 val.0[11] as i32,
220 val.0[12] as i32,
221 val.0[13] as i32,
222 val.0[14] as i32,
223 val.0[15] as i32,
224 ]),
225 ]
226 }
227}
228
229#[derive(Clone, Copy, Debug, Default)]
230pub struct i16x16([i16; 16]);
231
232impl i16x16 {
233 pub fn splat(val: i16) -> Self {
234 Self([val, val, val, val, val, val, val, val, val, val, val, val, val, val, val, val])
235 }
236}
237
238impl From<i16x16> for [i32x8; 2] {
239 fn from(val: i16x16) -> Self {
240 [
241 i32x8([
242 val.0[0] as i32,
243 val.0[1] as i32,
244 val.0[2] as i32,
245 val.0[3] as i32,
246 val.0[4] as i32,
247 val.0[5] as i32,
248 val.0[6] as i32,
249 val.0[7] as i32,
250 ]),
251 i32x8([
252 val.0[8] as i32,
253 val.0[9] as i32,
254 val.0[10] as i32,
255 val.0[11] as i32,
256 val.0[12] as i32,
257 val.0[13] as i32,
258 val.0[14] as i32,
259 val.0[15] as i32,
260 ]),
261 ]
262 }
263}
264
265#[derive(Clone, Copy, Debug, Default)]
266pub struct i32x8([i32; 8]);
267
268impl i32x8 {
269 pub fn splat(val: i32) -> Self {
270 Self([val, val, val, val, val, val, val, val])
271 }
272
273 pub fn eq(self, other: Self) -> m32x8 {
274 m32x8([
275 if self.0[0] == other.0[0] { u32::MAX } else { 0 },
276 if self.0[1] == other.0[1] { u32::MAX } else { 0 },
277 if self.0[2] == other.0[2] { u32::MAX } else { 0 },
278 if self.0[3] == other.0[3] { u32::MAX } else { 0 },
279 if self.0[4] == other.0[4] { u32::MAX } else { 0 },
280 if self.0[5] == other.0[5] { u32::MAX } else { 0 },
281 if self.0[6] == other.0[6] { u32::MAX } else { 0 },
282 if self.0[7] == other.0[7] { u32::MAX } else { 0 },
283 ])
284 }
285
286 pub fn shr<const N: i32>(mut self) -> Self {
287 self.0.iter_mut().for_each(|t| *t >>= N);
288 self
289 }
290
291 pub fn abs(mut self) -> Self {
292 self.0.iter_mut().for_each(|t| *t = t.abs());
293 self
294 }
295}
296
297impl Add for i32x8 {
298 type Output = Self;
299
300 fn add(mut self, rhs: Self) -> Self::Output {
301 self.0.iter_mut().zip(rhs.0.iter()).for_each(|(t, &o)| *t += o);
302 self
303 }
304}
305
306impl Sub for i32x8 {
307 type Output = Self;
308
309 fn sub(mut self, rhs: Self) -> Self::Output {
310 self.0.iter_mut().zip(rhs.0.iter()).for_each(|(t, &o)| *t -= o);
311 self
312 }
313}
314
315impl Mul for i32x8 {
316 type Output = Self;
317
318 fn mul(mut self, rhs: Self) -> Self::Output {
319 self.0.iter_mut().zip(rhs.0.iter()).for_each(|(t, &o)| *t *= o);
320 self
321 }
322}
323
324impl BitAnd for i32x8 {
325 type Output = Self;
326
327 fn bitand(mut self, rhs: Self) -> Self::Output {
328 self.0.iter_mut().zip(rhs.0.iter()).for_each(|(t, &o)| *t &= o);
329 self
330 }
331}
332
333#[derive(Clone, Copy, Debug, Default)]
334pub struct u32x4([u32; 4]);
335
336impl u32x4 {
337 pub fn splat(val: u32) -> Self {
338 Self([val, val, val, val])
339 }
340}
341
342impl From<u32x4> for [u8; 4] {
343 fn from(val: u32x4) -> Self {
344 [val.0[0] as u8, val.0[1] as u8, val.0[2] as u8, val.0[3] as u8]
345 }
346}
347
348#[derive(Clone, Copy, Debug, Default)]
349pub struct u32x8([u32; 8]);
350
351impl u32x8 {
352 pub fn splat(val: u32) -> Self {
353 Self([val, val, val, val, val, val, val, val])
354 }
355
356 pub fn to_array(self) -> [u32; 8] {
357 self.0
358 }
359
360 pub fn mul_add(mut self, a: Self, b: Self) -> Self {
361 self.0.iter_mut().zip(a.0.iter().zip(b.0.iter())).for_each(|(t, (&a, &b))| *t = *t * a + b);
362 self
363 }
364}
365
366impl From<f32x8> for u32x8 {
367 fn from(val: f32x8) -> Self {
368 Self([
369 val.0[0] as u32,
370 val.0[1] as u32,
371 val.0[2] as u32,
372 val.0[3] as u32,
373 val.0[4] as u32,
374 val.0[5] as u32,
375 val.0[6] as u32,
376 val.0[7] as u32,
377 ])
378 }
379}
380
381#[derive(Clone, Copy, Debug, Default)]
382pub struct f32x4([f32; 4]);
383
384impl f32x4 {
385 pub fn new(vals: [f32; 4]) -> Self {
386 Self(vals)
387 }
388
389 pub fn splat(val: f32) -> Self {
390 Self([val, val, val, val])
391 }
392
393 pub fn from_bits(val: u32x4) -> Self {
394 Self([
395 f32::from_bits(val.0[0]),
396 f32::from_bits(val.0[1]),
397 f32::from_bits(val.0[2]),
398 f32::from_bits(val.0[3]),
399 ])
400 }
401
402 pub fn to_bits(self) -> u32x4 {
403 u32x4([self.0[0].to_bits(), self.0[1].to_bits(), self.0[2].to_bits(), self.0[3].to_bits()])
404 }
405
406 pub fn set<const INDEX: i32>(mut self, val: f32) -> Self {
407 self.0[INDEX as usize] = val;
408 self
409 }
410
411 pub fn le(self, other: Self) -> m32x4 {
412 m32x4([
413 if self.0[0] <= other.0[0] { u32::MAX } else { 0 },
414 if self.0[1] <= other.0[1] { u32::MAX } else { 0 },
415 if self.0[2] <= other.0[2] { u32::MAX } else { 0 },
416 if self.0[3] <= other.0[3] { u32::MAX } else { 0 },
417 ])
418 }
419
420 pub fn select(self, other: Self, mask: m32x4) -> Self {
421 Self([
422 if mask.0[0] == u32::MAX { self.0[0] } else { other.0[0] },
423 if mask.0[1] == u32::MAX { self.0[1] } else { other.0[1] },
424 if mask.0[2] == u32::MAX { self.0[2] } else { other.0[2] },
425 if mask.0[3] == u32::MAX { self.0[3] } else { other.0[3] },
426 ])
427 }
428
429 pub fn clamp(mut self, min: Self, max: Self) -> Self {
430 self.0
431 .iter_mut()
432 .zip(min.0.iter().zip(max.0.iter()))
433 .for_each(|(t, (&min, &max))| *t = t.clamp(min, max));
434 self
435 }
436
437 pub fn sqrt(mut self) -> Self {
438 self.0.iter_mut().for_each(|val| *val = val.sqrt());
439 self
440 }
441
442 pub fn mul_add(mut self, a: Self, b: Self) -> Self {
443 self.0
444 .iter_mut()
445 .zip(a.0.iter().zip(b.0.iter()))
446 .for_each(|(t, (&a, &b))| *t = t.mul_add(a, b));
447 self
448 }
449}
450
451impl Add for f32x4 {
452 type Output = Self;
453
454 fn add(mut self, rhs: Self) -> Self::Output {
455 self.0.iter_mut().zip(rhs.0.iter()).for_each(|(t, &o)| *t += o);
456 self
457 }
458}
459
460impl Mul for f32x4 {
461 type Output = Self;
462
463 fn mul(mut self, rhs: Self) -> Self::Output {
464 self.0.iter_mut().zip(rhs.0.iter()).for_each(|(t, &o)| *t *= o);
465 self
466 }
467}
468
469#[derive(Clone, Copy, Debug, Default)]
470pub struct f32x8([f32; 8]);
471
472impl f32x8 {
473 pub fn splat(val: f32) -> Self {
474 Self([val, val, val, val, val, val, val, val])
475 }
476
477 pub fn indexed() -> Self {
478 Self::from_array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0])
479 }
480
481 pub fn from_array(val: [f32; 8]) -> Self {
482 Self(val)
483 }
484
485 pub fn from_bits(val: u32x8) -> Self {
486 Self([
487 f32::from_bits(val.0[0]),
488 f32::from_bits(val.0[1]),
489 f32::from_bits(val.0[2]),
490 f32::from_bits(val.0[3]),
491 f32::from_bits(val.0[4]),
492 f32::from_bits(val.0[5]),
493 f32::from_bits(val.0[6]),
494 f32::from_bits(val.0[7]),
495 ])
496 }
497
498 pub fn to_bits(self) -> u32x8 {
499 u32x8([
500 self.0[0].to_bits(),
501 self.0[1].to_bits(),
502 self.0[2].to_bits(),
503 self.0[3].to_bits(),
504 self.0[4].to_bits(),
505 self.0[5].to_bits(),
506 self.0[6].to_bits(),
507 self.0[7].to_bits(),
508 ])
509 }
510
511 #[cfg(test)]
512 pub fn to_array(self) -> [f32; 8] {
513 self.0
514 }
515
516 pub fn eq(self, other: Self) -> m32x8 {
517 m32x8([
518 if self.0[0] == other.0[0] { u32::MAX } else { 0 },
519 if self.0[1] == other.0[1] { u32::MAX } else { 0 },
520 if self.0[2] == other.0[2] { u32::MAX } else { 0 },
521 if self.0[3] == other.0[3] { u32::MAX } else { 0 },
522 if self.0[4] == other.0[4] { u32::MAX } else { 0 },
523 if self.0[5] == other.0[5] { u32::MAX } else { 0 },
524 if self.0[6] == other.0[6] { u32::MAX } else { 0 },
525 if self.0[7] == other.0[7] { u32::MAX } else { 0 },
526 ])
527 }
528
529 pub fn lt(self, other: Self) -> m32x8 {
530 m32x8([
531 if self.0[0] < other.0[0] { u32::MAX } else { 0 },
532 if self.0[1] < other.0[1] { u32::MAX } else { 0 },
533 if self.0[2] < other.0[2] { u32::MAX } else { 0 },
534 if self.0[3] < other.0[3] { u32::MAX } else { 0 },
535 if self.0[4] < other.0[4] { u32::MAX } else { 0 },
536 if self.0[5] < other.0[5] { u32::MAX } else { 0 },
537 if self.0[6] < other.0[6] { u32::MAX } else { 0 },
538 if self.0[7] < other.0[7] { u32::MAX } else { 0 },
539 ])
540 }
541
542 pub fn le(self, other: Self) -> m32x8 {
543 m32x8([
544 if self.0[0] <= other.0[0] { u32::MAX } else { 0 },
545 if self.0[1] <= other.0[1] { u32::MAX } else { 0 },
546 if self.0[2] <= other.0[2] { u32::MAX } else { 0 },
547 if self.0[3] <= other.0[3] { u32::MAX } else { 0 },
548 if self.0[4] <= other.0[4] { u32::MAX } else { 0 },
549 if self.0[5] <= other.0[5] { u32::MAX } else { 0 },
550 if self.0[6] <= other.0[6] { u32::MAX } else { 0 },
551 if self.0[7] <= other.0[7] { u32::MAX } else { 0 },
552 ])
553 }
554
555 pub fn select(self, other: Self, mask: m32x8) -> Self {
556 Self([
557 if mask.0[0] == u32::MAX { self.0[0] } else { other.0[0] },
558 if mask.0[1] == u32::MAX { self.0[1] } else { other.0[1] },
559 if mask.0[2] == u32::MAX { self.0[2] } else { other.0[2] },
560 if mask.0[3] == u32::MAX { self.0[3] } else { other.0[3] },
561 if mask.0[4] == u32::MAX { self.0[4] } else { other.0[4] },
562 if mask.0[5] == u32::MAX { self.0[5] } else { other.0[5] },
563 if mask.0[6] == u32::MAX { self.0[6] } else { other.0[6] },
564 if mask.0[7] == u32::MAX { self.0[7] } else { other.0[7] },
565 ])
566 }
567
568 pub fn abs(mut self) -> Self {
569 self.0.iter_mut().for_each(|val| *val = val.abs());
570 self
571 }
572
573 pub fn min(mut self, other: Self) -> Self {
574 self.0.iter_mut().zip(other.0.iter()).for_each(|(t, &o)| *t = t.min(o));
575 self
576 }
577
578 pub fn max(mut self, other: Self) -> Self {
579 self.0.iter_mut().zip(other.0.iter()).for_each(|(t, &o)| *t = t.max(o));
580 self
581 }
582
583 pub fn clamp(mut self, min: Self, max: Self) -> Self {
584 self.0
585 .iter_mut()
586 .zip(min.0.iter().zip(max.0.iter()))
587 .for_each(|(t, (&min, &max))| *t = t.clamp(min, max));
588 self
589 }
590
591 pub fn sqrt(mut self) -> Self {
592 self.0.iter_mut().for_each(|val| *val = val.sqrt());
593 self
594 }
595
596 pub fn recip(mut self) -> Self {
597 self.0.iter_mut().for_each(|val| *val = val.recip());
598 self
599 }
600
601 pub fn mul_add(mut self, a: Self, b: Self) -> Self {
602 self.0
603 .iter_mut()
604 .zip(a.0.iter().zip(b.0.iter()))
605 .for_each(|(t, (&a, &b))| *t = t.mul_add(a, b));
606 self
607 }
608}
609
610impl Add for f32x8 {
611 type Output = Self;
612
613 fn add(mut self, rhs: Self) -> Self::Output {
614 self.0.iter_mut().zip(rhs.0.iter()).for_each(|(t, &o)| *t += o);
615 self
616 }
617}
618
619impl AddAssign for f32x8 {
620 fn add_assign(&mut self, rhs: Self) {
621 *self = *self + rhs;
622 }
623}
624
625impl Sub for f32x8 {
626 type Output = Self;
627
628 fn sub(mut self, rhs: Self) -> Self::Output {
629 self.0.iter_mut().zip(rhs.0.iter()).for_each(|(t, &o)| *t -= o);
630 self
631 }
632}
633
634impl Mul for f32x8 {
635 type Output = Self;
636
637 fn mul(mut self, rhs: Self) -> Self::Output {
638 self.0.iter_mut().zip(rhs.0.iter()).for_each(|(t, &o)| *t *= o);
639 self
640 }
641}
642
643impl MulAssign for f32x8 {
644 fn mul_assign(&mut self, rhs: Self) {
645 *self = *self * rhs;
646 }
647}
648
649impl Div for f32x8 {
650 type Output = Self;
651
652 fn div(mut self, rhs: Self) -> Self::Output {
653 self.0.iter_mut().zip(rhs.0.iter()).for_each(|(t, &o)| *t /= o);
654 self
655 }
656}
657
658impl Neg for f32x8 {
659 type Output = Self;
660
661 fn neg(mut self) -> Self::Output {
662 self.0.iter_mut().for_each(|t| *t = -*t);
663 self
664 }
665}
666
667impl BitOr for f32x8 {
668 type Output = Self;
669
670 fn bitor(mut self, rhs: Self) -> Self::Output {
671 self.0.iter_mut().zip(rhs.0.iter()).for_each(|(t, &o)| {
672 let t_bytes = t.to_ne_bytes();
673 let o_bytes = o.to_ne_bytes();
674
675 *t = f32::from_ne_bytes([
676 t_bytes[0] | o_bytes[0],
677 t_bytes[1] | o_bytes[1],
678 t_bytes[2] | o_bytes[2],
679 t_bytes[3] | o_bytes[3],
680 ]);
681 });
682 self
683 }
684}
685
686impl BitOrAssign for f32x8 {
687 fn bitor_assign(&mut self, rhs: Self) {
688 *self = *self | rhs;
689 }
690}
691
692impl From<i32x8> for f32x8 {
693 fn from(val: i32x8) -> Self {
694 Self([
695 val.0[0] as f32,
696 val.0[1] as f32,
697 val.0[2] as f32,
698 val.0[3] as f32,
699 val.0[4] as f32,
700 val.0[5] as f32,
701 val.0[6] as f32,
702 val.0[7] as f32,
703 ])
704 }
705}