diff --git a/crates/core_simd/src/elements.rs b/crates/core_simd/src/elements.rs new file mode 100644 index 00000000000..0fb1f5b9fe9 --- /dev/null +++ b/crates/core_simd/src/elements.rs @@ -0,0 +1,5 @@ +mod int; +mod uint; + +pub use int::*; +pub use uint::*; diff --git a/crates/core_simd/src/elements/int.rs b/crates/core_simd/src/elements/int.rs new file mode 100644 index 00000000000..61135427456 --- /dev/null +++ b/crates/core_simd/src/elements/int.rs @@ -0,0 +1,273 @@ +use crate::simd::{ + intrinsics, LaneCount, Mask, Simd, SimdElement, SimdPartialOrd, SupportedLaneCount, +}; + +/// Operations on SIMD vectors of signed integers. +pub trait SimdInt: Sized { + /// Mask type used for manipulating this SIMD vector type. + type Mask; + + /// Scalar type contained by this SIMD vector type. + type Scalar; + + /// Lanewise saturating add. + /// + /// # Examples + /// ``` + /// # #![feature(portable_simd)] + /// # use core::simd::Simd; + /// use core::i32::{MIN, MAX}; + /// let x = Simd::from_array([MIN, 0, 1, MAX]); + /// let max = Simd::splat(MAX); + /// let unsat = x + max; + /// let sat = x.saturating_add(max); + /// assert_eq!(unsat, Simd::from_array([-1, MAX, MIN, -2])); + /// assert_eq!(sat, Simd::from_array([-1, MAX, MAX, MAX])); + /// ``` + fn saturating_add(self, second: Self) -> Self; + + /// Lanewise saturating subtract. + /// + /// # Examples + /// ``` + /// # #![feature(portable_simd)] + /// # use core::simd::Simd; + /// use core::i32::{MIN, MAX}; + /// let x = Simd::from_array([MIN, -2, -1, MAX]); + /// let max = Simd::splat(MAX); + /// let unsat = x - max; + /// let sat = x.saturating_sub(max); + /// assert_eq!(unsat, Simd::from_array([1, MAX, MIN, 0])); + /// assert_eq!(sat, Simd::from_array([MIN, MIN, MIN, 0])); + fn saturating_sub(self, second: Self) -> Self; + + /// Lanewise absolute value, implemented in Rust. + /// Every lane becomes its absolute value. + /// + /// # Examples + /// ``` + /// # #![feature(portable_simd)] + /// # use core::simd::Simd; + /// use core::i32::{MIN, MAX}; + /// let xs = Simd::from_array([MIN, MIN +1, -5, 0]); + /// assert_eq!(xs.abs(), Simd::from_array([MIN, MAX, 5, 0])); + /// ``` + fn abs(self) -> Self; + + /// Lanewise saturating absolute value, implemented in Rust. + /// As abs(), except the MIN value becomes MAX instead of itself. + /// + /// # Examples + /// ``` + /// # #![feature(portable_simd)] + /// # use core::simd::Simd; + /// use core::i32::{MIN, MAX}; + /// let xs = Simd::from_array([MIN, -2, 0, 3]); + /// let unsat = xs.abs(); + /// let sat = xs.saturating_abs(); + /// assert_eq!(unsat, Simd::from_array([MIN, 2, 0, 3])); + /// assert_eq!(sat, Simd::from_array([MAX, 2, 0, 3])); + /// ``` + fn saturating_abs(self) -> Self; + + /// Lanewise saturating negation, implemented in Rust. + /// As neg(), except the MIN value becomes MAX instead of itself. + /// + /// # Examples + /// ``` + /// # #![feature(portable_simd)] + /// # use core::simd::Simd; + /// use core::i32::{MIN, MAX}; + /// let x = Simd::from_array([MIN, -2, 3, MAX]); + /// let unsat = -x; + /// let sat = x.saturating_neg(); + /// assert_eq!(unsat, Simd::from_array([MIN, 2, -3, MIN + 1])); + /// assert_eq!(sat, Simd::from_array([MAX, 2, -3, MIN + 1])); + /// ``` + fn saturating_neg(self) -> Self; + + /// Returns true for each positive lane and false if it is zero or negative. + fn is_positive(self) -> Self::Mask; + + /// Returns true for each negative lane and false if it is zero or positive. + fn is_negative(self) -> Self::Mask; + + /// Returns numbers representing the sign of each lane. + /// * `0` if the number is zero + /// * `1` if the number is positive + /// * `-1` if the number is negative + fn signum(self) -> Self; + + /// Returns the sum of the lanes of the vector, with wrapping addition. + /// + /// # Examples + /// + /// ``` + /// # #![feature(portable_simd)] + /// # use core::simd::i32x4; + /// let v = i32x4::from_array([1, 2, 3, 4]); + /// assert_eq!(v.reduce_sum(), 10); + /// + /// // SIMD integer addition is always wrapping + /// let v = i32x4::from_array([i32::MAX, 1, 0, 0]); + /// assert_eq!(v.reduce_sum(), i32::MIN); + /// ``` + fn reduce_sum(self) -> Self::Scalar; + + /// Returns the product of the lanes of the vector, with wrapping multiplication. + /// + /// # Examples + /// + /// ``` + /// # #![feature(portable_simd)] + /// # use core::simd::i32x4; + /// let v = i32x4::from_array([1, 2, 3, 4]); + /// assert_eq!(v.reduce_product(), 24); + /// + /// // SIMD integer multiplication is always wrapping + /// let v = i32x4::from_array([i32::MAX, 2, 1, 1]); + /// assert!(v.reduce_product() < i32::MAX); + /// ``` + fn reduce_product(self) -> Self::Scalar; + + /// Returns the maximum lane in the vector. + /// + /// # Examples + /// + /// ``` + /// # #![feature(portable_simd)] + /// # use core::simd::i32x4; + /// let v = i32x4::from_array([1, 2, 3, 4]); + /// assert_eq!(v.reduce_max(), 4); + /// ``` + fn reduce_max(self) -> Self::Scalar; + + /// Returns the minimum lane in the vector. + /// + /// # Examples + /// + /// ``` + /// # #![feature(portable_simd)] + /// # use core::simd::i32x4; + /// let v = i32x4::from_array([1, 2, 3, 4]); + /// assert_eq!(v.reduce_min(), 1); + /// ``` + fn reduce_min(self) -> Self::Scalar; + + /// Returns the cumulative bitwise "and" across the lanes of the vector. + fn reduce_and(self) -> Self::Scalar; + + /// Returns the cumulative bitwise "or" across the lanes of the vector. + fn reduce_or(self) -> Self::Scalar; + + /// Returns the cumulative bitwise "xor" across the lanes of the vector. + fn reduce_xor(self) -> Self::Scalar; +} + +macro_rules! impl_trait { + { $($ty:ty),* } => { + $( + impl SimdInt for Simd<$ty, LANES> + where + LaneCount: SupportedLaneCount, + { + type Mask = Mask<<$ty as SimdElement>::Mask, LANES>; + type Scalar = $ty; + + #[inline] + fn saturating_add(self, second: Self) -> Self { + // Safety: `self` is a vector + unsafe { intrinsics::simd_saturating_add(self, second) } + } + + #[inline] + fn saturating_sub(self, second: Self) -> Self { + // Safety: `self` is a vector + unsafe { intrinsics::simd_saturating_sub(self, second) } + } + + #[inline] + fn abs(self) -> Self { + const SHR: $ty = <$ty>::BITS as $ty - 1; + let m = self >> Simd::splat(SHR); + (self^m) - m + } + + #[inline] + fn saturating_abs(self) -> Self { + // arith shift for -1 or 0 mask based on sign bit, giving 2s complement + const SHR: $ty = <$ty>::BITS as $ty - 1; + let m = self >> Simd::splat(SHR); + (self^m).saturating_sub(m) + } + + #[inline] + fn saturating_neg(self) -> Self { + Self::splat(0).saturating_sub(self) + } + + #[inline] + fn is_positive(self) -> Self::Mask { + self.simd_gt(Self::splat(0)) + } + + #[inline] + fn is_negative(self) -> Self::Mask { + self.simd_lt(Self::splat(0)) + } + + #[inline] + fn signum(self) -> Self { + self.is_positive().select( + Self::splat(1), + self.is_negative().select(Self::splat(-1), Self::splat(0)) + ) + } + + #[inline] + fn reduce_sum(self) -> Self::Scalar { + // Safety: `self` is an integer vector + unsafe { intrinsics::simd_reduce_add_ordered(self, 0) } + } + + #[inline] + fn reduce_product(self) -> Self::Scalar { + // Safety: `self` is an integer vector + unsafe { intrinsics::simd_reduce_mul_ordered(self, 1) } + } + + #[inline] + fn reduce_max(self) -> Self::Scalar { + // Safety: `self` is an integer vector + unsafe { intrinsics::simd_reduce_max(self) } + } + + #[inline] + fn reduce_min(self) -> Self::Scalar { + // Safety: `self` is an integer vector + unsafe { intrinsics::simd_reduce_min(self) } + } + + #[inline] + fn reduce_and(self) -> Self::Scalar { + // Safety: `self` is an integer vector + unsafe { intrinsics::simd_reduce_and(self) } + } + + #[inline] + fn reduce_or(self) -> Self::Scalar { + // Safety: `self` is an integer vector + unsafe { intrinsics::simd_reduce_or(self) } + } + + #[inline] + fn reduce_xor(self) -> Self::Scalar { + // Safety: `self` is an integer vector + unsafe { intrinsics::simd_reduce_xor(self) } + } + } + )* + } +} + +impl_trait! { i8, i16, i32, i64, isize } diff --git a/crates/core_simd/src/elements/uint.rs b/crates/core_simd/src/elements/uint.rs new file mode 100644 index 00000000000..da3213535a3 --- /dev/null +++ b/crates/core_simd/src/elements/uint.rs @@ -0,0 +1,128 @@ +use crate::simd::{intrinsics, LaneCount, Simd, SupportedLaneCount}; + +/// Operations on SIMD vectors of unsigned integers. +pub trait SimdUint: Sized { + /// Scalar type contained by this SIMD vector type. + type Scalar; + + /// Lanewise saturating add. + /// + /// # Examples + /// ``` + /// # #![feature(portable_simd)] + /// # use core::simd::Simd; + /// use core::u32::MAX; + /// let x = Simd::from_array([2, 1, 0, MAX]); + /// let max = Simd::splat(MAX); + /// let unsat = x + max; + /// let sat = x.saturating_add(max); + /// assert_eq!(unsat, Simd::from_array([1, 0, MAX, MAX - 1])); + /// assert_eq!(sat, max); + /// ``` + fn saturating_add(self, second: Self) -> Self; + + /// Lanewise saturating subtract. + /// + /// # Examples + /// ``` + /// # #![feature(portable_simd)] + /// # use core::simd::Simd; + /// use core::u32::MAX; + /// let x = Simd::from_array([2, 1, 0, MAX]); + /// let max = Simd::splat(MAX); + /// let unsat = x - max; + /// let sat = x.saturating_sub(max); + /// assert_eq!(unsat, Simd::from_array([3, 2, 1, 0])); + /// assert_eq!(sat, Simd::splat(0)); + fn saturating_sub(self, second: Self) -> Self; + + /// Returns the sum of the lanes of the vector, with wrapping addition. + fn reduce_sum(self) -> Self::Scalar; + + /// Returns the product of the lanes of the vector, with wrapping multiplication. + fn reduce_product(self) -> Self::Scalar; + + /// Returns the maximum lane in the vector. + fn reduce_max(self) -> Self::Scalar; + + /// Returns the minimum lane in the vector. + fn reduce_min(self) -> Self::Scalar; + + /// Returns the cumulative bitwise "and" across the lanes of the vector. + fn reduce_and(self) -> Self::Scalar; + + /// Returns the cumulative bitwise "or" across the lanes of the vector. + fn reduce_or(self) -> Self::Scalar; + + /// Returns the cumulative bitwise "xor" across the lanes of the vector. + fn reduce_xor(self) -> Self::Scalar; +} + +macro_rules! impl_trait { + { $($ty:ty),* } => { + $( + impl SimdUint for Simd<$ty, LANES> + where + LaneCount: SupportedLaneCount, + { + type Scalar = $ty; + + #[inline] + fn saturating_add(self, second: Self) -> Self { + // Safety: `self` is a vector + unsafe { intrinsics::simd_saturating_add(self, second) } + } + + #[inline] + fn saturating_sub(self, second: Self) -> Self { + // Safety: `self` is a vector + unsafe { intrinsics::simd_saturating_sub(self, second) } + } + + #[inline] + fn reduce_sum(self) -> Self::Scalar { + // Safety: `self` is an integer vector + unsafe { intrinsics::simd_reduce_add_ordered(self, 0) } + } + + #[inline] + fn reduce_product(self) -> Self::Scalar { + // Safety: `self` is an integer vector + unsafe { intrinsics::simd_reduce_mul_ordered(self, 1) } + } + + #[inline] + fn reduce_max(self) -> Self::Scalar { + // Safety: `self` is an integer vector + unsafe { intrinsics::simd_reduce_max(self) } + } + + #[inline] + fn reduce_min(self) -> Self::Scalar { + // Safety: `self` is an integer vector + unsafe { intrinsics::simd_reduce_min(self) } + } + + #[inline] + fn reduce_and(self) -> Self::Scalar { + // Safety: `self` is an integer vector + unsafe { intrinsics::simd_reduce_and(self) } + } + + #[inline] + fn reduce_or(self) -> Self::Scalar { + // Safety: `self` is an integer vector + unsafe { intrinsics::simd_reduce_or(self) } + } + + #[inline] + fn reduce_xor(self) -> Self::Scalar { + // Safety: `self` is an integer vector + unsafe { intrinsics::simd_reduce_xor(self) } + } + } + )* + } +} + +impl_trait! { u8, u16, u32, u64, usize } diff --git a/crates/core_simd/src/math.rs b/crates/core_simd/src/math.rs deleted file mode 100644 index 606021e983e..00000000000 --- a/crates/core_simd/src/math.rs +++ /dev/null @@ -1,156 +0,0 @@ -use crate::simd::intrinsics::{simd_saturating_add, simd_saturating_sub}; -use crate::simd::{LaneCount, Simd, SupportedLaneCount}; - -macro_rules! impl_uint_arith { - ($($ty:ty),+) => { - $( impl Simd<$ty, LANES> where LaneCount: SupportedLaneCount { - - /// Lanewise saturating add. - /// - /// # Examples - /// ``` - /// # #![feature(portable_simd)] - /// # use core::simd::Simd; - #[doc = concat!("# use core::", stringify!($ty), "::MAX;")] - /// let x = Simd::from_array([2, 1, 0, MAX]); - /// let max = Simd::splat(MAX); - /// let unsat = x + max; - /// let sat = x.saturating_add(max); - /// assert_eq!(unsat, Simd::from_array([1, 0, MAX, MAX - 1])); - /// assert_eq!(sat, max); - /// ``` - #[inline] - pub fn saturating_add(self, second: Self) -> Self { - // Safety: `self` is a vector - unsafe { simd_saturating_add(self, second) } - } - - /// Lanewise saturating subtract. - /// - /// # Examples - /// ``` - /// # #![feature(portable_simd)] - /// # use core::simd::Simd; - #[doc = concat!("# use core::", stringify!($ty), "::MAX;")] - /// let x = Simd::from_array([2, 1, 0, MAX]); - /// let max = Simd::splat(MAX); - /// let unsat = x - max; - /// let sat = x.saturating_sub(max); - /// assert_eq!(unsat, Simd::from_array([3, 2, 1, 0])); - /// assert_eq!(sat, Simd::splat(0)); - #[inline] - pub fn saturating_sub(self, second: Self) -> Self { - // Safety: `self` is a vector - unsafe { simd_saturating_sub(self, second) } - } - })+ - } -} - -macro_rules! impl_int_arith { - ($($ty:ty),+) => { - $( impl Simd<$ty, LANES> where LaneCount: SupportedLaneCount { - - /// Lanewise saturating add. - /// - /// # Examples - /// ``` - /// # #![feature(portable_simd)] - /// # use core::simd::Simd; - #[doc = concat!("# use core::", stringify!($ty), "::{MIN, MAX};")] - /// let x = Simd::from_array([MIN, 0, 1, MAX]); - /// let max = Simd::splat(MAX); - /// let unsat = x + max; - /// let sat = x.saturating_add(max); - /// assert_eq!(unsat, Simd::from_array([-1, MAX, MIN, -2])); - /// assert_eq!(sat, Simd::from_array([-1, MAX, MAX, MAX])); - /// ``` - #[inline] - pub fn saturating_add(self, second: Self) -> Self { - // Safety: `self` is a vector - unsafe { simd_saturating_add(self, second) } - } - - /// Lanewise saturating subtract. - /// - /// # Examples - /// ``` - /// # #![feature(portable_simd)] - /// # use core::simd::Simd; - #[doc = concat!("# use core::", stringify!($ty), "::{MIN, MAX};")] - /// let x = Simd::from_array([MIN, -2, -1, MAX]); - /// let max = Simd::splat(MAX); - /// let unsat = x - max; - /// let sat = x.saturating_sub(max); - /// assert_eq!(unsat, Simd::from_array([1, MAX, MIN, 0])); - /// assert_eq!(sat, Simd::from_array([MIN, MIN, MIN, 0])); - #[inline] - pub fn saturating_sub(self, second: Self) -> Self { - // Safety: `self` is a vector - unsafe { simd_saturating_sub(self, second) } - } - - /// Lanewise absolute value, implemented in Rust. - /// Every lane becomes its absolute value. - /// - /// # Examples - /// ``` - /// # #![feature(portable_simd)] - /// # use core::simd::Simd; - #[doc = concat!("# use core::", stringify!($ty), "::{MIN, MAX};")] - /// let xs = Simd::from_array([MIN, MIN +1, -5, 0]); - /// assert_eq!(xs.abs(), Simd::from_array([MIN, MAX, 5, 0])); - /// ``` - #[inline] - pub fn abs(self) -> Self { - const SHR: $ty = <$ty>::BITS as $ty - 1; - let m = self >> Simd::splat(SHR); - (self^m) - m - } - - /// Lanewise saturating absolute value, implemented in Rust. - /// As abs(), except the MIN value becomes MAX instead of itself. - /// - /// # Examples - /// ``` - /// # #![feature(portable_simd)] - /// # use core::simd::Simd; - #[doc = concat!("# use core::", stringify!($ty), "::{MIN, MAX};")] - /// let xs = Simd::from_array([MIN, -2, 0, 3]); - /// let unsat = xs.abs(); - /// let sat = xs.saturating_abs(); - /// assert_eq!(unsat, Simd::from_array([MIN, 2, 0, 3])); - /// assert_eq!(sat, Simd::from_array([MAX, 2, 0, 3])); - /// ``` - #[inline] - pub fn saturating_abs(self) -> Self { - // arith shift for -1 or 0 mask based on sign bit, giving 2s complement - const SHR: $ty = <$ty>::BITS as $ty - 1; - let m = self >> Simd::splat(SHR); - (self^m).saturating_sub(m) - } - - /// Lanewise saturating negation, implemented in Rust. - /// As neg(), except the MIN value becomes MAX instead of itself. - /// - /// # Examples - /// ``` - /// # #![feature(portable_simd)] - /// # use core::simd::Simd; - #[doc = concat!("# use core::", stringify!($ty), "::{MIN, MAX};")] - /// let x = Simd::from_array([MIN, -2, 3, MAX]); - /// let unsat = -x; - /// let sat = x.saturating_neg(); - /// assert_eq!(unsat, Simd::from_array([MIN, 2, -3, MIN + 1])); - /// assert_eq!(sat, Simd::from_array([MAX, 2, -3, MIN + 1])); - /// ``` - #[inline] - pub fn saturating_neg(self) -> Self { - Self::splat(0).saturating_sub(self) - } - })+ - } -} - -impl_uint_arith! { u8, u16, u32, u64, usize } -impl_int_arith! { i8, i16, i32, i64, isize } diff --git a/crates/core_simd/src/mod.rs b/crates/core_simd/src/mod.rs index 42257f4e119..2d4fe2b7fde 100644 --- a/crates/core_simd/src/mod.rs +++ b/crates/core_simd/src/mod.rs @@ -9,12 +9,12 @@ pub(crate) mod intrinsics; #[cfg(feature = "generic_const_exprs")] mod to_bytes; +mod elements; mod eq; mod fmt; mod iter; mod lane_count; mod masks; -mod math; mod ops; mod ord; mod round; @@ -26,6 +26,7 @@ mod vendor; pub mod simd { pub(crate) use crate::core_simd::intrinsics; + pub use crate::core_simd::elements::*; pub use crate::core_simd::eq::*; pub use crate::core_simd::lane_count::{LaneCount, SupportedLaneCount}; pub use crate::core_simd::masks::*; diff --git a/crates/core_simd/src/reduction.rs b/crates/core_simd/src/reduction.rs index 642ab319cdd..9d8639feeee 100644 --- a/crates/core_simd/src/reduction.rs +++ b/crates/core_simd/src/reduction.rs @@ -1,105 +1,7 @@ use crate::simd::intrinsics::{ - simd_reduce_add_ordered, simd_reduce_and, simd_reduce_max, simd_reduce_min, - simd_reduce_mul_ordered, simd_reduce_or, simd_reduce_xor, + simd_reduce_add_ordered, simd_reduce_max, simd_reduce_min, simd_reduce_mul_ordered, }; -use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount}; -use core::ops::{BitAnd, BitOr, BitXor}; - -macro_rules! impl_integer_reductions { - { $scalar:ty } => { - impl Simd<$scalar, LANES> - where - LaneCount: SupportedLaneCount, - { - /// Reducing wrapping add. Returns the sum of the lanes of the vector, with wrapping addition. - /// - /// # Examples - /// - /// ``` - /// # #![feature(portable_simd)] - /// # use core::simd::Simd; - #[doc = concat!("# use core::simd::", stringify!($scalar), "x4;")] - #[doc = concat!("let v = ", stringify!($scalar), "x4::from_array([1, 2, 3, 4]);")] - /// assert_eq!(v.reduce_sum(), 10); - /// - /// // SIMD integer addition is always wrapping - #[doc = concat!("let v = ", stringify!($scalar), "x4::from_array([", stringify!($scalar) ,"::MAX, 1, 0, 0]);")] - #[doc = concat!("assert_eq!(v.reduce_sum(), ", stringify!($scalar), "::MIN);")] - /// ``` - #[inline] - pub fn reduce_sum(self) -> $scalar { - // Safety: `self` is an integer vector - unsafe { simd_reduce_add_ordered(self, 0) } - } - - /// Reducing wrapping multiply. Returns the product of the lanes of the vector, with wrapping multiplication. - /// - /// # Examples - /// - /// ``` - /// # #![feature(portable_simd)] - /// # use core::simd::Simd; - #[doc = concat!("# use core::simd::", stringify!($scalar), "x4;")] - #[doc = concat!("let v = ", stringify!($scalar), "x4::from_array([1, 2, 3, 4]);")] - /// assert_eq!(v.reduce_product(), 24); - /// - /// // SIMD integer multiplication is always wrapping - #[doc = concat!("let v = ", stringify!($scalar), "x4::from_array([", stringify!($scalar) ,"::MAX, 2, 1, 1]);")] - #[doc = concat!("assert!(v.reduce_product() < ", stringify!($scalar), "::MAX);")] - /// ``` - #[inline] - pub fn reduce_product(self) -> $scalar { - // Safety: `self` is an integer vector - unsafe { simd_reduce_mul_ordered(self, 1) } - } - - /// Reducing maximum. Returns the maximum lane in the vector. - /// - /// # Examples - /// - /// ``` - /// # #![feature(portable_simd)] - /// # use core::simd::Simd; - #[doc = concat!("# use core::simd::", stringify!($scalar), "x4;")] - #[doc = concat!("let v = ", stringify!($scalar), "x4::from_array([1, 2, 3, 4]);")] - /// assert_eq!(v.reduce_max(), 4); - /// ``` - #[inline] - pub fn reduce_max(self) -> $scalar { - // Safety: `self` is an integer vector - unsafe { simd_reduce_max(self) } - } - - /// Reducing minimum. Returns the minimum lane in the vector. - /// - /// # Examples - /// - /// ``` - /// # #![feature(portable_simd)] - /// # use core::simd::Simd; - #[doc = concat!("# use core::simd::", stringify!($scalar), "x4;")] - #[doc = concat!("let v = ", stringify!($scalar), "x4::from_array([1, 2, 3, 4]);")] - /// assert_eq!(v.reduce_min(), 1); - /// ``` - #[inline] - pub fn reduce_min(self) -> $scalar { - // Safety: `self` is an integer vector - unsafe { simd_reduce_min(self) } - } - } - } -} - -impl_integer_reductions! { i8 } -impl_integer_reductions! { i16 } -impl_integer_reductions! { i32 } -impl_integer_reductions! { i64 } -impl_integer_reductions! { isize } -impl_integer_reductions! { u8 } -impl_integer_reductions! { u16 } -impl_integer_reductions! { u32 } -impl_integer_reductions! { u64 } -impl_integer_reductions! { usize } +use crate::simd::{LaneCount, Simd, SupportedLaneCount}; macro_rules! impl_float_reductions { { $scalar:ty } => { @@ -223,45 +125,3 @@ macro_rules! impl_float_reductions { impl_float_reductions! { f32 } impl_float_reductions! { f64 } - -impl Simd -where - Self: BitAnd, - T: SimdElement + BitAnd, - LaneCount: SupportedLaneCount, -{ - /// Reducing bitwise "and". Returns the cumulative bitwise "and" across the lanes of - /// the vector. - #[inline] - pub fn reduce_and(self) -> T { - unsafe { simd_reduce_and(self) } - } -} - -impl Simd -where - Self: BitOr, - T: SimdElement + BitOr, - LaneCount: SupportedLaneCount, -{ - /// Reducing bitwise "or". Returns the cumulative bitwise "or" across the lanes of - /// the vector. - #[inline] - pub fn reduce_or(self) -> T { - unsafe { simd_reduce_or(self) } - } -} - -impl Simd -where - Self: BitXor, - T: SimdElement + BitXor, - LaneCount: SupportedLaneCount, -{ - /// Reducing bitwise "xor". Returns the cumulative bitwise "xor" across the lanes of - /// the vector. - #[inline] - pub fn reduce_xor(self) -> T { - unsafe { simd_reduce_xor(self) } - } -} diff --git a/crates/core_simd/src/vector/int.rs b/crates/core_simd/src/vector/int.rs index 384f01d822a..20e56c7dc64 100644 --- a/crates/core_simd/src/vector/int.rs +++ b/crates/core_simd/src/vector/int.rs @@ -1,46 +1,6 @@ #![allow(non_camel_case_types)] -use crate::simd::{LaneCount, Mask, Simd, SimdPartialOrd, SupportedLaneCount}; - -/// Implements additional integer traits (Eq, Ord, Hash) on the specified vector `$name`, holding multiple `$lanes` of `$type`. -macro_rules! impl_integer_vector { - { $type:ty } => { - impl Simd<$type, LANES> - where - LaneCount: SupportedLaneCount, - { - /// Returns true for each positive lane and false if it is zero or negative. - #[inline] - pub fn is_positive(self) -> Mask<$type, LANES> { - self.simd_gt(Self::splat(0)) - } - - /// Returns true for each negative lane and false if it is zero or positive. - #[inline] - pub fn is_negative(self) -> Mask<$type, LANES> { - self.simd_lt(Self::splat(0)) - } - - /// Returns numbers representing the sign of each lane. - /// * `0` if the number is zero - /// * `1` if the number is positive - /// * `-1` if the number is negative - #[inline] - pub fn signum(self) -> Self { - self.is_positive().select( - Self::splat(1), - self.is_negative().select(Self::splat(-1), Self::splat(0)) - ) - } - } - } -} - -impl_integer_vector! { isize } -impl_integer_vector! { i16 } -impl_integer_vector! { i32 } -impl_integer_vector! { i64 } -impl_integer_vector! { i8 } +use crate::simd::Simd; /// A SIMD vector with two elements of type `isize`. pub type isizex2 = Simd; diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs index 47fe49b0982..48c512be7d0 100644 --- a/crates/core_simd/tests/ops_macros.rs +++ b/crates/core_simd/tests/ops_macros.rs @@ -172,6 +172,7 @@ macro_rules! impl_common_integer_tests { macro_rules! impl_signed_tests { { $scalar:tt } => { mod $scalar { + use core_simd::simd::SimdInt; type Vector = core_simd::Simd; type Scalar = $scalar; @@ -312,6 +313,7 @@ macro_rules! impl_signed_tests { macro_rules! impl_unsigned_tests { { $scalar:tt } => { mod $scalar { + use core_simd::simd::SimdUint; type Vector = core_simd::Simd; type Scalar = $scalar;