diff options
Diffstat (limited to 'vendor/packed_simd/src/api/ops')
-rw-r--r-- | vendor/packed_simd/src/api/ops/scalar_arithmetic.rs | 203 | ||||
-rw-r--r-- | vendor/packed_simd/src/api/ops/scalar_bitwise.rs | 162 | ||||
-rw-r--r-- | vendor/packed_simd/src/api/ops/scalar_mask_bitwise.rs | 140 | ||||
-rw-r--r-- | vendor/packed_simd/src/api/ops/scalar_shifts.rs | 106 | ||||
-rw-r--r-- | vendor/packed_simd/src/api/ops/vector_arithmetic.rs | 148 | ||||
-rw-r--r-- | vendor/packed_simd/src/api/ops/vector_bitwise.rs | 129 | ||||
-rw-r--r-- | vendor/packed_simd/src/api/ops/vector_float_min_max.rs | 74 | ||||
-rw-r--r-- | vendor/packed_simd/src/api/ops/vector_int_min_max.rs | 57 | ||||
-rw-r--r-- | vendor/packed_simd/src/api/ops/vector_mask_bitwise.rs | 116 | ||||
-rw-r--r-- | vendor/packed_simd/src/api/ops/vector_neg.rs | 43 | ||||
-rw-r--r-- | vendor/packed_simd/src/api/ops/vector_rotates.rs | 92 | ||||
-rw-r--r-- | vendor/packed_simd/src/api/ops/vector_shifts.rs | 106 |
12 files changed, 1376 insertions, 0 deletions
diff --git a/vendor/packed_simd/src/api/ops/scalar_arithmetic.rs b/vendor/packed_simd/src/api/ops/scalar_arithmetic.rs new file mode 100644 index 000000000..da1a2037e --- /dev/null +++ b/vendor/packed_simd/src/api/ops/scalar_arithmetic.rs @@ -0,0 +1,203 @@ +//! Vertical (lane-wise) vector-scalar / scalar-vector arithmetic operations. + +macro_rules! impl_ops_scalar_arithmetic { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { + impl crate::ops::Add<$elem_ty> for $id { + type Output = Self; + #[inline] + fn add(self, other: $elem_ty) -> Self { + self + $id::splat(other) + } + } + impl crate::ops::Add<$id> for $elem_ty { + type Output = $id; + #[inline] + fn add(self, other: $id) -> $id { + $id::splat(self) + other + } + } + + impl crate::ops::Sub<$elem_ty> for $id { + type Output = Self; + #[inline] + fn sub(self, other: $elem_ty) -> Self { + self - $id::splat(other) + } + } + impl crate::ops::Sub<$id> for $elem_ty { + type Output = $id; + #[inline] + fn sub(self, other: $id) -> $id { + $id::splat(self) - other + } + } + + impl crate::ops::Mul<$elem_ty> for $id { + type Output = Self; + #[inline] + fn mul(self, other: $elem_ty) -> Self { + self * $id::splat(other) + } + } + impl crate::ops::Mul<$id> for $elem_ty { + type Output = $id; + #[inline] + fn mul(self, other: $id) -> $id { + $id::splat(self) * other + } + } + + impl crate::ops::Div<$elem_ty> for $id { + type Output = Self; + #[inline] + fn div(self, other: $elem_ty) -> Self { + self / $id::splat(other) + } + } + impl crate::ops::Div<$id> for $elem_ty { + type Output = $id; + #[inline] + fn div(self, other: $id) -> $id { + $id::splat(self) / other + } + } + + impl crate::ops::Rem<$elem_ty> for $id { + type Output = Self; + #[inline] + fn rem(self, other: $elem_ty) -> Self { + self % $id::splat(other) + } + } + impl crate::ops::Rem<$id> for $elem_ty { + type Output = $id; + #[inline] + fn rem(self, other: $id) -> $id { + $id::splat(self) % other + } + } + + impl crate::ops::AddAssign<$elem_ty> for $id { + #[inline] + fn add_assign(&mut self, other: $elem_ty) { + *self = *self + other; + } + } + + impl crate::ops::SubAssign<$elem_ty> for $id { + #[inline] + fn sub_assign(&mut self, other: $elem_ty) { + *self = *self - other; + } + } + + impl crate::ops::MulAssign<$elem_ty> for $id { + #[inline] + fn mul_assign(&mut self, other: $elem_ty) { + *self = *self * other; + } + } + + impl crate::ops::DivAssign<$elem_ty> for $id { + #[inline] + fn div_assign(&mut self, other: $elem_ty) { + *self = *self / other; + } + } + + impl crate::ops::RemAssign<$elem_ty> for $id { + #[inline] + fn rem_assign(&mut self, other: $elem_ty) { + *self = *self % other; + } + } + + test_if!{ + $test_tt: + paste::item! { + pub mod [<$id _ops_scalar_arith>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn ops_scalar_arithmetic() { + let zi = 0 as $elem_ty; + let oi = 1 as $elem_ty; + let ti = 2 as $elem_ty; + let fi = 4 as $elem_ty; + let z = $id::splat(zi); + let o = $id::splat(oi); + let t = $id::splat(ti); + let f = $id::splat(fi); + + // add + assert_eq!(zi + z, z); + assert_eq!(z + zi, z); + assert_eq!(oi + z, o); + assert_eq!(o + zi, o); + assert_eq!(ti + z, t); + assert_eq!(t + zi, t); + assert_eq!(ti + t, f); + assert_eq!(t + ti, f); + // sub + assert_eq!(zi - z, z); + assert_eq!(z - zi, z); + assert_eq!(oi - z, o); + assert_eq!(o - zi, o); + assert_eq!(ti - z, t); + assert_eq!(t - zi, t); + assert_eq!(fi - t, t); + assert_eq!(f - ti, t); + assert_eq!(f - o - o, t); + assert_eq!(f - oi - oi, t); + // mul + assert_eq!(zi * z, z); + assert_eq!(z * zi, z); + assert_eq!(zi * o, z); + assert_eq!(z * oi, z); + assert_eq!(zi * t, z); + assert_eq!(z * ti, z); + assert_eq!(oi * t, t); + assert_eq!(o * ti, t); + assert_eq!(ti * t, f); + assert_eq!(t * ti, f); + // div + assert_eq!(zi / o, z); + assert_eq!(z / oi, z); + assert_eq!(ti / o, t); + assert_eq!(t / oi, t); + assert_eq!(fi / o, f); + assert_eq!(f / oi, f); + assert_eq!(ti / t, o); + assert_eq!(t / ti, o); + assert_eq!(fi / t, t); + assert_eq!(f / ti, t); + // rem + assert_eq!(oi % o, z); + assert_eq!(o % oi, z); + assert_eq!(fi % t, z); + assert_eq!(f % ti, z); + + { + let mut v = z; + assert_eq!(v, z); + v += oi; // add_assign + assert_eq!(v, o); + v -= oi; // sub_assign + assert_eq!(v, z); + v = t; + v *= oi; // mul_assign + assert_eq!(v, t); + v *= ti; + assert_eq!(v, f); + v /= oi; // div_assign + assert_eq!(v, f); + v /= ti; + assert_eq!(v, t); + v %= ti; // rem_assign + assert_eq!(v, z); + } + } + } + } + } + }; +} diff --git a/vendor/packed_simd/src/api/ops/scalar_bitwise.rs b/vendor/packed_simd/src/api/ops/scalar_bitwise.rs new file mode 100644 index 000000000..88216769a --- /dev/null +++ b/vendor/packed_simd/src/api/ops/scalar_bitwise.rs @@ -0,0 +1,162 @@ +//! Vertical (lane-wise) vector-scalar / scalar-vector bitwise operations. + +macro_rules! impl_ops_scalar_bitwise { + ( + [$elem_ty:ident; $elem_count:expr]: + $id:ident | $test_tt:tt | + ($true:expr, $false:expr) + ) => { + impl crate::ops::BitXor<$elem_ty> for $id { + type Output = Self; + #[inline] + fn bitxor(self, other: $elem_ty) -> Self { + self ^ $id::splat(other) + } + } + impl crate::ops::BitXor<$id> for $elem_ty { + type Output = $id; + #[inline] + fn bitxor(self, other: $id) -> $id { + $id::splat(self) ^ other + } + } + + impl crate::ops::BitAnd<$elem_ty> for $id { + type Output = Self; + #[inline] + fn bitand(self, other: $elem_ty) -> Self { + self & $id::splat(other) + } + } + impl crate::ops::BitAnd<$id> for $elem_ty { + type Output = $id; + #[inline] + fn bitand(self, other: $id) -> $id { + $id::splat(self) & other + } + } + + impl crate::ops::BitOr<$elem_ty> for $id { + type Output = Self; + #[inline] + fn bitor(self, other: $elem_ty) -> Self { + self | $id::splat(other) + } + } + impl crate::ops::BitOr<$id> for $elem_ty { + type Output = $id; + #[inline] + fn bitor(self, other: $id) -> $id { + $id::splat(self) | other + } + } + + impl crate::ops::BitAndAssign<$elem_ty> for $id { + #[inline] + fn bitand_assign(&mut self, other: $elem_ty) { + *self = *self & other; + } + } + impl crate::ops::BitOrAssign<$elem_ty> for $id { + #[inline] + fn bitor_assign(&mut self, other: $elem_ty) { + *self = *self | other; + } + } + impl crate::ops::BitXorAssign<$elem_ty> for $id { + #[inline] + fn bitxor_assign(&mut self, other: $elem_ty) { + *self = *self ^ other; + } + } + + test_if!{ + $test_tt: + paste::item! { + pub mod [<$id _ops_scalar_bitwise>] { + use super::*; + + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn ops_scalar_bitwise() { + let zi = 0 as $elem_ty; + let oi = 1 as $elem_ty; + let ti = 2 as $elem_ty; + let z = $id::splat(zi); + let o = $id::splat(oi); + let t = $id::splat(ti); + + // BitAnd: + assert_eq!(oi & o, o); + assert_eq!(o & oi, o); + assert_eq!(oi & z, z); + assert_eq!(o & zi, z); + assert_eq!(zi & o, z); + assert_eq!(z & oi, z); + assert_eq!(zi & z, z); + assert_eq!(z & zi, z); + + assert_eq!(ti & t, t); + assert_eq!(t & ti, t); + assert_eq!(ti & o, z); + assert_eq!(t & oi, z); + assert_eq!(oi & t, z); + assert_eq!(o & ti, z); + + // BitOr: + assert_eq!(oi | o, o); + assert_eq!(o | oi, o); + assert_eq!(oi | z, o); + assert_eq!(o | zi, o); + assert_eq!(zi | o, o); + assert_eq!(z | oi, o); + assert_eq!(zi | z, z); + assert_eq!(z | zi, z); + + assert_eq!(ti | t, t); + assert_eq!(t | ti, t); + assert_eq!(zi | t, t); + assert_eq!(z | ti, t); + assert_eq!(ti | z, t); + assert_eq!(t | zi, t); + + // BitXOR: + assert_eq!(oi ^ o, z); + assert_eq!(o ^ oi, z); + assert_eq!(zi ^ z, z); + assert_eq!(z ^ zi, z); + assert_eq!(zi ^ o, o); + assert_eq!(z ^ oi, o); + assert_eq!(oi ^ z, o); + assert_eq!(o ^ zi, o); + + assert_eq!(ti ^ t, z); + assert_eq!(t ^ ti, z); + assert_eq!(ti ^ z, t); + assert_eq!(t ^ zi, t); + assert_eq!(zi ^ t, t); + assert_eq!(z ^ ti, t); + + { + // AndAssign: + let mut v = o; + v &= ti; + assert_eq!(v, z); + } + { + // OrAssign: + let mut v = z; + v |= oi; + assert_eq!(v, o); + } + { + // XORAssign: + let mut v = z; + v ^= oi; + assert_eq!(v, o); + } + } + } + } + } + }; +} diff --git a/vendor/packed_simd/src/api/ops/scalar_mask_bitwise.rs b/vendor/packed_simd/src/api/ops/scalar_mask_bitwise.rs new file mode 100644 index 000000000..523a85207 --- /dev/null +++ b/vendor/packed_simd/src/api/ops/scalar_mask_bitwise.rs @@ -0,0 +1,140 @@ +//! Vertical (lane-wise) vector-vector bitwise operations. + +macro_rules! impl_ops_scalar_mask_bitwise { + ( + [$elem_ty:ident; $elem_count:expr]: + $id:ident | $test_tt:tt | + ($true:expr, $false:expr) + ) => { + impl crate::ops::BitXor<bool> for $id { + type Output = Self; + #[inline] + fn bitxor(self, other: bool) -> Self { + self ^ $id::splat(other) + } + } + impl crate::ops::BitXor<$id> for bool { + type Output = $id; + #[inline] + fn bitxor(self, other: $id) -> $id { + $id::splat(self) ^ other + } + } + + impl crate::ops::BitAnd<bool> for $id { + type Output = Self; + #[inline] + fn bitand(self, other: bool) -> Self { + self & $id::splat(other) + } + } + impl crate::ops::BitAnd<$id> for bool { + type Output = $id; + #[inline] + fn bitand(self, other: $id) -> $id { + $id::splat(self) & other + } + } + + impl crate::ops::BitOr<bool> for $id { + type Output = Self; + #[inline] + fn bitor(self, other: bool) -> Self { + self | $id::splat(other) + } + } + impl crate::ops::BitOr<$id> for bool { + type Output = $id; + #[inline] + fn bitor(self, other: $id) -> $id { + $id::splat(self) | other + } + } + + impl crate::ops::BitAndAssign<bool> for $id { + #[inline] + fn bitand_assign(&mut self, other: bool) { + *self = *self & other; + } + } + impl crate::ops::BitOrAssign<bool> for $id { + #[inline] + fn bitor_assign(&mut self, other: bool) { + *self = *self | other; + } + } + impl crate::ops::BitXorAssign<bool> for $id { + #[inline] + fn bitxor_assign(&mut self, other: bool) { + *self = *self ^ other; + } + } + + test_if!{ + $test_tt: + paste::item! { + pub mod [<$id _ops_scalar_mask_bitwise>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn ops_scalar_mask_bitwise() { + let ti = true; + let fi = false; + let t = $id::splat(ti); + let f = $id::splat(fi); + assert!(t != f); + assert!(!(t == f)); + + // BitAnd: + assert_eq!(ti & f, f); + assert_eq!(t & fi, f); + assert_eq!(fi & t, f); + assert_eq!(f & ti, f); + assert_eq!(ti & t, t); + assert_eq!(t & ti, t); + assert_eq!(fi & f, f); + assert_eq!(f & fi, f); + + // BitOr: + assert_eq!(ti | f, t); + assert_eq!(t | fi, t); + assert_eq!(fi | t, t); + assert_eq!(f | ti, t); + assert_eq!(ti | t, t); + assert_eq!(t | ti, t); + assert_eq!(fi | f, f); + assert_eq!(f | fi, f); + + // BitXOR: + assert_eq!(ti ^ f, t); + assert_eq!(t ^ fi, t); + assert_eq!(fi ^ t, t); + assert_eq!(f ^ ti, t); + assert_eq!(ti ^ t, f); + assert_eq!(t ^ ti, f); + assert_eq!(fi ^ f, f); + assert_eq!(f ^ fi, f); + + { + // AndAssign: + let mut v = f; + v &= ti; + assert_eq!(v, f); + } + { + // OrAssign: + let mut v = f; + v |= ti; + assert_eq!(v, t); + } + { + // XORAssign: + let mut v = f; + v ^= ti; + assert_eq!(v, t); + } + } + } + } + } + }; +} diff --git a/vendor/packed_simd/src/api/ops/scalar_shifts.rs b/vendor/packed_simd/src/api/ops/scalar_shifts.rs new file mode 100644 index 000000000..4a7a09626 --- /dev/null +++ b/vendor/packed_simd/src/api/ops/scalar_shifts.rs @@ -0,0 +1,106 @@ +//! Vertical (lane-wise) vector-scalar shifts operations. + +macro_rules! impl_ops_scalar_shifts { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { + impl crate::ops::Shl<u32> for $id { + type Output = Self; + #[inline] + fn shl(self, other: u32) -> Self { + self << $id::splat(other as $elem_ty) + } + } + impl crate::ops::Shr<u32> for $id { + type Output = Self; + #[inline] + fn shr(self, other: u32) -> Self { + self >> $id::splat(other as $elem_ty) + } + } + + impl crate::ops::ShlAssign<u32> for $id { + #[inline] + fn shl_assign(&mut self, other: u32) { + *self = *self << other; + } + } + impl crate::ops::ShrAssign<u32> for $id { + #[inline] + fn shr_assign(&mut self, other: u32) { + *self = *self >> other; + } + } + test_if!{ + $test_tt: + paste::item! { + pub mod [<$id _ops_scalar_shifts>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr(any(target_arch = "s390x", target_arch = "sparc64"), + allow(unreachable_code, unused_variables) + )] + #[cfg(not(target_arch = "aarch64"))] + //~^ FIXME: https://github.com/rust-lang/packed_simd/issues/317 + fn ops_scalar_shifts() { + let z = $id::splat(0 as $elem_ty); + let o = $id::splat(1 as $elem_ty); + let t = $id::splat(2 as $elem_ty); + let f = $id::splat(4 as $elem_ty); + + { + let zi = 0 as u32; + let oi = 1 as u32; + let ti = 2 as u32; + let maxi + = (mem::size_of::<$elem_ty>() * 8 - 1) as u32; + + // shr + assert_eq!(z >> zi, z); + assert_eq!(z >> oi, z); + assert_eq!(z >> ti, z); + assert_eq!(z >> ti, z); + + #[cfg(any(target_arch = "s390x", target_arch = "sparc64"))] { + // FIXME: https://github.com/rust-lang-nursery/packed_simd/issues/13 + return; + } + + assert_eq!(o >> zi, o); + assert_eq!(t >> zi, t); + assert_eq!(f >> zi, f); + assert_eq!(f >> maxi, z); + + assert_eq!(o >> oi, z); + assert_eq!(t >> oi, o); + assert_eq!(t >> ti, z); + assert_eq!(f >> oi, t); + assert_eq!(f >> ti, o); + assert_eq!(f >> maxi, z); + + // shl + assert_eq!(z << zi, z); + assert_eq!(o << zi, o); + assert_eq!(t << zi, t); + assert_eq!(f << zi, f); + assert_eq!(f << maxi, z); + + assert_eq!(o << oi, t); + assert_eq!(o << ti, f); + assert_eq!(t << oi, f); + + { // shr_assign + let mut v = o; + v >>= oi; + assert_eq!(v, z); + } + { // shl_assign + let mut v = o; + v <<= oi; + assert_eq!(v, t); + } + } + } + } + } + } + }; +} diff --git a/vendor/packed_simd/src/api/ops/vector_arithmetic.rs b/vendor/packed_simd/src/api/ops/vector_arithmetic.rs new file mode 100644 index 000000000..7057f52d0 --- /dev/null +++ b/vendor/packed_simd/src/api/ops/vector_arithmetic.rs @@ -0,0 +1,148 @@ +//! Vertical (lane-wise) vector-vector arithmetic operations. + +macro_rules! impl_ops_vector_arithmetic { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { + impl crate::ops::Add for $id { + type Output = Self; + #[inline] + fn add(self, other: Self) -> Self { + use crate::llvm::simd_add; + unsafe { Simd(simd_add(self.0, other.0)) } + } + } + + impl crate::ops::Sub for $id { + type Output = Self; + #[inline] + fn sub(self, other: Self) -> Self { + use crate::llvm::simd_sub; + unsafe { Simd(simd_sub(self.0, other.0)) } + } + } + + impl crate::ops::Mul for $id { + type Output = Self; + #[inline] + fn mul(self, other: Self) -> Self { + use crate::llvm::simd_mul; + unsafe { Simd(simd_mul(self.0, other.0)) } + } + } + + impl crate::ops::Div for $id { + type Output = Self; + #[inline] + fn div(self, other: Self) -> Self { + use crate::llvm::simd_div; + unsafe { Simd(simd_div(self.0, other.0)) } + } + } + + impl crate::ops::Rem for $id { + type Output = Self; + #[inline] + fn rem(self, other: Self) -> Self { + use crate::llvm::simd_rem; + unsafe { Simd(simd_rem(self.0, other.0)) } + } + } + + impl crate::ops::AddAssign for $id { + #[inline] + fn add_assign(&mut self, other: Self) { + *self = *self + other; + } + } + + impl crate::ops::SubAssign for $id { + #[inline] + fn sub_assign(&mut self, other: Self) { + *self = *self - other; + } + } + + impl crate::ops::MulAssign for $id { + #[inline] + fn mul_assign(&mut self, other: Self) { + *self = *self * other; + } + } + + impl crate::ops::DivAssign for $id { + #[inline] + fn div_assign(&mut self, other: Self) { + *self = *self / other; + } + } + + impl crate::ops::RemAssign for $id { + #[inline] + fn rem_assign(&mut self, other: Self) { + *self = *self % other; + } + } + + test_if!{ + $test_tt: + paste::item! { + pub mod [<$id _ops_vector_arith>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn ops_vector_arithmetic() { + let z = $id::splat(0 as $elem_ty); + let o = $id::splat(1 as $elem_ty); + let t = $id::splat(2 as $elem_ty); + let f = $id::splat(4 as $elem_ty); + + // add + assert_eq!(z + z, z); + assert_eq!(o + z, o); + assert_eq!(t + z, t); + assert_eq!(t + t, f); + // sub + assert_eq!(z - z, z); + assert_eq!(o - z, o); + assert_eq!(t - z, t); + assert_eq!(f - t, t); + assert_eq!(f - o - o, t); + // mul + assert_eq!(z * z, z); + assert_eq!(z * o, z); + assert_eq!(z * t, z); + assert_eq!(o * t, t); + assert_eq!(t * t, f); + // div + assert_eq!(z / o, z); + assert_eq!(t / o, t); + assert_eq!(f / o, f); + assert_eq!(t / t, o); + assert_eq!(f / t, t); + // rem + assert_eq!(o % o, z); + assert_eq!(f % t, z); + + { + let mut v = z; + assert_eq!(v, z); + v += o; // add_assign + assert_eq!(v, o); + v -= o; // sub_assign + assert_eq!(v, z); + v = t; + v *= o; // mul_assign + assert_eq!(v, t); + v *= t; + assert_eq!(v, f); + v /= o; // div_assign + assert_eq!(v, f); + v /= t; + assert_eq!(v, t); + v %= t; // rem_assign + assert_eq!(v, z); + } + } + } + } + } + }; +} diff --git a/vendor/packed_simd/src/api/ops/vector_bitwise.rs b/vendor/packed_simd/src/api/ops/vector_bitwise.rs new file mode 100644 index 000000000..7be9603fa --- /dev/null +++ b/vendor/packed_simd/src/api/ops/vector_bitwise.rs @@ -0,0 +1,129 @@ +//! Vertical (lane-wise) vector-vector bitwise operations. + +macro_rules! impl_ops_vector_bitwise { + ( + [$elem_ty:ident; $elem_count:expr]: + $id:ident | $test_tt:tt | + ($true:expr, $false:expr) + ) => { + impl crate::ops::Not for $id { + type Output = Self; + #[inline] + fn not(self) -> Self { + Self::splat($true) ^ self + } + } + impl crate::ops::BitXor for $id { + type Output = Self; + #[inline] + fn bitxor(self, other: Self) -> Self { + use crate::llvm::simd_xor; + unsafe { Simd(simd_xor(self.0, other.0)) } + } + } + impl crate::ops::BitAnd for $id { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + use crate::llvm::simd_and; + unsafe { Simd(simd_and(self.0, other.0)) } + } + } + impl crate::ops::BitOr for $id { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + use crate::llvm::simd_or; + unsafe { Simd(simd_or(self.0, other.0)) } + } + } + impl crate::ops::BitAndAssign for $id { + #[inline] + fn bitand_assign(&mut self, other: Self) { + *self = *self & other; + } + } + impl crate::ops::BitOrAssign for $id { + #[inline] + fn bitor_assign(&mut self, other: Self) { + *self = *self | other; + } + } + impl crate::ops::BitXorAssign for $id { + #[inline] + fn bitxor_assign(&mut self, other: Self) { + *self = *self ^ other; + } + } + + test_if!{ + $test_tt: + paste::item! { + pub mod [<$id _ops_vector_bitwise>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn ops_vector_bitwise() { + + let z = $id::splat(0 as $elem_ty); + let o = $id::splat(1 as $elem_ty); + let t = $id::splat(2 as $elem_ty); + let m = $id::splat(!z.extract(0)); + + // Not: + assert_eq!(!z, m); + assert_eq!(!m, z); + + // BitAnd: + assert_eq!(o & o, o); + assert_eq!(o & z, z); + assert_eq!(z & o, z); + assert_eq!(z & z, z); + + assert_eq!(t & t, t); + assert_eq!(t & o, z); + assert_eq!(o & t, z); + + // BitOr: + assert_eq!(o | o, o); + assert_eq!(o | z, o); + assert_eq!(z | o, o); + assert_eq!(z | z, z); + + assert_eq!(t | t, t); + assert_eq!(z | t, t); + assert_eq!(t | z, t); + + // BitXOR: + assert_eq!(o ^ o, z); + assert_eq!(z ^ z, z); + assert_eq!(z ^ o, o); + assert_eq!(o ^ z, o); + + assert_eq!(t ^ t, z); + assert_eq!(t ^ z, t); + assert_eq!(z ^ t, t); + + { + // AndAssign: + let mut v = o; + v &= t; + assert_eq!(v, z); + } + { + // OrAssign: + let mut v = z; + v |= o; + assert_eq!(v, o); + } + { + // XORAssign: + let mut v = z; + v ^= o; + assert_eq!(v, o); + } + } + } + } + } + }; +} diff --git a/vendor/packed_simd/src/api/ops/vector_float_min_max.rs b/vendor/packed_simd/src/api/ops/vector_float_min_max.rs new file mode 100644 index 000000000..8310667b7 --- /dev/null +++ b/vendor/packed_simd/src/api/ops/vector_float_min_max.rs @@ -0,0 +1,74 @@ +//! Vertical (lane-wise) vector `min` and `max` for floating-point vectors. + +macro_rules! impl_ops_vector_float_min_max { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { + impl $id { + /// Minimum of two vectors. + /// + /// Returns a new vector containing the minimum value of each of + /// the input vector lanes. + #[inline] + pub fn min(self, x: Self) -> Self { + use crate::llvm::simd_fmin; + unsafe { Simd(simd_fmin(self.0, x.0)) } + } + + /// Maximum of two vectors. + /// + /// Returns a new vector containing the maximum value of each of + /// the input vector lanes. + #[inline] + pub fn max(self, x: Self) -> Self { + use crate::llvm::simd_fmax; + unsafe { Simd(simd_fmax(self.0, x.0)) } + } + } + test_if!{ + $test_tt: + paste::item! { + #[cfg(not(any( + // FIXME: https://github.com/rust-lang-nursery/packed_simd/issues/223 + all(target_arch = "mips", target_endian = "big"), + target_arch = "mips64", + )))] + pub mod [<$id _ops_vector_min_max>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn min_max() { + let n = crate::$elem_ty::NAN; + let o = $id::splat(1. as $elem_ty); + let t = $id::splat(2. as $elem_ty); + + let mut m = o; // [1., 2., 1., 2., ...] + let mut on = o; + for i in 0..$id::lanes() { + if i % 2 == 0 { + m = m.replace(i, 2. as $elem_ty); + on = on.replace(i, n); + } + } + + assert_eq!(o.min(t), o); + assert_eq!(t.min(o), o); + assert_eq!(m.min(o), o); + assert_eq!(o.min(m), o); + assert_eq!(m.min(t), m); + assert_eq!(t.min(m), m); + + assert_eq!(o.max(t), t); + assert_eq!(t.max(o), t); + assert_eq!(m.max(o), m); + assert_eq!(o.max(m), m); + assert_eq!(m.max(t), t); + assert_eq!(t.max(m), t); + + assert_eq!(on.min(o), o); + assert_eq!(o.min(on), o); + assert_eq!(on.max(o), o); + assert_eq!(o.max(on), o); + } + } + } + } + }; +} diff --git a/vendor/packed_simd/src/api/ops/vector_int_min_max.rs b/vendor/packed_simd/src/api/ops/vector_int_min_max.rs new file mode 100644 index 000000000..36ea98e6b --- /dev/null +++ b/vendor/packed_simd/src/api/ops/vector_int_min_max.rs @@ -0,0 +1,57 @@ +//! Vertical (lane-wise) vector `min` and `max` for integer vectors. + +macro_rules! impl_ops_vector_int_min_max { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { + impl $id { + /// Minimum of two vectors. + /// + /// Returns a new vector containing the minimum value of each of + /// the input vector lanes. + #[inline] + pub fn min(self, x: Self) -> Self { + self.lt(x).select(self, x) + } + + /// Maximum of two vectors. + /// + /// Returns a new vector containing the maximum value of each of + /// the input vector lanes. + #[inline] + pub fn max(self, x: Self) -> Self { + self.gt(x).select(self, x) + } + } + test_if!{$test_tt: + paste::item! { + pub mod [<$id _ops_vector_min_max>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn min_max() { + let o = $id::splat(1 as $elem_ty); + let t = $id::splat(2 as $elem_ty); + + let mut m = o; + for i in 0..$id::lanes() { + if i % 2 == 0 { + m = m.replace(i, 2 as $elem_ty); + } + } + assert_eq!(o.min(t), o); + assert_eq!(t.min(o), o); + assert_eq!(m.min(o), o); + assert_eq!(o.min(m), o); + assert_eq!(m.min(t), m); + assert_eq!(t.min(m), m); + + assert_eq!(o.max(t), t); + assert_eq!(t.max(o), t); + assert_eq!(m.max(o), m); + assert_eq!(o.max(m), m); + assert_eq!(m.max(t), t); + assert_eq!(t.max(m), t); + } + } + } + } + }; +} diff --git a/vendor/packed_simd/src/api/ops/vector_mask_bitwise.rs b/vendor/packed_simd/src/api/ops/vector_mask_bitwise.rs new file mode 100644 index 000000000..295fc1ca8 --- /dev/null +++ b/vendor/packed_simd/src/api/ops/vector_mask_bitwise.rs @@ -0,0 +1,116 @@ +//! Vertical (lane-wise) vector-vector bitwise operations. + +macro_rules! impl_ops_vector_mask_bitwise { + ( + [$elem_ty:ident; $elem_count:expr]: + $id:ident | $test_tt:tt | + ($true:expr, $false:expr) + ) => { + impl crate::ops::Not for $id { + type Output = Self; + #[inline] + fn not(self) -> Self { + Self::splat($true) ^ self + } + } + impl crate::ops::BitXor for $id { + type Output = Self; + #[inline] + fn bitxor(self, other: Self) -> Self { + use crate::llvm::simd_xor; + unsafe { Simd(simd_xor(self.0, other.0)) } + } + } + impl crate::ops::BitAnd for $id { + type Output = Self; + #[inline] + fn bitand(self, other: Self) -> Self { + use crate::llvm::simd_and; + unsafe { Simd(simd_and(self.0, other.0)) } + } + } + impl crate::ops::BitOr for $id { + type Output = Self; + #[inline] + fn bitor(self, other: Self) -> Self { + use crate::llvm::simd_or; + unsafe { Simd(simd_or(self.0, other.0)) } + } + } + impl crate::ops::BitAndAssign for $id { + #[inline] + fn bitand_assign(&mut self, other: Self) { + *self = *self & other; + } + } + impl crate::ops::BitOrAssign for $id { + #[inline] + fn bitor_assign(&mut self, other: Self) { + *self = *self | other; + } + } + impl crate::ops::BitXorAssign for $id { + #[inline] + fn bitxor_assign(&mut self, other: Self) { + *self = *self ^ other; + } + } + + test_if!{ + $test_tt: + paste::item! { + pub mod [<$id _ops_vector_mask_bitwise>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn ops_vector_mask_bitwise() { + let t = $id::splat(true); + let f = $id::splat(false); + assert!(t != f); + assert!(!(t == f)); + + // Not: + assert_eq!(!t, f); + assert_eq!(t, !f); + + // BitAnd: + assert_eq!(t & f, f); + assert_eq!(f & t, f); + assert_eq!(t & t, t); + assert_eq!(f & f, f); + + // BitOr: + assert_eq!(t | f, t); + assert_eq!(f | t, t); + assert_eq!(t | t, t); + assert_eq!(f | f, f); + + // BitXOR: + assert_eq!(t ^ f, t); + assert_eq!(f ^ t, t); + assert_eq!(t ^ t, f); + assert_eq!(f ^ f, f); + + { + // AndAssign: + let mut v = f; + v &= t; + assert_eq!(v, f); + } + { + // OrAssign: + let mut v = f; + v |= t; + assert_eq!(v, t); + } + { + // XORAssign: + let mut v = f; + v ^= t; + assert_eq!(v, t); + } + } + } + } + } + }; +} diff --git a/vendor/packed_simd/src/api/ops/vector_neg.rs b/vendor/packed_simd/src/api/ops/vector_neg.rs new file mode 100644 index 000000000..e2d91fd2f --- /dev/null +++ b/vendor/packed_simd/src/api/ops/vector_neg.rs @@ -0,0 +1,43 @@ +//! Vertical (lane-wise) vector `Neg`. + +macro_rules! impl_ops_vector_neg { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { + impl crate::ops::Neg for $id { + type Output = Self; + #[inline] + fn neg(self) -> Self { + Self::splat(-1 as $elem_ty) * self + } + } + test_if!{ + $test_tt: + paste::item! { + pub mod [<$id _ops_vector_neg>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn neg() { + let z = $id::splat(0 as $elem_ty); + let o = $id::splat(1 as $elem_ty); + let t = $id::splat(2 as $elem_ty); + let f = $id::splat(4 as $elem_ty); + + let nz = $id::splat(-(0 as $elem_ty)); + let no = $id::splat(-(1 as $elem_ty)); + let nt = $id::splat(-(2 as $elem_ty)); + let nf = $id::splat(-(4 as $elem_ty)); + + assert_eq!(-z, nz); + assert_eq!(-o, no); + assert_eq!(-t, nt); + assert_eq!(-f, nf); + + assert_eq!(z, -nz); + assert_eq!(o, -no); + assert_eq!(t, -nt); + assert_eq!(f, -nf); + } + } + } + } + }; +} diff --git a/vendor/packed_simd/src/api/ops/vector_rotates.rs b/vendor/packed_simd/src/api/ops/vector_rotates.rs new file mode 100644 index 000000000..6c4bed72a --- /dev/null +++ b/vendor/packed_simd/src/api/ops/vector_rotates.rs @@ -0,0 +1,92 @@ +//! Vertical (lane-wise) vector rotates operations. +#![allow(unused)] + +macro_rules! impl_ops_vector_rotates { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { + impl $id { + /// Shifts the bits of each lane to the left by the specified + /// amount in the corresponding lane of `n`, wrapping the + /// truncated bits to the end of the resulting integer. + /// + /// Note: this is neither the same operation as `<<` nor equivalent + /// to `slice::rotate_left`. + #[inline] + pub fn rotate_left(self, n: $id) -> $id { + const LANE_WIDTH: $elem_ty = + crate::mem::size_of::<$elem_ty>() as $elem_ty * 8; + // Protect against undefined behavior for over-long bit shifts + let n = n % LANE_WIDTH; + (self << n) | (self >> ((LANE_WIDTH - n) % LANE_WIDTH)) + } + + /// Shifts the bits of each lane to the right by the specified + /// amount in the corresponding lane of `n`, wrapping the + /// truncated bits to the beginning of the resulting integer. + /// + /// Note: this is neither the same operation as `>>` nor equivalent + /// to `slice::rotate_right`. + #[inline] + pub fn rotate_right(self, n: $id) -> $id { + const LANE_WIDTH: $elem_ty = + crate::mem::size_of::<$elem_ty>() as $elem_ty * 8; + // Protect against undefined behavior for over-long bit shifts + let n = n % LANE_WIDTH; + (self >> n) | (self << ((LANE_WIDTH - n) % LANE_WIDTH)) + } + } + + test_if!{ + $test_tt: + paste::item! { + // FIXME: + // https://github.com/rust-lang-nursery/packed_simd/issues/75 + #[cfg(not(any( + target_arch = "s390x", + target_arch = "sparc64", + )))] + pub mod [<$id _ops_vector_rotate>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg(not(target_arch = "aarch64"))] + //~^ FIXME: https://github.com/rust-lang/packed_simd/issues/317 + fn rotate_ops() { + let z = $id::splat(0 as $elem_ty); + let o = $id::splat(1 as $elem_ty); + let t = $id::splat(2 as $elem_ty); + let f = $id::splat(4 as $elem_ty); + + let max = $id::splat( + (mem::size_of::<$elem_ty>() * 8 - 1) as $elem_ty); + + // rotate_right + assert_eq!(z.rotate_right(z), z); + assert_eq!(z.rotate_right(o), z); + assert_eq!(z.rotate_right(t), z); + + assert_eq!(o.rotate_right(z), o); + assert_eq!(t.rotate_right(z), t); + assert_eq!(f.rotate_right(z), f); + assert_eq!(f.rotate_right(max), f << 1); + + assert_eq!(o.rotate_right(o), o << max); + assert_eq!(t.rotate_right(o), o); + assert_eq!(t.rotate_right(t), o << max); + assert_eq!(f.rotate_right(o), t); + assert_eq!(f.rotate_right(t), o); + + // rotate_left + assert_eq!(z.rotate_left(z), z); + assert_eq!(o.rotate_left(z), o); + assert_eq!(t.rotate_left(z), t); + assert_eq!(f.rotate_left(z), f); + assert_eq!(f.rotate_left(max), t); + + assert_eq!(o.rotate_left(o), t); + assert_eq!(o.rotate_left(t), f); + assert_eq!(t.rotate_left(o), f); + } + } + } + } + }; +} diff --git a/vendor/packed_simd/src/api/ops/vector_shifts.rs b/vendor/packed_simd/src/api/ops/vector_shifts.rs new file mode 100644 index 000000000..8bb5ac2fc --- /dev/null +++ b/vendor/packed_simd/src/api/ops/vector_shifts.rs @@ -0,0 +1,106 @@ +//! Vertical (lane-wise) vector-vector shifts operations. + +macro_rules! impl_ops_vector_shifts { + ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { + impl crate::ops::Shl<$id> for $id { + type Output = Self; + #[inline] + fn shl(self, other: Self) -> Self { + use crate::llvm::simd_shl; + unsafe { Simd(simd_shl(self.0, other.0)) } + } + } + impl crate::ops::Shr<$id> for $id { + type Output = Self; + #[inline] + fn shr(self, other: Self) -> Self { + use crate::llvm::simd_shr; + unsafe { Simd(simd_shr(self.0, other.0)) } + } + } + impl crate::ops::ShlAssign<$id> for $id { + #[inline] + fn shl_assign(&mut self, other: Self) { + *self = *self << other; + } + } + impl crate::ops::ShrAssign<$id> for $id { + #[inline] + fn shr_assign(&mut self, other: Self) { + *self = *self >> other; + } + } + test_if!{ + $test_tt: + paste::item! { + pub mod [<$id _ops_vector_shifts>] { + use super::*; + #[cfg_attr(not(target_arch = "wasm32"), test)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[cfg_attr(any(target_arch = "s390x", target_arch = "sparc64"), + allow(unreachable_code, unused_variables) + )] + #[cfg(not(target_arch = "aarch64"))] + //~^ FIXME: https://github.com/rust-lang/packed_simd/issues/317 + fn ops_vector_shifts() { + let z = $id::splat(0 as $elem_ty); + let o = $id::splat(1 as $elem_ty); + let t = $id::splat(2 as $elem_ty); + let f = $id::splat(4 as $elem_ty); + + let max =$id::splat( + (mem::size_of::<$elem_ty>() * 8 - 1) as $elem_ty + ); + + // shr + assert_eq!(z >> z, z); + assert_eq!(z >> o, z); + assert_eq!(z >> t, z); + assert_eq!(z >> t, z); + + #[cfg(any(target_arch = "s390x", target_arch = "sparc64"))] { + // FIXME: rust produces bad codegen for shifts: + // https://github.com/rust-lang-nursery/packed_simd/issues/13 + return; + } + + assert_eq!(o >> z, o); + assert_eq!(t >> z, t); + assert_eq!(f >> z, f); + assert_eq!(f >> max, z); + + assert_eq!(o >> o, z); + assert_eq!(t >> o, o); + assert_eq!(t >> t, z); + assert_eq!(f >> o, t); + assert_eq!(f >> t, o); + assert_eq!(f >> max, z); + + // shl + assert_eq!(z << z, z); + assert_eq!(o << z, o); + assert_eq!(t << z, t); + assert_eq!(f << z, f); + assert_eq!(f << max, z); + + assert_eq!(o << o, t); + assert_eq!(o << t, f); + assert_eq!(t << o, f); + + { + // shr_assign + let mut v = o; + v >>= o; + assert_eq!(v, z); + } + { + // shl_assign + let mut v = o; + v <<= o; + assert_eq!(v, t); + } + } + } + } + } + }; +} |