1use super::vector_reg::{assert_runtime_supported, Vector};
6use crate::arch::SimdArch;
7use crate::kernel::SimdKernel;
8use crate::scalar::Scalar;
9
10impl<T, Arch> core::ops::Add for Vector<T, Arch>
15where
16 Arch: SimdArch + SimdKernel<T>,
17 T: Scalar,
18{
19 type Output = Self;
20 #[inline(always)]
21 fn add(self, rhs: Self) -> Self {
22 assert_runtime_supported::<T, Arch>();
23 Self::new(unsafe { Arch::add(self.raw, rhs.raw) })
24 }
25}
26
27impl<T, Arch> core::ops::AddAssign for Vector<T, Arch>
28where
29 Arch: SimdArch + SimdKernel<T>,
30 T: Scalar,
31{
32 #[inline(always)]
33 fn add_assign(&mut self, rhs: Self) {
34 assert_runtime_supported::<T, Arch>();
35 self.raw = unsafe { Arch::add(self.raw, rhs.raw) };
36 }
37}
38
39impl<T, Arch> core::ops::Sub for Vector<T, Arch>
40where
41 Arch: SimdArch + SimdKernel<T>,
42 T: Scalar,
43{
44 type Output = Self;
45 #[inline(always)]
46 fn sub(self, rhs: Self) -> Self {
47 assert_runtime_supported::<T, Arch>();
48 Self::new(unsafe { Arch::sub(self.raw, rhs.raw) })
49 }
50}
51
52impl<T, Arch> core::ops::SubAssign for Vector<T, Arch>
53where
54 Arch: SimdArch + SimdKernel<T>,
55 T: Scalar,
56{
57 #[inline(always)]
58 fn sub_assign(&mut self, rhs: Self) {
59 assert_runtime_supported::<T, Arch>();
60 self.raw = unsafe { Arch::sub(self.raw, rhs.raw) };
61 }
62}
63
64impl<T, Arch> core::ops::Mul for Vector<T, Arch>
65where
66 Arch: SimdArch + SimdKernel<T>,
67 T: Scalar,
68{
69 type Output = Self;
70 #[inline(always)]
71 fn mul(self, rhs: Self) -> Self {
72 assert_runtime_supported::<T, Arch>();
73 Self::new(unsafe { Arch::mul(self.raw, rhs.raw) })
74 }
75}
76
77impl<T, Arch> core::ops::MulAssign for Vector<T, Arch>
78where
79 Arch: SimdArch + SimdKernel<T>,
80 T: Scalar,
81{
82 #[inline(always)]
83 fn mul_assign(&mut self, rhs: Self) {
84 assert_runtime_supported::<T, Arch>();
85 self.raw = unsafe { Arch::mul(self.raw, rhs.raw) };
86 }
87}
88
89impl<T, Arch> core::ops::Div for Vector<T, Arch>
90where
91 Arch: SimdArch + SimdKernel<T>,
92 T: Scalar,
93{
94 type Output = Self;
95 #[inline(always)]
96 fn div(self, rhs: Self) -> Self {
97 assert_runtime_supported::<T, Arch>();
98 Self::new(unsafe { Arch::div(self.raw, rhs.raw) })
99 }
100}
101
102impl<T, Arch> core::ops::DivAssign for Vector<T, Arch>
103where
104 Arch: SimdArch + SimdKernel<T>,
105 T: Scalar,
106{
107 #[inline(always)]
108 fn div_assign(&mut self, rhs: Self) {
109 assert_runtime_supported::<T, Arch>();
110 self.raw = unsafe { Arch::div(self.raw, rhs.raw) };
111 }
112}
113
114impl<T, Arch> core::ops::BitAnd for Vector<T, Arch>
115where
116 Arch: SimdArch + SimdKernel<T>,
117 T: Scalar,
118{
119 type Output = Self;
120 #[inline(always)]
121 fn bitand(self, rhs: Self) -> Self {
122 assert_runtime_supported::<T, Arch>();
123 Self::new(unsafe { Arch::bitand(self.raw, rhs.raw) })
124 }
125}
126
127impl<T, Arch> core::ops::BitAndAssign for Vector<T, Arch>
128where
129 Arch: SimdArch + SimdKernel<T>,
130 T: Scalar,
131{
132 #[inline(always)]
133 fn bitand_assign(&mut self, rhs: Self) {
134 assert_runtime_supported::<T, Arch>();
135 self.raw = unsafe { Arch::bitand(self.raw, rhs.raw) };
136 }
137}
138
139impl<T, Arch> core::ops::BitOr for Vector<T, Arch>
140where
141 Arch: SimdArch + SimdKernel<T>,
142 T: Scalar,
143{
144 type Output = Self;
145 #[inline(always)]
146 fn bitor(self, rhs: Self) -> Self {
147 assert_runtime_supported::<T, Arch>();
148 Self::new(unsafe { Arch::bitor(self.raw, rhs.raw) })
149 }
150}
151
152impl<T, Arch> core::ops::BitOrAssign for Vector<T, Arch>
153where
154 Arch: SimdArch + SimdKernel<T>,
155 T: Scalar,
156{
157 #[inline(always)]
158 fn bitor_assign(&mut self, rhs: Self) {
159 assert_runtime_supported::<T, Arch>();
160 self.raw = unsafe { Arch::bitor(self.raw, rhs.raw) };
161 }
162}
163
164impl<T, Arch> core::ops::BitXor for Vector<T, Arch>
165where
166 Arch: SimdArch + SimdKernel<T>,
167 T: Scalar,
168{
169 type Output = Self;
170 #[inline(always)]
171 fn bitxor(self, rhs: Self) -> Self {
172 assert_runtime_supported::<T, Arch>();
173 Self::new(unsafe { Arch::bitxor(self.raw, rhs.raw) })
174 }
175}
176
177impl<T, Arch> core::ops::BitXorAssign for Vector<T, Arch>
178where
179 Arch: SimdArch + SimdKernel<T>,
180 T: Scalar,
181{
182 #[inline(always)]
183 fn bitxor_assign(&mut self, rhs: Self) {
184 assert_runtime_supported::<T, Arch>();
185 self.raw = unsafe { Arch::bitxor(self.raw, rhs.raw) };
186 }
187}
188
189impl<T, Arch> core::ops::Neg for Vector<T, Arch>
190where
191 Arch: SimdArch + SimdKernel<T>,
192 T: Scalar,
193{
194 type Output = Self;
195 #[inline(always)]
196 fn neg(self) -> Self {
197 assert_runtime_supported::<T, Arch>();
198 Self::new(unsafe { Arch::neg(self.raw) })
199 }
200}
201
202impl<T, Arch> core::ops::Neg for &Vector<T, Arch>
203where
204 Arch: SimdArch + SimdKernel<T>,
205 T: Scalar,
206{
207 type Output = Vector<T, Arch>;
208 #[inline(always)]
209 fn neg(self) -> Self::Output {
210 assert_runtime_supported::<T, Arch>();
211 Vector::new(unsafe { Arch::neg(self.raw) })
212 }
213}
214
215impl<T, Arch> core::ops::Not for Vector<T, Arch>
216where
217 Arch: SimdArch + SimdKernel<T>,
218 T: Scalar,
219{
220 type Output = Self;
221 #[inline(always)]
222 fn not(self) -> Self {
223 assert_runtime_supported::<T, Arch>();
224 Self::new(unsafe { Arch::bitnot(self.raw) })
225 }
226}
227
228impl<T, Arch> core::ops::Not for &Vector<T, Arch>
229where
230 Arch: SimdArch + SimdKernel<T>,
231 T: Scalar,
232{
233 type Output = Vector<T, Arch>;
234 #[inline(always)]
235 fn not(self) -> Self::Output {
236 assert_runtime_supported::<T, Arch>();
237 Vector::new(unsafe { Arch::bitnot(self.raw) })
238 }
239}
240
241macro_rules! impl_ref_binary_op {
242 ($op_trait:ident, $op_method:ident, $kernel_method:ident) => {
243 impl<'a, T, Arch> core::ops::$op_trait<Vector<T, Arch>> for &'a Vector<T, Arch>
244 where
245 Arch: SimdArch + SimdKernel<T>,
246 T: Scalar,
247 {
248 type Output = Vector<T, Arch>;
249 #[inline(always)]
250 fn $op_method(self, rhs: Vector<T, Arch>) -> Self::Output {
251 assert_runtime_supported::<T, Arch>();
252 Vector::new(unsafe { Arch::$kernel_method(self.raw, rhs.raw) })
253 }
254 }
255 impl<'a, T, Arch> core::ops::$op_trait<&'a Vector<T, Arch>> for Vector<T, Arch>
256 where
257 Arch: SimdArch + SimdKernel<T>,
258 T: Scalar,
259 {
260 type Output = Vector<T, Arch>;
261 #[inline(always)]
262 fn $op_method(self, rhs: &'a Vector<T, Arch>) -> Self::Output {
263 assert_runtime_supported::<T, Arch>();
264 Vector::new(unsafe { Arch::$kernel_method(self.raw, rhs.raw) })
265 }
266 }
267 impl<'a, 'b, T, Arch> core::ops::$op_trait<&'b Vector<T, Arch>> for &'a Vector<T, Arch>
268 where
269 Arch: SimdArch + SimdKernel<T>,
270 T: Scalar,
271 {
272 type Output = Vector<T, Arch>;
273 #[inline(always)]
274 fn $op_method(self, rhs: &'b Vector<T, Arch>) -> Self::Output {
275 assert_runtime_supported::<T, Arch>();
276 Vector::new(unsafe { Arch::$kernel_method(self.raw, rhs.raw) })
277 }
278 }
279 };
280}
281
282impl_ref_binary_op!(Add, add, add);
283impl_ref_binary_op!(Sub, sub, sub);
284impl_ref_binary_op!(Mul, mul, mul);
285impl_ref_binary_op!(Div, div, div);
286impl_ref_binary_op!(BitAnd, bitand, bitand);
287impl_ref_binary_op!(BitOr, bitor, bitor);
288impl_ref_binary_op!(BitXor, bitxor, bitxor);