]> git.proxmox.com Git - rustc.git/blob - vendor/packed_simd_2/src/codegen/math/float/macros.rs
New upstream version 1.53.0+dfsg1
[rustc.git] / vendor / packed_simd_2 / src / codegen / math / float / macros.rs
1 //! Utility macros
2 #![allow(unused)]
3
4
5 macro_rules! impl_unary_ {
6 // implementation mapping 1:1
7 (vec | $trait_id:ident, $trait_method:ident, $vec_id:ident,
8 $fun:ident) => {
9 impl $trait_id for $vec_id {
10 #[inline]
11 fn $trait_method(self) -> Self {
12 unsafe {
13 use crate::mem::transmute;
14 transmute($fun(transmute(self)))
15 }
16 }
17 }
18 };
19 // implementation mapping 1:1 for when `$fun` is a generic function
20 // like some of the fp math rustc intrinsics (e.g. `fn fun<T>(x: T) -> T`).
21 (gen | $trait_id:ident, $trait_method:ident, $vec_id:ident,
22 $fun:ident) => {
23 impl $trait_id for $vec_id {
24 #[inline]
25 fn $trait_method(self) -> Self {
26 unsafe {
27 use crate::mem::transmute;
28 transmute($fun(self.0))
29 }
30 }
31 }
32 };
33 (scalar | $trait_id:ident, $trait_method:ident,
34 $vec_id:ident, [$sid:ident; $scount:expr], $fun:ident) => {
35 impl $trait_id for $vec_id {
36 #[inline]
37 fn $trait_method(self) -> Self {
38 unsafe {
39 union U {
40 vec: $vec_id,
41 scalars: [$sid; $scount],
42 }
43 let mut scalars = U { vec: self }.scalars;
44 for i in &mut scalars {
45 *i = $fun(*i);
46 }
47 U { scalars }.vec
48 }
49 }
50 }
51 };
52 // implementation calling fun twice on each of the vector halves:
53 (halves | $trait_id:ident, $trait_method:ident, $vec_id:ident,
54 $vech_id:ident, $fun:ident) => {
55 impl $trait_id for $vec_id {
56 #[inline]
57 fn $trait_method(self) -> Self {
58 unsafe {
59 use crate::mem::transmute;
60 union U {
61 vec: $vec_id,
62 halves: [$vech_id; 2],
63 }
64
65 let mut halves = U { vec: self }.halves;
66
67 *halves.get_unchecked_mut(0) =
68 transmute($fun(transmute(*halves.get_unchecked(0))));
69 *halves.get_unchecked_mut(1) =
70 transmute($fun(transmute(*halves.get_unchecked(1))));
71
72 U { halves }.vec
73 }
74 }
75 }
76 };
77 // implementation calling fun four times on each of the vector quarters:
78 (quarter | $trait_id:ident, $trait_method:ident, $vec_id:ident,
79 $vecq_id:ident, $fun:ident) => {
80 impl $trait_id for $vec_id {
81 #[inline]
82 fn $trait_method(self) -> Self {
83 unsafe {
84 use crate::mem::transmute;
85 union U {
86 vec: $vec_id,
87 quarters: [$vecq_id; 4],
88 }
89
90 let mut quarters = U { vec: self }.quarters;
91
92 *quarters.get_unchecked_mut(0) =
93 transmute($fun(transmute(*quarters.get_unchecked(0))));
94 *quarters.get_unchecked_mut(1) =
95 transmute($fun(transmute(*quarters.get_unchecked(1))));
96 *quarters.get_unchecked_mut(2) =
97 transmute($fun(transmute(*quarters.get_unchecked(2))));
98 *quarters.get_unchecked_mut(3) =
99 transmute($fun(transmute(*quarters.get_unchecked(3))));
100
101 U { quarters }.vec
102 }
103 }
104 }
105 };
106 // implementation calling fun once on a vector twice as large:
107 (twice | $trait_id:ident, $trait_method:ident, $vec_id:ident,
108 $vect_id:ident, $fun:ident) => {
109 impl $trait_id for $vec_id {
110 #[inline]
111 fn $trait_method(self) -> Self {
112 unsafe {
113 use crate::mem::{transmute, uninitialized};
114
115 union U {
116 vec: [$vec_id; 2],
117 twice: $vect_id,
118 }
119
120 let twice = U { vec: [self, uninitialized()] }.twice;
121 let twice = transmute($fun(transmute(twice)));
122
123 *(U { twice }.vec.get_unchecked(0))
124 }
125 }
126 }
127 };
128 }
129
130 macro_rules! gen_unary_impl_table {
131 ($trait_id:ident, $trait_method:ident) => {
132 macro_rules! impl_unary {
133 ($vid:ident: $fun:ident) => {
134 impl_unary_!(vec | $trait_id, $trait_method, $vid, $fun);
135 };
136 ($vid:ident[g]: $fun:ident) => {
137 impl_unary_!(gen | $trait_id, $trait_method, $vid, $fun);
138 };
139 ($vid:ident[$sid:ident; $sc:expr]: $fun:ident) => {
140 impl_unary_!(
141 scalar | $trait_id,
142 $trait_method,
143 $vid,
144 [$sid; $sc],
145 $fun
146 );
147 };
148 ($vid:ident[s]: $fun:ident) => {
149 impl_unary_!(scalar | $trait_id, $trait_method, $vid, $fun);
150 };
151 ($vid:ident[h => $vid_h:ident]: $fun:ident) => {
152 impl_unary_!(
153 halves | $trait_id,
154 $trait_method,
155 $vid,
156 $vid_h,
157 $fun
158 );
159 };
160 ($vid:ident[q => $vid_q:ident]: $fun:ident) => {
161 impl_unary_!(
162 quarter | $trait_id,
163 $trait_method,
164 $vid,
165 $vid_q,
166 $fun
167 );
168 };
169 ($vid:ident[t => $vid_t:ident]: $fun:ident) => {
170 impl_unary_!(
171 twice | $trait_id,
172 $trait_method,
173 $vid,
174 $vid_t,
175 $fun
176 );
177 };
178 }
179 };
180 }
181
182 macro_rules! impl_tertiary_ {
183 // implementation mapping 1:1
184 (vec | $trait_id:ident, $trait_method:ident, $vec_id:ident,
185 $fun:ident) => {
186 impl $trait_id for $vec_id {
187 #[inline]
188 fn $trait_method(self, y: Self, z: Self) -> Self {
189 unsafe {
190 use crate::mem::transmute;
191 transmute($fun(
192 transmute(self),
193 transmute(y),
194 transmute(z),
195 ))
196 }
197 }
198 }
199 };
200 (scalar | $trait_id:ident, $trait_method:ident,
201 $vec_id:ident, [$sid:ident; $scount:expr], $fun:ident) => {
202 impl $trait_id for $vec_id {
203 #[inline]
204 fn $trait_method(self, y: Self, z: Self) -> Self {
205 unsafe {
206 union U {
207 vec: $vec_id,
208 scalars: [$sid; $scount],
209 }
210 let mut x = U { vec: self }.scalars;
211 let y = U { vec: y }.scalars;
212 let z = U { vec: z }.scalars;
213 for (x, (y, z)) in (&mut scalars).zip(&y).zip(&z) {
214 *i = $fun(*i, *y, *z);
215 }
216 U { vec: x }.vec
217 }
218 }
219 }
220 };
221 // implementation calling fun twice on each of the vector halves:
222 (halves | $trait_id:ident, $trait_method:ident, $vec_id:ident,
223 $vech_id:ident, $fun:ident) => {
224 impl $trait_id for $vec_id {
225 #[inline]
226 fn $trait_method(self, y: Self, z: Self) -> Self {
227 unsafe {
228 use crate::mem::transmute;
229 union U {
230 vec: $vec_id,
231 halves: [$vech_id; 2],
232 }
233
234 let mut x_halves = U { vec: self }.halves;
235 let y_halves = U { vec: y }.halves;
236 let z_halves = U { vec: z }.halves;
237
238 *x_halves.get_unchecked_mut(0) = transmute($fun(
239 transmute(*x_halves.get_unchecked(0)),
240 transmute(*y_halves.get_unchecked(0)),
241 transmute(*z_halves.get_unchecked(0)),
242 ));
243 *x_halves.get_unchecked_mut(1) = transmute($fun(
244 transmute(*x_halves.get_unchecked(1)),
245 transmute(*y_halves.get_unchecked(1)),
246 transmute(*z_halves.get_unchecked(1)),
247 ));
248
249 U { halves: x_halves }.vec
250 }
251 }
252 }
253 };
254 // implementation calling fun four times on each of the vector quarters:
255 (quarter | $trait_id:ident, $trait_method:ident, $vec_id:ident,
256 $vecq_id:ident, $fun:ident) => {
257 impl $trait_id for $vec_id {
258 #[inline]
259 fn $trait_method(self, y: Self, z: Self) -> Self {
260 unsafe {
261 use crate::mem::transmute;
262 union U {
263 vec: $vec_id,
264 quarters: [$vecq_id; 4],
265 }
266
267 let mut x_quarters = U { vec: self }.quarters;
268 let y_quarters = U { vec: y }.quarters;
269 let z_quarters = U { vec: z }.quarters;
270
271 *x_quarters.get_unchecked_mut(0) = transmute($fun(
272 transmute(*x_quarters.get_unchecked(0)),
273 transmute(*y_quarters.get_unchecked(0)),
274 transmute(*z_quarters.get_unchecked(0)),
275 ));
276
277 *x_quarters.get_unchecked_mut(1) = transmute($fun(
278 transmute(*x_quarters.get_unchecked(1)),
279 transmute(*y_quarters.get_unchecked(1)),
280 transmute(*z_quarters.get_unchecked(1)),
281 ));
282
283 *x_quarters.get_unchecked_mut(2) = transmute($fun(
284 transmute(*x_quarters.get_unchecked(2)),
285 transmute(*y_quarters.get_unchecked(2)),
286 transmute(*z_quarters.get_unchecked(2)),
287 ));
288
289 *x_quarters.get_unchecked_mut(3) = transmute($fun(
290 transmute(*x_quarters.get_unchecked(3)),
291 transmute(*y_quarters.get_unchecked(3)),
292 transmute(*z_quarters.get_unchecked(3)),
293 ));
294
295 U { quarters: x_quarters }.vec
296 }
297 }
298 }
299 };
300 // implementation calling fun once on a vector twice as large:
301 (twice | $trait_id:ident, $trait_method:ident, $vec_id:ident,
302 $vect_id:ident, $fun:ident) => {
303 impl $trait_id for $vec_id {
304 #[inline]
305 fn $trait_method(self, y: Self, z: Self) -> Self {
306 unsafe {
307 use crate::mem::{transmute, uninitialized};
308
309 union U {
310 vec: [$vec_id; 2],
311 twice: $vect_id,
312 }
313
314 let x_twice = U { vec: [self, uninitialized()] }.twice;
315 let y_twice = U { vec: [y, uninitialized()] }.twice;
316 let z_twice = U { vec: [z, uninitialized()] }.twice;
317 let twice: $vect_id = transmute($fun(
318 transmute(x_twice),
319 transmute(y_twice),
320 transmute(z_twice),
321 ));
322
323 *(U { twice }.vec.get_unchecked(0))
324 }
325 }
326 }
327 };
328 }
329
330 macro_rules! gen_tertiary_impl_table {
331 ($trait_id:ident, $trait_method:ident) => {
332 macro_rules! impl_tertiary {
333 ($vid:ident: $fun:ident) => {
334 impl_tertiary_!(vec | $trait_id, $trait_method, $vid, $fun);
335 };
336 ($vid:ident[$sid:ident; $sc:expr]: $fun:ident) => {
337 impl_tertiary_!(
338 scalar | $trait_id,
339 $trait_method,
340 $vid,
341 [$sid; $sc],
342 $fun
343 );
344 };
345 ($vid:ident[s]: $fun:ident) => {
346 impl_tertiary_!(scalar | $trait_id, $trait_method, $vid, $fun);
347 };
348 ($vid:ident[h => $vid_h:ident]: $fun:ident) => {
349 impl_tertiary_!(
350 halves | $trait_id,
351 $trait_method,
352 $vid,
353 $vid_h,
354 $fun
355 );
356 };
357 ($vid:ident[q => $vid_q:ident]: $fun:ident) => {
358 impl_tertiary_!(
359 quarter | $trait_id,
360 $trait_method,
361 $vid,
362 $vid_q,
363 $fun
364 );
365 };
366 ($vid:ident[t => $vid_t:ident]: $fun:ident) => {
367 impl_tertiary_!(
368 twice | $trait_id,
369 $trait_method,
370 $vid,
371 $vid_t,
372 $fun
373 );
374 };
375 }
376 };
377 }
378
379 macro_rules! impl_binary_ {
380 // implementation mapping 1:1
381 (vec | $trait_id:ident, $trait_method:ident, $vec_id:ident,
382 $fun:ident) => {
383 impl $trait_id for $vec_id {
384 #[inline]
385 fn $trait_method(self, y: Self) -> Self {
386 unsafe {
387 use crate::mem::transmute;
388 transmute($fun(transmute(self), transmute(y)))
389 }
390 }
391 }
392 };
393 (scalar | $trait_id:ident, $trait_method:ident,
394 $vec_id:ident, [$sid:ident; $scount:expr], $fun:ident) => {
395 impl $trait_id for $vec_id {
396 #[inline]
397 fn $trait_method(self, y: Self) -> Self {
398 unsafe {
399 union U {
400 vec: $vec_id,
401 scalars: [$sid; $scount],
402 }
403 let mut x = U { vec: self }.scalars;
404 let y = U { vec: y }.scalars;
405 for (x, y) in x.iter_mut().zip(&y) {
406 *x = $fun(*x, *y);
407 }
408 U { scalars: x }.vec
409 }
410 }
411 }
412 };
413 // implementation calling fun twice on each of the vector halves:
414 (halves | $trait_id:ident, $trait_method:ident, $vec_id:ident,
415 $vech_id:ident, $fun:ident) => {
416 impl $trait_id for $vec_id {
417 #[inline]
418 fn $trait_method(self, y: Self) -> Self {
419 unsafe {
420 use crate::mem::transmute;
421 union U {
422 vec: $vec_id,
423 halves: [$vech_id; 2],
424 }
425
426 let mut x_halves = U { vec: self }.halves;
427 let y_halves = U { vec: y }.halves;
428
429 *x_halves.get_unchecked_mut(0) = transmute($fun(
430 transmute(*x_halves.get_unchecked(0)),
431 transmute(*y_halves.get_unchecked(0)),
432 ));
433 *x_halves.get_unchecked_mut(1) = transmute($fun(
434 transmute(*x_halves.get_unchecked(1)),
435 transmute(*y_halves.get_unchecked(1)),
436 ));
437
438 U { halves: x_halves }.vec
439 }
440 }
441 }
442 };
443 // implementation calling fun four times on each of the vector quarters:
444 (quarter | $trait_id:ident, $trait_method:ident, $vec_id:ident,
445 $vecq_id:ident, $fun:ident) => {
446 impl $trait_id for $vec_id {
447 #[inline]
448 fn $trait_method(self, y: Self) -> Self {
449 unsafe {
450 use crate::mem::transmute;
451 union U {
452 vec: $vec_id,
453 quarters: [$vecq_id; 4],
454 }
455
456 let mut x_quarters = U { vec: self }.quarters;
457 let y_quarters = U { vec: y }.quarters;
458
459 *x_quarters.get_unchecked_mut(0) = transmute($fun(
460 transmute(*x_quarters.get_unchecked(0)),
461 transmute(*y_quarters.get_unchecked(0)),
462 ));
463
464 *x_quarters.get_unchecked_mut(1) = transmute($fun(
465 transmute(*x_quarters.get_unchecked(1)),
466 transmute(*y_quarters.get_unchecked(1)),
467 ));
468
469 *x_quarters.get_unchecked_mut(2) = transmute($fun(
470 transmute(*x_quarters.get_unchecked(2)),
471 transmute(*y_quarters.get_unchecked(2)),
472 ));
473
474 *x_quarters.get_unchecked_mut(3) = transmute($fun(
475 transmute(*x_quarters.get_unchecked(3)),
476 transmute(*y_quarters.get_unchecked(3)),
477 ));
478
479 U { quarters: x_quarters }.vec
480 }
481 }
482 }
483 };
484 // implementation calling fun once on a vector twice as large:
485 (twice | $trait_id:ident, $trait_method:ident, $vec_id:ident,
486 $vect_id:ident, $fun:ident) => {
487 impl $trait_id for $vec_id {
488 #[inline]
489 fn $trait_method(self, y: Self) -> Self {
490 unsafe {
491 use crate::mem::{transmute, uninitialized};
492
493 union U {
494 vec: [$vec_id; 2],
495 twice: $vect_id,
496 }
497
498 let x_twice = U { vec: [self, uninitialized()] }.twice;
499 let y_twice = U { vec: [y, uninitialized()] }.twice;
500 let twice: $vect_id = transmute($fun(
501 transmute(x_twice),
502 transmute(y_twice),
503 ));
504
505 *(U { twice }.vec.get_unchecked(0))
506 }
507 }
508 }
509 };
510 }
511
512 macro_rules! gen_binary_impl_table {
513 ($trait_id:ident, $trait_method:ident) => {
514 macro_rules! impl_binary {
515 ($vid:ident: $fun:ident) => {
516 impl_binary_!(vec | $trait_id, $trait_method, $vid, $fun);
517 };
518 ($vid:ident[$sid:ident; $sc:expr]: $fun:ident) => {
519 impl_binary_!(
520 scalar | $trait_id,
521 $trait_method,
522 $vid,
523 [$sid; $sc],
524 $fun
525 );
526 };
527 ($vid:ident[s]: $fun:ident) => {
528 impl_binary_!(scalar | $trait_id, $trait_method, $vid, $fun);
529 };
530 ($vid:ident[h => $vid_h:ident]: $fun:ident) => {
531 impl_binary_!(
532 halves | $trait_id,
533 $trait_method,
534 $vid,
535 $vid_h,
536 $fun
537 );
538 };
539 ($vid:ident[q => $vid_q:ident]: $fun:ident) => {
540 impl_binary_!(
541 quarter | $trait_id,
542 $trait_method,
543 $vid,
544 $vid_q,
545 $fun
546 );
547 };
548 ($vid:ident[t => $vid_t:ident]: $fun:ident) => {
549 impl_binary_!(
550 twice | $trait_id,
551 $trait_method,
552 $vid,
553 $vid_t,
554 $fun
555 );
556 };
557 }
558 };
559 }