1use core::fmt;
2use core::ops;
3
4#[cfg(target_pointer_width = "32")]
5use core::arch::x86::*;
6
7#[cfg(target_pointer_width = "64")]
8use core::arch::x86_64::*;
9
10use crate::{
11 Vector,
12 Integer2, Integer3, Integer4,
13 UInteger2, UInteger3, UInteger4,
14};
15
16
17
18#[repr(C)]
23#[derive(Clone, Copy)]
24pub union VectorInt {
25 arr: [i32; 4],
27
28 pub(crate) inner: __m128i
29}
30
31impl VectorInt {
32 pub const ZERO: Self = Self { arr: [0; 4] };
34
35 pub const ONE: Self = Self { arr: [1; 4] };
37
38 pub const NEG_ONE: Self = Self { arr: [-1; 4] };
40
41 pub const X: Self = Self { arr: [1, 0, 0, 0] };
43
44 pub const Y: Self = Self { arr: [0, 1, 0, 0] };
46
47 pub const Z: Self = Self { arr: [0, 0, 1, 0] };
49
50 pub const W: Self = Self { arr: [0, 0, 0, 1] };
52
53 pub const NEG_X: Self = Self { arr: [-1, 0, 0, 0] };
55
56 pub const NEG_Y: Self = Self { arr: [0, -1, 0, 0] };
58
59 pub const NEG_Z: Self = Self { arr: [0, 0, -1, 0] };
61
62 pub const NEG_W: Self = Self { arr: [0, 0, 0, -1] };
64}
65
66impl VectorInt {
67 #[inline]
69 #[must_use]
70 pub fn new(x: i32, y: i32, z: i32, w: i32) -> Self {
71 unsafe {
72 let arr = [x, y, z, w];
73 Self { inner: _mm_loadu_si128(arr.as_ptr() as *const __m128i) }
74 }
75 }
76
77 #[inline]
79 #[must_use]
80 pub fn fill(v: i32) -> Self {
81 unsafe { Self { inner: _mm_set1_epi32(v) } }
82 }
83
84 #[inline]
86 #[must_use]
87 pub fn from_array(arr: [i32; 4]) -> Self {
88 unsafe { Self { inner: _mm_loadu_si128(arr.as_ptr() as *const __m128i) } }
89 }
90
91 #[inline]
93 #[must_use]
94 pub fn into_array(self) -> [i32; 4] {
95 let mut arr = [0; 4];
96 unsafe { _mm_storeu_si128(arr.as_mut_ptr() as *mut __m128i, self.inner) };
97 return arr;
98 }
99
100 #[inline]
107 #[must_use]
108 pub fn from_slice(slice: &[i32]) -> Self {
109 #[cfg(feature = "use-assertion")]
110 assert!(slice.len() >= 4, "The given array slice has less than four elements!");
111 unsafe { Self { inner: _mm_loadu_si128(slice.as_ptr() as *const __m128i) } }
112 }
113
114 #[inline]
116 #[must_use]
117 pub fn load_int2(val: Integer2) -> Self {
118 Self::load_int4(val.into())
119 }
120
121 #[inline]
123 #[must_use]
124 pub fn store_int2(self) -> Integer2 {
125 self.store_int4().xy()
126 }
127
128 #[inline]
130 #[must_use]
131 pub fn load_int3(val: Integer3) -> Self {
132 Self::load_int4(val.into())
133 }
134
135 #[inline]
137 #[must_use]
138 pub fn store_int3(self) -> Integer3 {
139 self.store_int4().xyz()
140 }
141
142 #[inline]
144 #[must_use]
145 pub fn load_int4(val: Integer4) -> Self {
146 unsafe {
147 Self { inner: _mm_loadu_si128(&val as *const _ as *const __m128i) }
148 }
149 }
150
151 #[inline]
153 #[must_use]
154 pub fn store_int4(self) -> Integer4 {
155 unsafe {
156 let mut val = Integer4::default();
157 _mm_storeu_si128(&mut val as *mut _ as *mut __m128i, self.inner);
158 val
159 }
160 }
161
162 #[inline]
164 #[must_use]
165 pub fn load_uint2(val: UInteger2) -> Self {
166 Self::load_uint4(val.into())
167 }
168
169 #[inline]
171 #[must_use]
172 pub fn store_uint2(self) -> UInteger2 {
173 self.store_uint4().xy()
174 }
175
176 #[inline]
178 #[must_use]
179 pub fn load_uint3(val: UInteger3) -> Self {
180 Self::load_uint4(val.into())
181 }
182
183 #[inline]
185 #[must_use]
186 pub fn store_uint3(self) -> UInteger3 {
187 self.store_uint4().xyz()
188 }
189
190 #[inline]
192 #[must_use]
193 pub fn load_uint4(val: UInteger4) -> Self {
194 unsafe {
195 Self { inner: _mm_loadu_si128(&val as *const _ as *const __m128i) }
196 }
197 }
198
199 #[inline]
201 #[must_use]
202 pub fn store_uint4(self) -> UInteger4 {
203 unsafe {
204 let mut val = UInteger4::default();
205 _mm_storeu_si128(&mut val as *mut _ as *mut __m128i, self.inner);
206 val
207 }
208 }
209}
210
211impl VectorInt {
212 #[inline]
214 #[must_use]
215 pub fn get_x(&self) -> i32 {
216 unsafe { _mm_cvtsi128_si32(self.inner) }
217 }
218
219 #[inline]
221 pub fn set_x(&mut self, v: i32) {
222 unsafe {
224 match is_x86_feature_detected!("sse4.1") {
225 true => self.inner = _mm_insert_epi32::<0b00>(self.inner, v),
226 false => {
227 let mut arr = self.into_array();
228 arr[0] = v;
229 *self = Self::from_array(arr)
230 }
231 }
232 }
233 }
234
235 #[inline]
237 #[must_use]
238 pub fn get_y(&self) -> i32 {
239 unsafe {
240 match is_x86_feature_detected!("sse4.1") {
241 true => _mm_extract_epi32::<0b01>(self.inner),
242 false => _mm_cvtsi128_si32(_mm_shuffle_epi32::<0b_01_01_01_01>(self.inner))
243 }
244 }
245 }
246
247 #[inline]
249 pub fn set_y(&mut self, v: i32) {
250 unsafe {
252 match is_x86_feature_detected!("sse4.1") {
253 true => self.inner = _mm_insert_epi32::<0b01>(self.inner, v),
254 false => {
255 let mut arr = self.into_array();
256 arr[1] = v;
257 *self = Self::from_array(arr)
258 }
259 }
260 }
261 }
262
263 #[inline]
265 #[must_use]
266 pub fn get_z(&self) -> i32 {
267 unsafe {
268 match is_x86_feature_detected!("sse4.1") {
269 true => _mm_extract_epi32::<0b10>(self.inner),
270 false => _mm_cvtsi128_si32(_mm_shuffle_epi32::<0b_10_10_10_10>(self.inner))
271 }
272 }
273 }
274
275 #[inline]
277 pub fn set_z(&mut self, v: i32) {
278 unsafe {
280 match is_x86_feature_detected!("sse4.1") {
281 true => self.inner = _mm_insert_epi32::<0b10>(self.inner, v),
282 false => {
283 let mut arr = self.into_array();
284 arr[2] = v;
285 *self = Self::from_array(arr)
286 }
287 }
288 }
289 }
290
291 #[inline]
293 #[must_use]
294 pub fn get_w(&self) -> i32 {
295 unsafe {
296 match is_x86_feature_detected!("sse4.1") {
297 true => _mm_extract_epi32::<0b11>(self.inner),
298 false => _mm_cvtsi128_si32(_mm_shuffle_epi32::<0b_11_11_11_11>(self.inner))
299 }
300 }
301 }
302
303 #[inline]
305 pub fn set_w(&mut self, v: i32) {
306 unsafe {
308 match is_x86_feature_detected!("sse4.1") {
309 true => self.inner = _mm_insert_epi32::<0b11>(self.inner, v),
310 false => {
311 let mut arr = self.into_array();
312 arr[3] = v;
313 *self = Self::from_array(arr)
314 }
315 }
316 }
317 }
318
319 #[inline]
321 pub fn min(self, rhs: Self) -> Self {
322 unsafe { VectorInt { inner: _mm_min_epi32(self.inner, rhs.inner) } }
323 }
324
325 #[inline]
327 pub fn max(self, rhs: Self) -> Self {
328 unsafe { VectorInt { inner: _mm_max_epi32(self.inner, rhs.inner) } }
329 }
330
331 #[inline]
333 pub fn lt(self, rhs: Self) -> VectorInt {
334 unsafe { VectorInt { inner: _mm_cmplt_epi32(self.inner, rhs.inner) } }
335 }
336
337 #[inline]
339 pub fn le(self, rhs: Self) -> VectorInt {
340 self.lt(rhs) | self.eq(rhs)
341 }
342
343 #[inline]
345 pub fn gt(self, rhs: Self) -> VectorInt {
346 unsafe { VectorInt { inner: _mm_cmpgt_epi32(self.inner, rhs.inner) } }
347 }
348
349 #[inline]
351 pub fn ge(self, rhs: Self) -> VectorInt {
352 self.gt(rhs) | self.eq(rhs)
353 }
354
355 #[inline]
360 pub fn eq(self, rhs: Self) -> VectorInt {
361 unsafe { VectorInt { inner: _mm_cmpeq_epi32(self.inner, rhs.inner) } }
362 }
363
364 #[inline]
369 pub fn ne(self, rhs: Self) -> VectorInt {
370 !self.eq(rhs)
371 }
372
373 #[inline]
375 #[must_use]
376 pub fn abs(self) -> Self {
377 self.max(-self)
378 }
379
380 #[inline]
382 #[must_use]
383 pub fn sum(self) -> Self {
384 unsafe {
385 let sum = match is_x86_feature_detected!("sse3") {
386 true => {
387 let temp = _mm_hadd_epi32(self.inner, self.inner);
388 _mm_hadd_epi32(temp, temp)
389 },
390 false => {
391 let low = _mm_shuffle_epi32::<0b_01_00_01_00>(self.inner);
392 let high = _mm_shuffle_epi32::<0b_11_10_11_10>(self.inner);
393 let low = _mm_add_epi32(low, high);
394 let high = _mm_shuffle_epi32::<0b_10_11_00_01>(low);
395 _mm_add_epi32(low, high)
396 }
397 };
398 return VectorInt { inner: sum }
399 }
400 }
401
402 #[inline]
404 #[must_use]
405 pub fn sum_into(self) -> i32 {
406 self.sum().get_x()
407 }
408
409 #[inline]
411 #[must_use]
412 pub fn vec2_dot(self, rhs: Self) -> Self {
413 const MASK_XY: VectorInt = VectorInt { arr: [1, 1, 0, 0] };
414 (self * rhs * MASK_XY).sum()
415 }
416
417 #[inline]
419 #[must_use]
420 pub fn vec2_dot_into(self, rhs: Self) -> i32 {
421 self.vec2_dot(rhs).get_x()
422 }
423
424 #[inline]
426 #[must_use]
427 pub fn vec3_dot(self, rhs: Self) -> Self {
428 const MASK_XYZ: VectorInt = VectorInt { arr: [1, 1, 1, 0] };
429 (self * rhs * MASK_XYZ).sum()
430 }
431
432 #[inline]
434 #[must_use]
435 pub fn vec3_dot_into(self, rhs: Self) -> i32 {
436 self.vec3_dot(rhs).get_x()
437 }
438
439 #[inline]
441 #[must_use]
442 pub fn vec4_dot(self, rhs: Self) -> Self {
443 (self * rhs).sum()
444 }
445
446 #[inline]
448 #[must_use]
449 pub fn vec4_dot_into(self, rhs: Self) -> i32 {
450 self.vec4_dot(rhs).get_x()
451 }
452}
453
454impl Default for VectorInt {
455 #[inline]
456 fn default() -> Self {
457 Self::ZERO
458 }
459}
460
461impl From<Vector> for VectorInt {
462 #[inline]
463 fn from(value: Vector) -> Self {
464 unsafe { VectorInt { inner: _mm_castps_si128(value.inner) } }
465 }
466}
467
468impl From<[i32; 4]> for VectorInt {
469 #[inline]
470 fn from(value: [i32; 4]) -> Self {
471 Self::from_array(value)
472 }
473}
474
475impl Into<[i32; 4]> for VectorInt {
476 #[inline]
477 fn into(self) -> [i32; 4] {
478 self.into_array()
479 }
480}
481
482impl From<Integer2> for VectorInt {
483 #[inline]
484 fn from(value: Integer2) -> Self {
485 Self::load_int2(value)
486 }
487}
488
489impl Into<Integer2> for VectorInt {
490 #[inline]
491 fn into(self) -> Integer2 {
492 self.store_int2()
493 }
494}
495
496impl From<Integer3> for VectorInt {
497 #[inline]
498 fn from(value: Integer3) -> Self {
499 Self::load_int3(value)
500 }
501}
502
503impl Into<Integer3> for VectorInt {
504 #[inline]
505 fn into(self) -> Integer3 {
506 self.store_int3()
507 }
508}
509
510impl From<Integer4> for VectorInt {
511 #[inline]
512 fn from(value: Integer4) -> Self {
513 Self::load_int4(value)
514 }
515}
516
517impl Into<Integer4> for VectorInt {
518 #[inline]
519 fn into(self) -> Integer4 {
520 self.store_int4()
521 }
522}
523
524impl From<UInteger2> for VectorInt {
525 #[inline]
526 fn from(value: UInteger2) -> Self {
527 Self::load_uint2(value)
528 }
529}
530
531impl Into<UInteger2> for VectorInt {
532 #[inline]
533 fn into(self) -> UInteger2 {
534 self.store_uint2()
535 }
536}
537
538impl From<UInteger3> for VectorInt {
539 #[inline]
540 fn from(value: UInteger3) -> Self {
541 Self::load_uint3(value)
542 }
543}
544
545impl Into<UInteger3> for VectorInt {
546 #[inline]
547 fn into(self) -> UInteger3 {
548 self.store_uint3()
549 }
550}
551
552impl From<UInteger4> for VectorInt {
553 #[inline]
554 fn from(value: UInteger4) -> Self {
555 Self::load_uint4(value)
556 }
557}
558
559impl Into<UInteger4> for VectorInt {
560 #[inline]
561 fn into(self) -> UInteger4 {
562 self.store_uint4()
563 }
564}
565
566impl fmt::Debug for VectorInt {
567 #[inline]
568 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
569 f.debug_tuple(stringify!(VectorInt))
570 .field(unsafe { &self.inner })
571 .finish()
572 }
573}
574
575impl ops::Add<VectorInt> for i32 {
576 type Output = VectorInt;
577 #[inline]
579 fn add(self, rhs: VectorInt) -> Self::Output {
580 VectorInt::fill(self) + rhs
581 }
582}
583
584impl ops::Add<i32> for VectorInt {
585 type Output = VectorInt;
586 #[inline]
588 fn add(self, rhs: i32) -> Self::Output {
589 self + VectorInt::fill(rhs)
590 }
591}
592
593impl ops::AddAssign<i32> for VectorInt {
594 #[inline]
596 fn add_assign(&mut self, rhs: i32) {
597 *self = *self + rhs
598 }
599}
600
601impl ops::Add<VectorInt> for VectorInt {
602 type Output = VectorInt;
603 #[inline]
605 fn add(self, rhs: VectorInt) -> Self::Output {
606 unsafe { VectorInt { inner: _mm_add_epi32(self.inner, rhs.inner) } }
607 }
608}
609
610impl ops::AddAssign<VectorInt> for VectorInt {
611 #[inline]
613 fn add_assign(&mut self, rhs: VectorInt) {
614 *self = *self + rhs
615 }
616}
617
618impl ops::Sub<VectorInt> for i32 {
619 type Output = VectorInt;
620 #[inline]
621 fn sub(self, rhs: VectorInt) -> Self::Output {
622 VectorInt::fill(self) - rhs
623 }
624}
625
626impl ops::Sub<i32> for VectorInt {
627 type Output = VectorInt;
628 #[inline]
630 fn sub(self, rhs: i32) -> Self::Output {
631 self - VectorInt::fill(rhs)
632 }
633}
634
635impl ops::SubAssign<i32> for VectorInt {
636 #[inline]
638 fn sub_assign(&mut self, rhs: i32) {
639 *self = *self - rhs
640 }
641}
642
643impl ops::Sub<VectorInt> for VectorInt {
644 type Output = VectorInt;
645 #[inline]
647 fn sub(self, rhs: VectorInt) -> Self::Output {
648 unsafe { VectorInt { inner: _mm_sub_epi32(self.inner, rhs.inner) } }
649 }
650}
651
652impl ops::SubAssign<VectorInt> for VectorInt {
653 #[inline]
655 fn sub_assign(&mut self, rhs: VectorInt) {
656 *self = *self - rhs
657 }
658}
659
660impl ops::Neg for VectorInt {
661 type Output = VectorInt;
662 #[inline]
664 fn neg(self) -> Self::Output {
665 unsafe { VectorInt { inner: _mm_sub_epi32(_mm_setzero_si128(), self.inner) } }
666 }
667}
668
669impl ops::Mul<VectorInt> for i32 {
670 type Output = VectorInt;
671 #[inline]
673 fn mul(self, rhs: VectorInt) -> Self::Output {
674 VectorInt::fill(self) * rhs
675 }
676}
677
678impl ops::Mul<i32> for VectorInt {
679 type Output = VectorInt;
680 #[inline]
682 fn mul(self, rhs: i32) -> Self::Output {
683 self * VectorInt::fill(rhs)
684 }
685}
686
687impl ops::MulAssign<i32> for VectorInt {
688 #[inline]
690 fn mul_assign(&mut self, rhs: i32) {
691 *self = *self * rhs
692 }
693}
694
695impl ops::Mul<VectorInt> for VectorInt {
696 type Output = VectorInt;
697 #[inline]
699 fn mul(self, rhs: VectorInt) -> Self::Output {
700 unsafe { VectorInt { inner: _mm_mul_epi32(self.inner, rhs.inner) } }
701 }
702}
703
704impl ops::MulAssign<VectorInt> for VectorInt {
705 #[inline]
707 fn mul_assign(&mut self, rhs: VectorInt) {
708 *self = *self * rhs
709 }
710}
711
712impl ops::Div<VectorInt> for i32 {
713 type Output = VectorInt;
714 #[inline]
716 fn div(self, rhs: VectorInt) -> Self::Output {
717 VectorInt::fill(self) / rhs
718 }
719}
720
721impl ops::Div<i32> for VectorInt {
722 type Output = VectorInt;
723 #[inline]
725 fn div(self, rhs: i32) -> Self::Output {
726 self / VectorInt::fill(rhs)
727 }
728}
729
730impl ops::DivAssign<i32> for VectorInt {
731 #[inline]
733 fn div_assign(&mut self, rhs: i32) {
734 *self = *self / rhs
735 }
736}
737
738impl ops::Div<VectorInt> for VectorInt {
739 type Output = VectorInt;
740 #[inline]
742 fn div(self, rhs: VectorInt) -> Self::Output {
743 unsafe {
744 let a = _mm_castsi128_ps(self.inner);
745 let b = _mm_castsi128_ps(rhs.inner);
746 let result = _mm_div_ps(a, b);
747 return VectorInt { inner: _mm_castps_si128(result) }
748 }
749 }
750}
751
752impl ops::DivAssign<VectorInt> for VectorInt {
753 #[inline]
755 fn div_assign(&mut self, rhs: VectorInt) {
756 *self = *self / rhs
757 }
758}
759
760impl ops::BitAnd<VectorInt> for VectorInt {
761 type Output = VectorInt;
762 #[inline]
764 fn bitand(self, rhs: VectorInt) -> Self::Output {
765 unsafe { VectorInt { inner: _mm_and_si128(self.inner, rhs.inner) } }
766 }
767}
768
769impl ops::BitAndAssign<VectorInt> for VectorInt {
770 #[inline]
772 fn bitand_assign(&mut self, rhs: VectorInt) {
773 *self = *self & rhs
774 }
775}
776
777impl ops::BitOr<VectorInt> for VectorInt {
778 type Output = VectorInt;
779 #[inline]
781 fn bitor(self, rhs: VectorInt) -> Self::Output {
782 unsafe { VectorInt { inner: _mm_or_si128(self.inner, rhs.inner) } }
783 }
784}
785
786impl ops::BitOrAssign<VectorInt> for VectorInt {
787 #[inline]
789 fn bitor_assign(&mut self, rhs: VectorInt) {
790 *self = *self | rhs
791 }
792}
793
794impl ops::BitXor<VectorInt> for VectorInt {
795 type Output = VectorInt;
796 #[inline]
798 fn bitxor(self, rhs: VectorInt) -> Self::Output {
799 unsafe { VectorInt { inner: _mm_xor_si128(self.inner, rhs.inner) } }
800 }
801}
802
803impl ops::BitXorAssign<VectorInt> for VectorInt {
804 #[inline]
806 fn bitxor_assign(&mut self, rhs: VectorInt) {
807 *self = *self ^ rhs
808 }
809}
810
811impl ops::Not for VectorInt {
812 type Output = VectorInt;
813 #[inline]
815 fn not(self) -> Self::Output {
816 unsafe { VectorInt { inner: _mm_xor_si128(_mm_set1_epi32(-1) ,self.inner) } }
817 }
818}