Skip to main content

carbon_simd/x86_64/
num.rs

1use crate::*;
2use core::arch::x86_64::*;
3
4unsafe impl SimdNumElement for i8 {
5    #[inline(always)]
6    unsafe fn add(left: Self::Vector, right: Self::Vector) -> Self::Vector {
7        unsafe { _mm256_add_epi8(left, right) }
8    }
9
10    #[inline(always)]
11    unsafe fn sub(left: Self::Vector, right: Self::Vector) -> Self::Vector {
12        unsafe { _mm256_sub_epi8(left, right) }
13    }
14
15    #[inline(always)]
16    unsafe fn mul(left: Self::Vector, right: Self::Vector) -> Self::Vector {
17        let mut left_buff = [0i8; Self::VECTOR_LEN];
18        let mut right_buff = [0i8; Self::VECTOR_LEN];
19
20        unsafe {
21            Self::store(left_buff.as_mut_ptr(), left);
22            Self::store(right_buff.as_mut_ptr(), right);
23
24            for i in 0..Self::VECTOR_LEN {
25                left_buff[i] *= right_buff[i];
26            }
27
28            Self::load(left_buff.as_ptr())
29        }
30    }
31
32    #[inline(always)]
33    unsafe fn div(left: Self::Vector, right: Self::Vector) -> Self::Vector {
34        let mut left_buff = [0i8; Self::VECTOR_LEN];
35        let mut right_buff = [0i8; Self::VECTOR_LEN];
36
37        unsafe {
38            Self::store(left_buff.as_mut_ptr(), left);
39            Self::store(right_buff.as_mut_ptr(), right);
40
41            for i in 0..Self::VECTOR_LEN {
42                if right_buff[i] != 0 {
43                    left_buff[i] /= right_buff[i];
44                }
45            }
46
47            Self::load(left_buff.as_ptr())
48        }
49    }
50}
51
52unsafe impl SimdNumElement for u8 {
53    #[inline(always)]
54    unsafe fn add(left: Self::Vector, right: Self::Vector) -> Self::Vector {
55        unsafe { _mm256_add_epi8(left, right) }
56    }
57
58    #[inline(always)]
59    unsafe fn sub(left: Self::Vector, right: Self::Vector) -> Self::Vector {
60        unsafe { _mm256_sub_epi8(left, right) }
61    }
62
63    #[inline(always)]
64    unsafe fn mul(left: Self::Vector, right: Self::Vector) -> Self::Vector {
65        let mut left_buff = [0u8; Self::VECTOR_LEN];
66        let mut right_buff = [0u8; Self::VECTOR_LEN];
67
68        unsafe {
69            Self::store(left_buff.as_mut_ptr(), left);
70            Self::store(right_buff.as_mut_ptr(), right);
71
72            for i in 0..Self::VECTOR_LEN {
73                left_buff[i] *= right_buff[i];
74            }
75
76            Self::load(left_buff.as_ptr())
77        }
78    }
79
80    #[inline(always)]
81    unsafe fn div(left: Self::Vector, right: Self::Vector) -> Self::Vector {
82        let mut left_buff = [0u8; Self::VECTOR_LEN];
83        let mut right_buff = [0u8; Self::VECTOR_LEN];
84
85        unsafe {
86            Self::store(left_buff.as_mut_ptr(), left);
87            Self::store(right_buff.as_mut_ptr(), right);
88
89            for i in 0..Self::VECTOR_LEN {
90                if right_buff[i] != 0 {
91                    left_buff[i] /= right_buff[i];
92                }
93            }
94
95            Self::load(left_buff.as_ptr())
96        }
97    }
98}
99
100unsafe impl SimdNumElement for i16 {
101    #[inline(always)]
102    unsafe fn add(left: Self::Vector, right: Self::Vector) -> Self::Vector {
103        unsafe { _mm256_add_epi16(left, right) }
104    }
105
106    #[inline(always)]
107    unsafe fn sub(left: Self::Vector, right: Self::Vector) -> Self::Vector {
108        unsafe { _mm256_sub_epi16(left, right) }
109    }
110
111    #[inline(always)]
112    unsafe fn mul(left: Self::Vector, right: Self::Vector) -> Self::Vector {
113        unsafe { _mm256_mullo_epi16(left, right) }
114    }
115
116    #[inline(always)]
117    unsafe fn div(left: Self::Vector, right: Self::Vector) -> Self::Vector {
118        let mut left_buff = [0i16; Self::VECTOR_LEN];
119        let mut right_buff = [0i16; Self::VECTOR_LEN];
120
121        unsafe {
122            Self::store(left_buff.as_mut_ptr(), left);
123            Self::store(right_buff.as_mut_ptr(), right);
124
125            for i in 0..Self::VECTOR_LEN {
126                if right_buff[i] != 0 {
127                    left_buff[i] /= right_buff[i];
128                }
129            }
130
131            Self::load(left_buff.as_ptr())
132        }
133    }
134}
135
136unsafe impl SimdNumElement for u16 {
137    #[inline(always)]
138    unsafe fn add(left: Self::Vector, right: Self::Vector) -> Self::Vector {
139        unsafe { _mm256_add_epi16(left, right) }
140    }
141
142    #[inline(always)]
143    unsafe fn sub(left: Self::Vector, right: Self::Vector) -> Self::Vector {
144        unsafe { _mm256_sub_epi16(left, right) }
145    }
146
147    #[inline(always)]
148    unsafe fn mul(left: Self::Vector, right: Self::Vector) -> Self::Vector {
149        unsafe { _mm256_mullo_epi16(left, right) }
150    }
151
152    #[inline(always)]
153    unsafe fn div(left: Self::Vector, right: Self::Vector) -> Self::Vector {
154        let mut left_buff = [0u16; Self::VECTOR_LEN];
155        let mut right_buff = [0u16; Self::VECTOR_LEN];
156
157        unsafe {
158            Self::store(left_buff.as_mut_ptr(), left);
159            Self::store(right_buff.as_mut_ptr(), right);
160
161            for i in 0..Self::VECTOR_LEN {
162                if right_buff[i] != 0 {
163                    left_buff[i] /= right_buff[i];
164                }
165            }
166
167            Self::load(left_buff.as_ptr())
168        }
169    }
170}
171
172unsafe impl SimdNumElement for i32 {
173    #[inline(always)]
174    unsafe fn add(left: Self::Vector, right: Self::Vector) -> Self::Vector {
175        unsafe { _mm256_add_epi32(left, right) }
176    }
177
178    #[inline(always)]
179    unsafe fn sub(left: Self::Vector, right: Self::Vector) -> Self::Vector {
180        unsafe { _mm256_sub_epi32(left, right) }
181    }
182
183    #[inline(always)]
184    unsafe fn mul(left: Self::Vector, right: Self::Vector) -> Self::Vector {
185        unsafe { _mm256_mullo_epi32(left, right) }
186    }
187
188    #[inline(always)]
189    unsafe fn div(left: Self::Vector, right: Self::Vector) -> Self::Vector {
190        let mut left_buff = [0i32; Self::VECTOR_LEN];
191        let mut right_buff = [0i32; Self::VECTOR_LEN];
192
193        unsafe {
194            Self::store(left_buff.as_mut_ptr(), left);
195            Self::store(right_buff.as_mut_ptr(), right);
196
197            for i in 0..Self::VECTOR_LEN {
198                if right_buff[i] != 0 {
199                    left_buff[i] /= right_buff[i];
200                }
201            }
202
203            Self::load(left_buff.as_ptr())
204        }
205    }
206}
207
208unsafe impl SimdNumElement for u32 {
209    #[inline(always)]
210    unsafe fn add(left: Self::Vector, right: Self::Vector) -> Self::Vector {
211        unsafe { _mm256_add_epi32(left, right) }
212    }
213
214    #[inline(always)]
215    unsafe fn sub(left: Self::Vector, right: Self::Vector) -> Self::Vector {
216        unsafe { _mm256_sub_epi32(left, right) }
217    }
218
219    #[inline(always)]
220    unsafe fn mul(left: Self::Vector, right: Self::Vector) -> Self::Vector {
221        unsafe { _mm256_mullo_epi32(left, right) }
222    }
223
224    #[inline(always)]
225    unsafe fn div(left: Self::Vector, right: Self::Vector) -> Self::Vector {
226        let mut left_buff = [0u32; Self::VECTOR_LEN];
227        let mut right_buff = [0u32; Self::VECTOR_LEN];
228
229        unsafe {
230            Self::store(left_buff.as_mut_ptr(), left);
231            Self::store(right_buff.as_mut_ptr(), right);
232
233            for i in 0..Self::VECTOR_LEN {
234                if right_buff[i] != 0 {
235                    left_buff[i] /= right_buff[i];
236                }
237            }
238
239            Self::load(left_buff.as_ptr())
240        }
241    }
242}
243
244unsafe impl SimdNumElement for i64 {
245    #[inline(always)]
246    unsafe fn add(left: Self::Vector, right: Self::Vector) -> Self::Vector {
247        unsafe { _mm256_add_epi64(left, right) }
248    }
249
250    #[inline(always)]
251    unsafe fn sub(left: Self::Vector, right: Self::Vector) -> Self::Vector {
252        unsafe { _mm256_sub_epi64(left, right) }
253    }
254
255    #[inline(always)]
256    unsafe fn mul(left: Self::Vector, right: Self::Vector) -> Self::Vector {
257        let mut left_buff = [0i64; 4];
258        let mut right_buff = [0i64; 4];
259
260        unsafe {
261            Self::store(left_buff.as_mut_ptr(), left);
262            Self::store(right_buff.as_mut_ptr(), right);
263
264            for i in 0..4 {
265                left_buff[i] *= right_buff[i];
266            }
267
268            Self::load(left_buff.as_ptr())
269        }
270    }
271
272    #[inline(always)]
273    unsafe fn div(left: Self::Vector, right: Self::Vector) -> Self::Vector {
274        let mut left_buff = [0i64; Self::VECTOR_LEN];
275        let mut right_buff = [0i64; Self::VECTOR_LEN];
276
277        unsafe {
278            Self::store(left_buff.as_mut_ptr(), left);
279            Self::store(right_buff.as_mut_ptr(), right);
280
281            for i in 0..Self::VECTOR_LEN {
282                if right_buff[i] != 0 {
283                    left_buff[i] /= right_buff[i];
284                }
285            }
286
287            Self::load(left_buff.as_ptr())
288        }
289    }
290}
291
292unsafe impl SimdNumElement for u64 {
293    #[inline(always)]
294    unsafe fn add(left: Self::Vector, right: Self::Vector) -> Self::Vector {
295        unsafe { _mm256_add_epi64(left, right) }
296    }
297
298    #[inline(always)]
299    unsafe fn sub(left: Self::Vector, right: Self::Vector) -> Self::Vector {
300        unsafe { _mm256_sub_epi64(left, right) }
301    }
302
303    #[inline(always)]
304    unsafe fn mul(left: Self::Vector, right: Self::Vector) -> Self::Vector {
305        let mut left_buff = [0u64; 4];
306        let mut right_buff = [0u64; 4];
307
308        unsafe {
309            Self::store(left_buff.as_mut_ptr(), left);
310            Self::store(right_buff.as_mut_ptr(), right);
311
312            for i in 0..4 {
313                left_buff[i] *= right_buff[i];
314            }
315
316            Self::load(left_buff.as_ptr())
317        }
318    }
319
320    #[inline(always)]
321    unsafe fn div(left: Self::Vector, right: Self::Vector) -> Self::Vector {
322        let mut left_buff = [0u64; Self::VECTOR_LEN];
323        let mut right_buff = [0u64; Self::VECTOR_LEN];
324
325        unsafe {
326            Self::store(left_buff.as_mut_ptr(), left);
327            Self::store(right_buff.as_mut_ptr(), right);
328
329            for i in 0..Self::VECTOR_LEN {
330                if right_buff[i] != 0 {
331                    left_buff[i] /= right_buff[i];
332                }
333            }
334
335            Self::load(left_buff.as_ptr())
336        }
337    }
338}
339
340unsafe impl SimdNumElement for f32 {
341    #[inline(always)]
342    unsafe fn add(left: Self::Vector, right: Self::Vector) -> Self::Vector {
343        unsafe { _mm256_add_ps(left, right) }
344    }
345
346    #[inline(always)]
347    unsafe fn sub(left: Self::Vector, right: Self::Vector) -> Self::Vector {
348        unsafe { _mm256_sub_ps(left, right) }
349    }
350
351    #[inline(always)]
352    unsafe fn mul(left: Self::Vector, right: Self::Vector) -> Self::Vector {
353        unsafe { _mm256_mul_ps(left, right) }
354    }
355
356    #[inline(always)]
357    unsafe fn div(left: Self::Vector, right: Self::Vector) -> Self::Vector {
358        unsafe { _mm256_div_ps(left, right) }
359    }
360
361    #[inline(always)]
362    unsafe fn fma(a: Self::Vector, b: Self::Vector, c: Self::Vector) -> Self::Vector {
363        unsafe { _mm256_fmadd_ps(a, b, c) }
364    }
365}
366
367unsafe impl SimdNumElement for f64 {
368    #[inline(always)]
369    unsafe fn add(left: Self::Vector, right: Self::Vector) -> Self::Vector {
370        unsafe { _mm256_add_pd(left, right) }
371    }
372
373    #[inline(always)]
374    unsafe fn sub(left: Self::Vector, right: Self::Vector) -> Self::Vector {
375        unsafe { _mm256_sub_pd(left, right) }
376    }
377
378    #[inline(always)]
379    unsafe fn mul(left: Self::Vector, right: Self::Vector) -> Self::Vector {
380        unsafe { _mm256_mul_pd(left, right) }
381    }
382
383    #[inline(always)]
384    unsafe fn div(left: Self::Vector, right: Self::Vector) -> Self::Vector {
385        unsafe { _mm256_div_pd(left, right) }
386    }
387
388    #[inline(always)]
389    unsafe fn fma(a: Self::Vector, b: Self::Vector, c: Self::Vector) -> Self::Vector {
390        unsafe { _mm256_fmadd_pd(a, b, c) }
391    }
392}