1mod simd_opt;
9mod simdint;
10mod simdop;
11mod simdty;
12
13pub use self::simdty::{u32x4, u64x4};
14
15pub trait Vector4<T>: Copy {
16 fn gather(src: &[T], i0: usize, i1: usize, i2: usize, i3: usize) -> Self;
17
18 #[allow(clippy::wrong_self_convention)]
19 fn from_le(self) -> Self;
20 fn to_le(self) -> Self;
21
22 fn wrapping_add(self, rhs: Self) -> Self;
23
24 fn rotate_right_const(self, n: u32) -> Self;
25
26 fn shuffle_left_1(self) -> Self;
27 fn shuffle_left_2(self) -> Self;
28 fn shuffle_left_3(self) -> Self;
29
30 #[inline(always)]
31 fn shuffle_right_1(self) -> Self {
32 self.shuffle_left_3()
33 }
34 #[inline(always)]
35 fn shuffle_right_2(self) -> Self {
36 self.shuffle_left_2()
37 }
38 #[inline(always)]
39 fn shuffle_right_3(self) -> Self {
40 self.shuffle_left_1()
41 }
42}
43
44macro_rules! impl_vector4 {
45 ($vec:ident, $word:ident) => {
46 impl Vector4<$word> for $vec {
47 #[inline(always)]
48 fn gather(src: &[$word], i0: usize, i1: usize, i2: usize, i3: usize) -> Self {
49 $vec::new(src[i0], src[i1], src[i2], src[i3])
50 }
51
52 #[cfg(target_endian = "little")]
53 #[inline(always)]
54 fn from_le(self) -> Self {
55 self
56 }
57
58 #[cfg(not(target_endian = "little"))]
59 #[inline(always)]
60 fn from_le(self) -> Self {
61 $vec::new(
62 $word::from_le(self.0),
63 $word::from_le(self.1),
64 $word::from_le(self.2),
65 $word::from_le(self.3),
66 )
67 }
68
69 #[cfg(target_endian = "little")]
70 #[inline(always)]
71 fn to_le(self) -> Self {
72 self
73 }
74
75 #[cfg(not(target_endian = "little"))]
76 #[inline(always)]
77 fn to_le(self) -> Self {
78 $vec::new(
79 self.0.to_le(),
80 self.1.to_le(),
81 self.2.to_le(),
82 self.3.to_le(),
83 )
84 }
85
86 #[inline(always)]
87 fn wrapping_add(self, rhs: Self) -> Self {
88 self + rhs
89 }
90
91 #[inline(always)]
92 fn rotate_right_const(self, n: u32) -> Self {
93 simd_opt::$vec::rotate_right_const(self, n)
94 }
95
96 #[cfg(feature = "simd")]
97 #[inline(always)]
98 fn shuffle_left_1(self) -> Self {
99 use crate::simd::simdint::simd_shuffle4;
100 const IDX: [u32; 4] = [1, 2, 3, 0];
101 unsafe { simd_shuffle4(self, self, IDX) }
102 }
103
104 #[cfg(not(feature = "simd"))]
105 #[inline(always)]
106 fn shuffle_left_1(self) -> Self {
107 $vec::new(self.1, self.2, self.3, self.0)
108 }
109
110 #[cfg(feature = "simd")]
111 #[inline(always)]
112 fn shuffle_left_2(self) -> Self {
113 use crate::simd::simdint::simd_shuffle4;
114 const IDX: [u32; 4] = [2, 3, 0, 1];
115 unsafe { simd_shuffle4(self, self, IDX) }
116 }
117
118 #[cfg(not(feature = "simd"))]
119 #[inline(always)]
120 fn shuffle_left_2(self) -> Self {
121 $vec::new(self.2, self.3, self.0, self.1)
122 }
123
124 #[cfg(feature = "simd")]
125 #[inline(always)]
126 fn shuffle_left_3(self) -> Self {
127 use crate::simd::simdint::simd_shuffle4;
128 const IDX: [u32; 4] = [3, 0, 1, 2];
129 unsafe { simd_shuffle4(self, self, IDX) }
130 }
131
132 #[cfg(not(feature = "simd"))]
133 #[inline(always)]
134 fn shuffle_left_3(self) -> Self {
135 $vec::new(self.3, self.0, self.1, self.2)
136 }
137 }
138 };
139}
140
141impl_vector4!(u32x4, u32);
142impl_vector4!(u64x4, u64);