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}