diff options
Diffstat (limited to 'vendor/packed_simd_2/src/codegen/math/float/macros.rs')
-rw-r--r-- | vendor/packed_simd_2/src/codegen/math/float/macros.rs | 559 |
1 files changed, 559 insertions, 0 deletions
diff --git a/vendor/packed_simd_2/src/codegen/math/float/macros.rs b/vendor/packed_simd_2/src/codegen/math/float/macros.rs new file mode 100644 index 000000000..02d0ca3f5 --- /dev/null +++ b/vendor/packed_simd_2/src/codegen/math/float/macros.rs @@ -0,0 +1,559 @@ +//! Utility macros +#![allow(unused)] + + +macro_rules! impl_unary_ { + // implementation mapping 1:1 + (vec | $trait_id:ident, $trait_method:ident, $vec_id:ident, + $fun:ident) => { + impl $trait_id for $vec_id { + #[inline] + fn $trait_method(self) -> Self { + unsafe { + use crate::mem::transmute; + transmute($fun(transmute(self))) + } + } + } + }; + // implementation mapping 1:1 for when `$fun` is a generic function + // like some of the fp math rustc intrinsics (e.g. `fn fun<T>(x: T) -> T`). + (gen | $trait_id:ident, $trait_method:ident, $vec_id:ident, + $fun:ident) => { + impl $trait_id for $vec_id { + #[inline] + fn $trait_method(self) -> Self { + unsafe { + use crate::mem::transmute; + transmute($fun(self.0)) + } + } + } + }; + (scalar | $trait_id:ident, $trait_method:ident, + $vec_id:ident, [$sid:ident; $scount:expr], $fun:ident) => { + impl $trait_id for $vec_id { + #[inline] + fn $trait_method(self) -> Self { + unsafe { + union U { + vec: $vec_id, + scalars: [$sid; $scount], + } + let mut scalars = U { vec: self }.scalars; + for i in &mut scalars { + *i = $fun(*i); + } + U { scalars }.vec + } + } + } + }; + // implementation calling fun twice on each of the vector halves: + (halves | $trait_id:ident, $trait_method:ident, $vec_id:ident, + $vech_id:ident, $fun:ident) => { + impl $trait_id for $vec_id { + #[inline] + fn $trait_method(self) -> Self { + unsafe { + use crate::mem::transmute; + union U { + vec: $vec_id, + halves: [$vech_id; 2], + } + + let mut halves = U { vec: self }.halves; + + *halves.get_unchecked_mut(0) = + transmute($fun(transmute(*halves.get_unchecked(0)))); + *halves.get_unchecked_mut(1) = + transmute($fun(transmute(*halves.get_unchecked(1)))); + + U { halves }.vec + } + } + } + }; + // implementation calling fun four times on each of the vector quarters: + (quarter | $trait_id:ident, $trait_method:ident, $vec_id:ident, + $vecq_id:ident, $fun:ident) => { + impl $trait_id for $vec_id { + #[inline] + fn $trait_method(self) -> Self { + unsafe { + use crate::mem::transmute; + union U { + vec: $vec_id, + quarters: [$vecq_id; 4], + } + + let mut quarters = U { vec: self }.quarters; + + *quarters.get_unchecked_mut(0) = + transmute($fun(transmute(*quarters.get_unchecked(0)))); + *quarters.get_unchecked_mut(1) = + transmute($fun(transmute(*quarters.get_unchecked(1)))); + *quarters.get_unchecked_mut(2) = + transmute($fun(transmute(*quarters.get_unchecked(2)))); + *quarters.get_unchecked_mut(3) = + transmute($fun(transmute(*quarters.get_unchecked(3)))); + + U { quarters }.vec + } + } + } + }; + // implementation calling fun once on a vector twice as large: + (twice | $trait_id:ident, $trait_method:ident, $vec_id:ident, + $vect_id:ident, $fun:ident) => { + impl $trait_id for $vec_id { + #[inline] + fn $trait_method(self) -> Self { + unsafe { + use crate::mem::{transmute, uninitialized}; + + union U { + vec: [$vec_id; 2], + twice: $vect_id, + } + + let twice = U { vec: [self, uninitialized()] }.twice; + let twice = transmute($fun(transmute(twice))); + + *(U { twice }.vec.get_unchecked(0)) + } + } + } + }; +} + +macro_rules! gen_unary_impl_table { + ($trait_id:ident, $trait_method:ident) => { + macro_rules! impl_unary { + ($vid:ident: $fun:ident) => { + impl_unary_!(vec | $trait_id, $trait_method, $vid, $fun); + }; + ($vid:ident[g]: $fun:ident) => { + impl_unary_!(gen | $trait_id, $trait_method, $vid, $fun); + }; + ($vid:ident[$sid:ident; $sc:expr]: $fun:ident) => { + impl_unary_!( + scalar | $trait_id, + $trait_method, + $vid, + [$sid; $sc], + $fun + ); + }; + ($vid:ident[s]: $fun:ident) => { + impl_unary_!(scalar | $trait_id, $trait_method, $vid, $fun); + }; + ($vid:ident[h => $vid_h:ident]: $fun:ident) => { + impl_unary_!( + halves | $trait_id, + $trait_method, + $vid, + $vid_h, + $fun + ); + }; + ($vid:ident[q => $vid_q:ident]: $fun:ident) => { + impl_unary_!( + quarter | $trait_id, + $trait_method, + $vid, + $vid_q, + $fun + ); + }; + ($vid:ident[t => $vid_t:ident]: $fun:ident) => { + impl_unary_!( + twice | $trait_id, + $trait_method, + $vid, + $vid_t, + $fun + ); + }; + } + }; +} + +macro_rules! impl_tertiary_ { + // implementation mapping 1:1 + (vec | $trait_id:ident, $trait_method:ident, $vec_id:ident, + $fun:ident) => { + impl $trait_id for $vec_id { + #[inline] + fn $trait_method(self, y: Self, z: Self) -> Self { + unsafe { + use crate::mem::transmute; + transmute($fun( + transmute(self), + transmute(y), + transmute(z), + )) + } + } + } + }; + (scalar | $trait_id:ident, $trait_method:ident, + $vec_id:ident, [$sid:ident; $scount:expr], $fun:ident) => { + impl $trait_id for $vec_id { + #[inline] + fn $trait_method(self, y: Self, z: Self) -> Self { + unsafe { + union U { + vec: $vec_id, + scalars: [$sid; $scount], + } + let mut x = U { vec: self }.scalars; + let y = U { vec: y }.scalars; + let z = U { vec: z }.scalars; + for (x, (y, z)) in (&mut scalars).zip(&y).zip(&z) { + *i = $fun(*i, *y, *z); + } + U { vec: x }.vec + } + } + } + }; + // implementation calling fun twice on each of the vector halves: + (halves | $trait_id:ident, $trait_method:ident, $vec_id:ident, + $vech_id:ident, $fun:ident) => { + impl $trait_id for $vec_id { + #[inline] + fn $trait_method(self, y: Self, z: Self) -> Self { + unsafe { + use crate::mem::transmute; + union U { + vec: $vec_id, + halves: [$vech_id; 2], + } + + let mut x_halves = U { vec: self }.halves; + let y_halves = U { vec: y }.halves; + let z_halves = U { vec: z }.halves; + + *x_halves.get_unchecked_mut(0) = transmute($fun( + transmute(*x_halves.get_unchecked(0)), + transmute(*y_halves.get_unchecked(0)), + transmute(*z_halves.get_unchecked(0)), + )); + *x_halves.get_unchecked_mut(1) = transmute($fun( + transmute(*x_halves.get_unchecked(1)), + transmute(*y_halves.get_unchecked(1)), + transmute(*z_halves.get_unchecked(1)), + )); + + U { halves: x_halves }.vec + } + } + } + }; + // implementation calling fun four times on each of the vector quarters: + (quarter | $trait_id:ident, $trait_method:ident, $vec_id:ident, + $vecq_id:ident, $fun:ident) => { + impl $trait_id for $vec_id { + #[inline] + fn $trait_method(self, y: Self, z: Self) -> Self { + unsafe { + use crate::mem::transmute; + union U { + vec: $vec_id, + quarters: [$vecq_id; 4], + } + + let mut x_quarters = U { vec: self }.quarters; + let y_quarters = U { vec: y }.quarters; + let z_quarters = U { vec: z }.quarters; + + *x_quarters.get_unchecked_mut(0) = transmute($fun( + transmute(*x_quarters.get_unchecked(0)), + transmute(*y_quarters.get_unchecked(0)), + transmute(*z_quarters.get_unchecked(0)), + )); + + *x_quarters.get_unchecked_mut(1) = transmute($fun( + transmute(*x_quarters.get_unchecked(1)), + transmute(*y_quarters.get_unchecked(1)), + transmute(*z_quarters.get_unchecked(1)), + )); + + *x_quarters.get_unchecked_mut(2) = transmute($fun( + transmute(*x_quarters.get_unchecked(2)), + transmute(*y_quarters.get_unchecked(2)), + transmute(*z_quarters.get_unchecked(2)), + )); + + *x_quarters.get_unchecked_mut(3) = transmute($fun( + transmute(*x_quarters.get_unchecked(3)), + transmute(*y_quarters.get_unchecked(3)), + transmute(*z_quarters.get_unchecked(3)), + )); + + U { quarters: x_quarters }.vec + } + } + } + }; + // implementation calling fun once on a vector twice as large: + (twice | $trait_id:ident, $trait_method:ident, $vec_id:ident, + $vect_id:ident, $fun:ident) => { + impl $trait_id for $vec_id { + #[inline] + fn $trait_method(self, y: Self, z: Self) -> Self { + unsafe { + use crate::mem::{transmute, uninitialized}; + + union U { + vec: [$vec_id; 2], + twice: $vect_id, + } + + let x_twice = U { vec: [self, uninitialized()] }.twice; + let y_twice = U { vec: [y, uninitialized()] }.twice; + let z_twice = U { vec: [z, uninitialized()] }.twice; + let twice: $vect_id = transmute($fun( + transmute(x_twice), + transmute(y_twice), + transmute(z_twice), + )); + + *(U { twice }.vec.get_unchecked(0)) + } + } + } + }; +} + +macro_rules! gen_tertiary_impl_table { + ($trait_id:ident, $trait_method:ident) => { + macro_rules! impl_tertiary { + ($vid:ident: $fun:ident) => { + impl_tertiary_!(vec | $trait_id, $trait_method, $vid, $fun); + }; + ($vid:ident[$sid:ident; $sc:expr]: $fun:ident) => { + impl_tertiary_!( + scalar | $trait_id, + $trait_method, + $vid, + [$sid; $sc], + $fun + ); + }; + ($vid:ident[s]: $fun:ident) => { + impl_tertiary_!(scalar | $trait_id, $trait_method, $vid, $fun); + }; + ($vid:ident[h => $vid_h:ident]: $fun:ident) => { + impl_tertiary_!( + halves | $trait_id, + $trait_method, + $vid, + $vid_h, + $fun + ); + }; + ($vid:ident[q => $vid_q:ident]: $fun:ident) => { + impl_tertiary_!( + quarter | $trait_id, + $trait_method, + $vid, + $vid_q, + $fun + ); + }; + ($vid:ident[t => $vid_t:ident]: $fun:ident) => { + impl_tertiary_!( + twice | $trait_id, + $trait_method, + $vid, + $vid_t, + $fun + ); + }; + } + }; +} + +macro_rules! impl_binary_ { + // implementation mapping 1:1 + (vec | $trait_id:ident, $trait_method:ident, $vec_id:ident, + $fun:ident) => { + impl $trait_id for $vec_id { + #[inline] + fn $trait_method(self, y: Self) -> Self { + unsafe { + use crate::mem::transmute; + transmute($fun(transmute(self), transmute(y))) + } + } + } + }; + (scalar | $trait_id:ident, $trait_method:ident, + $vec_id:ident, [$sid:ident; $scount:expr], $fun:ident) => { + impl $trait_id for $vec_id { + #[inline] + fn $trait_method(self, y: Self) -> Self { + unsafe { + union U { + vec: $vec_id, + scalars: [$sid; $scount], + } + let mut x = U { vec: self }.scalars; + let y = U { vec: y }.scalars; + for (x, y) in x.iter_mut().zip(&y) { + *x = $fun(*x, *y); + } + U { scalars: x }.vec + } + } + } + }; + // implementation calling fun twice on each of the vector halves: + (halves | $trait_id:ident, $trait_method:ident, $vec_id:ident, + $vech_id:ident, $fun:ident) => { + impl $trait_id for $vec_id { + #[inline] + fn $trait_method(self, y: Self) -> Self { + unsafe { + use crate::mem::transmute; + union U { + vec: $vec_id, + halves: [$vech_id; 2], + } + + let mut x_halves = U { vec: self }.halves; + let y_halves = U { vec: y }.halves; + + *x_halves.get_unchecked_mut(0) = transmute($fun( + transmute(*x_halves.get_unchecked(0)), + transmute(*y_halves.get_unchecked(0)), + )); + *x_halves.get_unchecked_mut(1) = transmute($fun( + transmute(*x_halves.get_unchecked(1)), + transmute(*y_halves.get_unchecked(1)), + )); + + U { halves: x_halves }.vec + } + } + } + }; + // implementation calling fun four times on each of the vector quarters: + (quarter | $trait_id:ident, $trait_method:ident, $vec_id:ident, + $vecq_id:ident, $fun:ident) => { + impl $trait_id for $vec_id { + #[inline] + fn $trait_method(self, y: Self) -> Self { + unsafe { + use crate::mem::transmute; + union U { + vec: $vec_id, + quarters: [$vecq_id; 4], + } + + let mut x_quarters = U { vec: self }.quarters; + let y_quarters = U { vec: y }.quarters; + + *x_quarters.get_unchecked_mut(0) = transmute($fun( + transmute(*x_quarters.get_unchecked(0)), + transmute(*y_quarters.get_unchecked(0)), + )); + + *x_quarters.get_unchecked_mut(1) = transmute($fun( + transmute(*x_quarters.get_unchecked(1)), + transmute(*y_quarters.get_unchecked(1)), + )); + + *x_quarters.get_unchecked_mut(2) = transmute($fun( + transmute(*x_quarters.get_unchecked(2)), + transmute(*y_quarters.get_unchecked(2)), + )); + + *x_quarters.get_unchecked_mut(3) = transmute($fun( + transmute(*x_quarters.get_unchecked(3)), + transmute(*y_quarters.get_unchecked(3)), + )); + + U { quarters: x_quarters }.vec + } + } + } + }; + // implementation calling fun once on a vector twice as large: + (twice | $trait_id:ident, $trait_method:ident, $vec_id:ident, + $vect_id:ident, $fun:ident) => { + impl $trait_id for $vec_id { + #[inline] + fn $trait_method(self, y: Self) -> Self { + unsafe { + use crate::mem::{transmute, uninitialized}; + + union U { + vec: [$vec_id; 2], + twice: $vect_id, + } + + let x_twice = U { vec: [self, uninitialized()] }.twice; + let y_twice = U { vec: [y, uninitialized()] }.twice; + let twice: $vect_id = transmute($fun( + transmute(x_twice), + transmute(y_twice), + )); + + *(U { twice }.vec.get_unchecked(0)) + } + } + } + }; +} + +macro_rules! gen_binary_impl_table { + ($trait_id:ident, $trait_method:ident) => { + macro_rules! impl_binary { + ($vid:ident: $fun:ident) => { + impl_binary_!(vec | $trait_id, $trait_method, $vid, $fun); + }; + ($vid:ident[$sid:ident; $sc:expr]: $fun:ident) => { + impl_binary_!( + scalar | $trait_id, + $trait_method, + $vid, + [$sid; $sc], + $fun + ); + }; + ($vid:ident[s]: $fun:ident) => { + impl_binary_!(scalar | $trait_id, $trait_method, $vid, $fun); + }; + ($vid:ident[h => $vid_h:ident]: $fun:ident) => { + impl_binary_!( + halves | $trait_id, + $trait_method, + $vid, + $vid_h, + $fun + ); + }; + ($vid:ident[q => $vid_q:ident]: $fun:ident) => { + impl_binary_!( + quarter | $trait_id, + $trait_method, + $vid, + $vid_q, + $fun + ); + }; + ($vid:ident[t => $vid_t:ident]: $fun:ident) => { + impl_binary_!( + twice | $trait_id, + $trait_method, + $vid, + $vid_t, + $fun + ); + }; + } + }; +} |