1 macro_rules! impl_integer_reductions {
2 { $name:ident, $scalar:ty } => {
3 impl<const LANES: usize> crate::$name<LANES>
5 Self: crate::LanesAtMost32
7 /// Produces the sum of the lanes of the vector, with wrapping addition.
9 pub fn wrapping_sum(self) -> $scalar {
10 unsafe { crate::intrinsics::simd_reduce_add_ordered(self, 0) }
13 /// Produces the sum of the lanes of the vector, with wrapping multiplication.
15 pub fn wrapping_product(self) -> $scalar {
16 unsafe { crate::intrinsics::simd_reduce_mul_ordered(self, 1) }
19 /// Sequentially performs bitwise "and" between the lanes of the vector.
21 pub fn and_lanes(self) -> $scalar {
22 unsafe { crate::intrinsics::simd_reduce_and(self) }
25 /// Sequentially performs bitwise "or" between the lanes of the vector.
27 pub fn or_lanes(self) -> $scalar {
28 unsafe { crate::intrinsics::simd_reduce_or(self) }
31 /// Sequentially performs bitwise "xor" between the lanes of the vector.
33 pub fn xor_lanes(self) -> $scalar {
34 unsafe { crate::intrinsics::simd_reduce_xor(self) }
37 /// Returns the maximum lane in the vector.
39 pub fn max_lane(self) -> $scalar {
40 unsafe { crate::intrinsics::simd_reduce_max(self) }
43 /// Returns the minimum lane in the vector.
45 pub fn min_lane(self) -> $scalar {
46 unsafe { crate::intrinsics::simd_reduce_min(self) }
52 macro_rules! impl_float_reductions {
53 { $name:ident, $scalar:ty } => {
54 impl<const LANES: usize> crate::$name<LANES>
56 Self: crate::LanesAtMost32
59 /// Produces the sum of the lanes of the vector.
61 pub fn sum(self) -> $scalar {
62 // LLVM sum is inaccurate on i586
63 if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) {
64 self.as_slice().iter().sum()
66 unsafe { crate::intrinsics::simd_reduce_add_ordered(self, 0.) }
70 /// Produces the sum of the lanes of the vector.
72 pub fn product(self) -> $scalar {
73 // LLVM product is inaccurate on i586
74 if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) {
75 self.as_slice().iter().product()
77 unsafe { crate::intrinsics::simd_reduce_mul_ordered(self, 1.) }
81 /// Returns the maximum lane in the vector.
83 /// Returns values based on equality, so a vector containing both `0.` and `-0.` may
84 /// return either. This function will not return `NaN` unless all lanes are `NaN`.
86 pub fn max_lane(self) -> $scalar {
87 unsafe { crate::intrinsics::simd_reduce_max(self) }
90 /// Returns the minimum lane in the vector.
92 /// Returns values based on equality, so a vector containing both `0.` and `-0.` may
93 /// return either. This function will not return `NaN` unless all lanes are `NaN`.
95 pub fn min_lane(self) -> $scalar {
96 unsafe { crate::intrinsics::simd_reduce_min(self) }
102 macro_rules! impl_full_mask_reductions {
103 { $name:ident, $inner:ident } => {
104 impl<const LANES: usize> crate::$name<LANES>
106 crate::$inner<LANES>: crate::LanesAtMost32
108 /// Returns true if any lane is set, or false otherwise.
110 pub fn any(self) -> bool {
111 unsafe { crate::intrinsics::simd_reduce_any(self.to_int()) }
114 /// Returns true if all lanes are set, or false otherwise.
116 pub fn all(self) -> bool {
117 unsafe { crate::intrinsics::simd_reduce_all(self.to_int()) }
123 macro_rules! impl_opaque_mask_reductions {
124 { $name:ident, $inner:ident, $bits_ty:ident } => {
125 impl<const LANES: usize> $name<LANES>
127 $bits_ty<LANES>: crate::LanesAtMost32
129 /// Returns true if any lane is set, or false otherwise.
131 pub fn any(self) -> bool {
135 /// Returns true if all lanes are set, or false otherwise.
137 pub fn all(self) -> bool {
144 impl<const LANES: usize> crate::BitMask<LANES>
146 crate::BitMask<LANES>: crate::LanesAtMost32,
148 /// Returns true if any lane is set, or false otherwise.
150 pub fn any(self) -> bool {
151 self != Self::splat(false)
154 /// Returns true if all lanes are set, or false otherwise.
156 pub fn all(self) -> bool {
157 self == Self::splat(true)