1 macro_rules! impl_integer_reductions {
2 { $name:ident, $scalar:ty } => {
3 impl<const LANES: usize> crate::$name<LANES>
5 Self: crate::LanesAtMost32
7 /// Horizontal wrapping add. Returns the sum of the lanes of the vector, with wrapping addition.
9 pub fn horizontal_sum(self) -> $scalar {
10 unsafe { crate::intrinsics::simd_reduce_add_ordered(self, 0) }
13 /// Horizontal wrapping multiply. Returns the product of the lanes of the vector, with wrapping multiplication.
15 pub fn horizontal_product(self) -> $scalar {
16 unsafe { crate::intrinsics::simd_reduce_mul_ordered(self, 1) }
19 /// Horizontal bitwise "and". Returns the cumulative bitwise "and" across the lanes of
22 pub fn horizontal_and(self) -> $scalar {
23 unsafe { crate::intrinsics::simd_reduce_and(self) }
26 /// Horizontal bitwise "or". Returns the cumulative bitwise "or" across the lanes of
29 pub fn horizontal_or(self) -> $scalar {
30 unsafe { crate::intrinsics::simd_reduce_or(self) }
33 /// Horizontal bitwise "xor". Returns the cumulative bitwise "xor" across the lanes of
36 pub fn horizontal_xor(self) -> $scalar {
37 unsafe { crate::intrinsics::simd_reduce_xor(self) }
40 /// Horizontal maximum. Returns the maximum lane in the vector.
42 pub fn horizontal_max(self) -> $scalar {
43 unsafe { crate::intrinsics::simd_reduce_max(self) }
46 /// Horizontal minimum. Returns the minimum lane in the vector.
48 pub fn horizontal_min(self) -> $scalar {
49 unsafe { crate::intrinsics::simd_reduce_min(self) }
55 macro_rules! impl_float_reductions {
56 { $name:ident, $scalar:ty } => {
57 impl<const LANES: usize> crate::$name<LANES>
59 Self: crate::LanesAtMost32
62 /// Horizontal add. Returns the sum of the lanes of the vector.
64 pub fn horizontal_sum(self) -> $scalar {
65 // LLVM sum is inaccurate on i586
66 if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) {
67 self.as_slice().iter().sum()
69 unsafe { crate::intrinsics::simd_reduce_add_ordered(self, 0.) }
73 /// Horizontal multiply. Returns the product of the lanes of the vector.
75 pub fn horizontal_product(self) -> $scalar {
76 // LLVM product is inaccurate on i586
77 if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) {
78 self.as_slice().iter().product()
80 unsafe { crate::intrinsics::simd_reduce_mul_ordered(self, 1.) }
84 /// Horizontal maximum. Returns the maximum lane in the vector.
86 /// Returns values based on equality, so a vector containing both `0.` and `-0.` may
87 /// return either. This function will not return `NaN` unless all lanes are `NaN`.
89 pub fn horizontal_max(self) -> $scalar {
90 unsafe { crate::intrinsics::simd_reduce_max(self) }
93 /// Horizontal minimum. Returns the minimum lane in the vector.
95 /// Returns values based on equality, so a vector containing both `0.` and `-0.` may
96 /// return either. This function will not return `NaN` unless all lanes are `NaN`.
98 pub fn horizontal_min(self) -> $scalar {
99 unsafe { crate::intrinsics::simd_reduce_min(self) }
105 macro_rules! impl_full_mask_reductions {
106 { $name:ident, $inner:ident } => {
107 impl<const LANES: usize> crate::$name<LANES>
109 crate::$inner<LANES>: crate::LanesAtMost32
111 /// Returns true if any lane is set, or false otherwise.
113 pub fn any(self) -> bool {
114 unsafe { crate::intrinsics::simd_reduce_any(self.to_int()) }
117 /// Returns true if all lanes are set, or false otherwise.
119 pub fn all(self) -> bool {
120 unsafe { crate::intrinsics::simd_reduce_all(self.to_int()) }
126 macro_rules! impl_opaque_mask_reductions {
127 { $name:ident, $inner:ident, $bits_ty:ident } => {
128 impl<const LANES: usize> $name<LANES>
130 $bits_ty<LANES>: crate::LanesAtMost32
132 /// Returns true if any lane is set, or false otherwise.
134 pub fn any(self) -> bool {
138 /// Returns true if all lanes are set, or false otherwise.
140 pub fn all(self) -> bool {
147 impl<const LANES: usize> crate::BitMask<LANES>
149 crate::BitMask<LANES>: crate::LanesAtMost32,
151 /// Returns true if any lane is set, or false otherwise.
153 pub fn any(self) -> bool {
154 self != Self::splat(false)
157 /// Returns true if all lanes are set, or false otherwise.
159 pub fn all(self) -> bool {
160 self == Self::splat(true)