1 //! Types and traits associated with masking lanes of vectors.
3 #![allow(non_camel_case_types)]
5 #[cfg_attr(not(all(target_arch = "x86_64", target_feature = "avx512f")), path = "full_masks.rs")]
6 #[cfg_attr(all(target_arch = "x86_64", target_feature = "avx512f"), path = "bitmask.rs")]
9 use crate::{LanesAtMost32, SimdI16, SimdI32, SimdI64, SimdI8, SimdIsize};
11 macro_rules! define_opaque_mask {
14 struct $name:ident<const $lanes:ident: usize>($inner_ty:ty);
18 #[allow(non_camel_case_types)]
19 pub struct $name<const LANES: usize>($inner_ty) where $bits_ty<LANES>: LanesAtMost32;
21 impl_opaque_mask_reductions! { $name, $bits_ty }
23 impl<const LANES: usize> $name<LANES>
25 $bits_ty<LANES>: LanesAtMost32
27 /// Construct a mask by setting all lanes to the given value.
28 pub fn splat(value: bool) -> Self {
29 Self(<$inner_ty>::splat(value))
32 /// Converts an array to a SIMD vector.
33 pub fn from_array(array: [bool; LANES]) -> Self {
34 let mut vector = Self::splat(false);
37 vector.set(i, array[i]);
43 /// Converts a SIMD vector to an array.
44 pub fn to_array(self) -> [bool; LANES] {
45 let mut array = [false; LANES];
48 array[i] = self.test(i);
54 /// Converts a vector of integers to a mask, where 0 represents `false` and -1
55 /// represents `true`.
58 /// All lanes must be either 0 or -1.
60 pub unsafe fn from_int_unchecked(value: $bits_ty<LANES>) -> Self {
61 Self(<$inner_ty>::from_int_unchecked(value))
64 /// Tests the value of the specified lane.
67 /// Panics if `lane` is greater than or equal to the number of lanes in the vector.
69 pub fn test(&self, lane: usize) -> bool {
73 /// Sets the value of the specified lane.
76 /// Panics if `lane` is greater than or equal to the number of lanes in the vector.
78 pub fn set(&mut self, lane: usize, value: bool) {
79 self.0.set(lane, value);
83 // vector/array conversion
84 impl<const LANES: usize> From<[bool; LANES]> for $name<LANES>
86 $bits_ty<LANES>: crate::LanesAtMost32
88 fn from(array: [bool; LANES]) -> Self {
89 Self::from_array(array)
93 impl <const LANES: usize> From<$name<LANES>> for [bool; LANES]
95 $bits_ty<LANES>: crate::LanesAtMost32
97 fn from(vector: $name<LANES>) -> Self {
102 impl<const LANES: usize> Copy for $name<LANES>
105 $bits_ty<LANES>: LanesAtMost32,
108 impl<const LANES: usize> Clone for $name<LANES>
110 $bits_ty<LANES>: LanesAtMost32,
113 fn clone(&self) -> Self {
118 impl<const LANES: usize> Default for $name<LANES>
120 $bits_ty<LANES>: LanesAtMost32,
123 fn default() -> Self {
128 impl<const LANES: usize> PartialEq for $name<LANES>
130 $bits_ty<LANES>: LanesAtMost32,
133 fn eq(&self, other: &Self) -> bool {
138 impl<const LANES: usize> PartialOrd for $name<LANES>
140 $bits_ty<LANES>: LanesAtMost32,
143 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
144 self.0.partial_cmp(&other.0)
148 impl<const LANES: usize> core::fmt::Debug for $name<LANES>
150 $bits_ty<LANES>: LanesAtMost32,
152 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
153 core::fmt::Debug::fmt(&self.0, f)
157 impl<const LANES: usize> core::ops::BitAnd for $name<LANES>
159 $bits_ty<LANES>: LanesAtMost32,
163 fn bitand(self, rhs: Self) -> Self {
168 impl<const LANES: usize> core::ops::BitAnd<bool> for $name<LANES>
170 $bits_ty<LANES>: LanesAtMost32,
174 fn bitand(self, rhs: bool) -> Self {
175 self & Self::splat(rhs)
179 impl<const LANES: usize> core::ops::BitAnd<$name<LANES>> for bool
181 $bits_ty<LANES>: LanesAtMost32,
183 type Output = $name<LANES>;
185 fn bitand(self, rhs: $name<LANES>) -> $name<LANES> {
186 $name::<LANES>::splat(self) & rhs
190 impl<const LANES: usize> core::ops::BitOr for $name<LANES>
192 $bits_ty<LANES>: LanesAtMost32,
196 fn bitor(self, rhs: Self) -> Self {
201 impl<const LANES: usize> core::ops::BitOr<bool> for $name<LANES>
203 $bits_ty<LANES>: LanesAtMost32,
207 fn bitor(self, rhs: bool) -> Self {
208 self | Self::splat(rhs)
212 impl<const LANES: usize> core::ops::BitOr<$name<LANES>> for bool
214 $bits_ty<LANES>: LanesAtMost32,
216 type Output = $name<LANES>;
218 fn bitor(self, rhs: $name<LANES>) -> $name<LANES> {
219 $name::<LANES>::splat(self) | rhs
223 impl<const LANES: usize> core::ops::BitXor for $name<LANES>
225 $bits_ty<LANES>: LanesAtMost32,
229 fn bitxor(self, rhs: Self) -> Self::Output {
234 impl<const LANES: usize> core::ops::BitXor<bool> for $name<LANES>
236 $bits_ty<LANES>: LanesAtMost32,
240 fn bitxor(self, rhs: bool) -> Self::Output {
241 self ^ Self::splat(rhs)
245 impl<const LANES: usize> core::ops::BitXor<$name<LANES>> for bool
247 $bits_ty<LANES>: LanesAtMost32,
249 type Output = $name<LANES>;
251 fn bitxor(self, rhs: $name<LANES>) -> Self::Output {
252 $name::<LANES>::splat(self) ^ rhs
256 impl<const LANES: usize> core::ops::Not for $name<LANES>
258 $bits_ty<LANES>: LanesAtMost32,
260 type Output = $name<LANES>;
262 fn not(self) -> Self::Output {
267 impl<const LANES: usize> core::ops::BitAndAssign for $name<LANES>
269 $bits_ty<LANES>: LanesAtMost32,
272 fn bitand_assign(&mut self, rhs: Self) {
277 impl<const LANES: usize> core::ops::BitAndAssign<bool> for $name<LANES>
279 $bits_ty<LANES>: LanesAtMost32,
282 fn bitand_assign(&mut self, rhs: bool) {
283 *self &= Self::splat(rhs);
287 impl<const LANES: usize> core::ops::BitOrAssign for $name<LANES>
289 $bits_ty<LANES>: LanesAtMost32,
292 fn bitor_assign(&mut self, rhs: Self) {
297 impl<const LANES: usize> core::ops::BitOrAssign<bool> for $name<LANES>
299 $bits_ty<LANES>: LanesAtMost32,
302 fn bitor_assign(&mut self, rhs: bool) {
303 *self |= Self::splat(rhs);
307 impl<const LANES: usize> core::ops::BitXorAssign for $name<LANES>
309 $bits_ty<LANES>: LanesAtMost32,
312 fn bitxor_assign(&mut self, rhs: Self) {
317 impl<const LANES: usize> core::ops::BitXorAssign<bool> for $name<LANES>
319 $bits_ty<LANES>: LanesAtMost32,
322 fn bitxor_assign(&mut self, rhs: bool) {
323 *self ^= Self::splat(rhs);
329 define_opaque_mask! {
330 /// Mask for vectors with `LANES` 8-bit elements.
332 /// The layout of this type is unspecified.
333 struct Mask8<const LANES: usize>(mask_impl::Mask8<LANES>);
337 define_opaque_mask! {
338 /// Mask for vectors with `LANES` 16-bit elements.
340 /// The layout of this type is unspecified.
341 struct Mask16<const LANES: usize>(mask_impl::Mask16<LANES>);
345 define_opaque_mask! {
346 /// Mask for vectors with `LANES` 32-bit elements.
348 /// The layout of this type is unspecified.
349 struct Mask32<const LANES: usize>(mask_impl::Mask32<LANES>);
353 define_opaque_mask! {
354 /// Mask for vectors with `LANES` 64-bit elements.
356 /// The layout of this type is unspecified.
357 struct Mask64<const LANES: usize>(mask_impl::Mask64<LANES>);
361 define_opaque_mask! {
362 /// Mask for vectors with `LANES` pointer-width elements.
364 /// The layout of this type is unspecified.
365 struct MaskSize<const LANES: usize>(mask_impl::MaskSize<LANES>);
369 /// Vector of eight 8-bit masks
370 pub type mask8x8 = Mask8<8>;
372 /// Vector of 16 8-bit masks
373 pub type mask8x16 = Mask8<16>;
375 /// Vector of 32 8-bit masks
376 pub type mask8x32 = Mask8<32>;
378 /// Vector of 16 8-bit masks
379 pub type mask8x64 = Mask8<64>;
381 /// Vector of four 16-bit masks
382 pub type mask16x4 = Mask16<4>;
384 /// Vector of eight 16-bit masks
385 pub type mask16x8 = Mask16<8>;
387 /// Vector of 16 16-bit masks
388 pub type mask16x16 = Mask16<16>;
390 /// Vector of 32 16-bit masks
391 pub type mask16x32 = Mask32<32>;
393 /// Vector of two 32-bit masks
394 pub type mask32x2 = Mask32<2>;
396 /// Vector of four 32-bit masks
397 pub type mask32x4 = Mask32<4>;
399 /// Vector of eight 32-bit masks
400 pub type mask32x8 = Mask32<8>;
402 /// Vector of 16 32-bit masks
403 pub type mask32x16 = Mask32<16>;
405 /// Vector of two 64-bit masks
406 pub type mask64x2 = Mask64<2>;
408 /// Vector of four 64-bit masks
409 pub type mask64x4 = Mask64<4>;
411 /// Vector of eight 64-bit masks
412 pub type mask64x8 = Mask64<8>;
414 /// Vector of two pointer-width masks
415 pub type masksizex2 = MaskSize<2>;
417 /// Vector of four pointer-width masks
418 pub type masksizex4 = MaskSize<4>;
420 /// Vector of eight pointer-width masks
421 pub type masksizex8 = MaskSize<8>;