where
Self: crate::LanesAtMost32
{
- /// Produces the sum of the lanes of the vector, with wrapping addition.
+ /// Horizontal wrapping add. Returns the sum of the lanes of the vector, with wrapping addition.
#[inline]
- pub fn wrapping_sum(self) -> $scalar {
+ pub fn horizontal_sum(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_add_ordered(self, 0) }
}
- /// Produces the sum of the lanes of the vector, with wrapping multiplication.
+ /// Horizontal wrapping multiply. Returns the product of the lanes of the vector, with wrapping multiplication.
#[inline]
- pub fn wrapping_product(self) -> $scalar {
+ pub fn horizontal_product(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_mul_ordered(self, 1) }
}
- /// Sequentially performs bitwise "and" between the lanes of the vector.
+ /// Horizontal bitwise "and". Returns the cumulative bitwise "and" across the lanes of
+ /// the vector.
#[inline]
- pub fn and_lanes(self) -> $scalar {
+ pub fn horizontal_and(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_and(self) }
}
- /// Sequentially performs bitwise "or" between the lanes of the vector.
+ /// Horizontal bitwise "or". Returns the cumulative bitwise "or" across the lanes of
+ /// the vector.
#[inline]
- pub fn or_lanes(self) -> $scalar {
+ pub fn horizontal_or(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_or(self) }
}
- /// Sequentially performs bitwise "xor" between the lanes of the vector.
+ /// Horizontal bitwise "xor". Returns the cumulative bitwise "xor" across the lanes of
+ /// the vector.
#[inline]
- pub fn xor_lanes(self) -> $scalar {
+ pub fn horizontal_xor(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_xor(self) }
}
- /// Returns the maximum lane in the vector.
+ /// Horizontal maximum. Returns the maximum lane in the vector.
#[inline]
- pub fn max_lane(self) -> $scalar {
+ pub fn horizontal_max(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_max(self) }
}
- /// Returns the minimum lane in the vector.
+ /// Horizontal minimum. Returns the minimum lane in the vector.
#[inline]
- pub fn min_lane(self) -> $scalar {
+ pub fn horizontal_min(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_min(self) }
}
}
where
Self: crate::LanesAtMost32
{
- /// Produces the sum of the lanes of the vector.
+
+ /// Horizontal add. Returns the sum of the lanes of the vector.
#[inline]
- pub fn sum(self) -> $scalar {
- unsafe { crate::intrinsics::simd_reduce_add_ordered(self, 0.) }
+ pub fn horizontal_sum(self) -> $scalar {
+ // LLVM sum is inaccurate on i586
+ if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) {
+ self.as_slice().iter().sum()
+ } else {
+ unsafe { crate::intrinsics::simd_reduce_add_ordered(self, 0.) }
+ }
}
- /// Produces the sum of the lanes of the vector.
+ /// Horizontal multiply. Returns the product of the lanes of the vector.
#[inline]
- pub fn product(self) -> $scalar {
- unsafe { crate::intrinsics::simd_reduce_mul_ordered(self, 1.) }
+ pub fn horizontal_product(self) -> $scalar {
+ // LLVM product is inaccurate on i586
+ if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) {
+ self.as_slice().iter().product()
+ } else {
+ unsafe { crate::intrinsics::simd_reduce_mul_ordered(self, 1.) }
+ }
}
- /// Returns the maximum lane in the vector.
+ /// Horizontal maximum. Returns the maximum lane in the vector.
+ ///
+ /// Returns values based on equality, so a vector containing both `0.` and `-0.` may
+ /// return either. This function will not return `NaN` unless all lanes are `NaN`.
#[inline]
- pub fn max_lane(self) -> $scalar {
+ pub fn horizontal_max(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_max(self) }
}
- /// Returns the minimum lane in the vector.
+ /// Horizontal minimum. Returns the minimum lane in the vector.
+ ///
+ /// Returns values based on equality, so a vector containing both `0.` and `-0.` may
+ /// return either. This function will not return `NaN` unless all lanes are `NaN`.
#[inline]
- pub fn min_lane(self) -> $scalar {
+ pub fn horizontal_min(self) -> $scalar {
unsafe { crate::intrinsics::simd_reduce_min(self) }
}
}
}
macro_rules! impl_full_mask_reductions {
- { $name:ident, $inner:ident } => {
- impl<const LANES: usize> crate::$name<LANES>
+ { $name:ident, $bits_ty:ident } => {
+ impl<const LANES: usize> $name<LANES>
where
- crate::$inner<LANES>: crate::LanesAtMost32
+ crate::$bits_ty<LANES>: crate::LanesAtMost32
{
- /// Returns true if any lane is set, or false otherwise.
#[inline]
pub fn any(self) -> bool {
unsafe { crate::intrinsics::simd_reduce_any(self.to_int()) }
}
- /// Returns true if all lanes are set, or false otherwise.
#[inline]
pub fn all(self) -> bool {
unsafe { crate::intrinsics::simd_reduce_all(self.to_int()) }
}
macro_rules! impl_opaque_mask_reductions {
- { $name:ident, $inner:ident, $bits_ty:ident } => {
+ { $name:ident, $bits_ty:ident } => {
impl<const LANES: usize> $name<LANES>
where
- $bits_ty<LANES>: crate::LanesAtMost32
+ crate::$bits_ty<LANES>: crate::LanesAtMost32
{
/// Returns true if any lane is set, or false otherwise.
#[inline]
}
}
}
-
-impl<const LANES: usize> crate::BitMask<LANES>
-where
- crate::BitMask<LANES>: crate::LanesAtMost32,
-{
- /// Returns true if any lane is set, or false otherwise.
- #[inline]
- pub fn any(self) -> bool {
- self.0 != 0
- }
-
- /// Returns true if all lanes are set, or false otherwise.
- #[inline]
- pub fn all(self) -> bool {
- self.0 == (!0) >> (64 - LANES)
- }
-}