Skip to main content

hermes_simd_core/view/
vector_ops.rs

1//! Operator overloads for SIMD vectors.
2
3//! Operator overload implementations for the `Vector` register wrapper.
4
5use super::vector_reg::{assert_runtime_supported, Vector};
6use crate::arch::SimdArch;
7use crate::kernel::SimdKernel;
8use crate::scalar::Scalar;
9
10// -----------------------------------------------------------------------------
11// Operator Overloads
12// -----------------------------------------------------------------------------
13
14impl<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);