diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs index 7af4517226aa1..0623d2bf3d121 100644 --- a/crates/core_simd/src/masks.rs +++ b/crates/core_simd/src/masks.rs @@ -295,6 +295,16 @@ where /// /// Each bit is set if the corresponding element in the mask is `true`. /// The remaining bits are unset. + /// + /// The bits are packed into the first N bits of the vector: + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd; + /// # use simd::mask32x8; + /// let mask = mask32x8::from_array([true, false, true, false, false, false, true, false]); + /// assert_eq!(mask.to_bitmask_vector()[0], 0b01000101); + /// ``` #[inline] #[must_use = "method returns a new integer and does not mutate the original value"] pub fn to_bitmask_vector(self) -> Simd { @@ -304,6 +314,19 @@ where /// Create a mask from a bitmask vector. /// /// For each bit, if it is set, the corresponding element in the mask is set to `true`. + /// + /// The bits are packed into the first N bits of the vector: + /// ``` + /// # #![feature(portable_simd)] + /// # #[cfg(feature = "as_crate")] use core_simd::simd; + /// # #[cfg(not(feature = "as_crate"))] use core::simd; + /// # use simd::{mask32x8, u8x8}; + /// let bitmask = u8x8::from_array([0b01000101, 0, 0, 0, 0, 0, 0, 0]); + /// assert_eq!( + /// mask32x8::from_bitmask_vector(bitmask), + /// mask32x8::from_array([true, false, true, false, false, false, true, false]), + /// ); + /// ``` #[inline] #[must_use = "method returns a new mask and does not mutate the original value"] pub fn from_bitmask_vector(bitmask: Simd) -> Self { diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index 0d17e90c1289c..63964f455e05c 100644 --- a/crates/core_simd/src/masks/full_masks.rs +++ b/crates/core_simd/src/masks/full_masks.rs @@ -237,62 +237,36 @@ where #[inline] pub(crate) fn to_bitmask_integer(self) -> u64 { // TODO modify simd_bitmask to zero-extend output, making this unnecessary - macro_rules! bitmask { - { $($ty:ty: $($len:literal),*;)* } => { - match N { - $($( - // Safety: bitmask matches length - $len => unsafe { self.to_bitmask_impl::<$ty, $len>() as u64 }, - )*)* - // Safety: bitmask matches length - _ => unsafe { self.to_bitmask_impl::() }, - } - } - } - #[cfg(all_lane_counts)] - bitmask! { - u8: 1, 2, 3, 4, 5, 6, 7, 8; - u16: 9, 10, 11, 12, 13, 14, 15, 16; - u32: 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32; - u64: 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64; - } - #[cfg(not(all_lane_counts))] - bitmask! { - u8: 1, 2, 4, 8; - u16: 16; - u32: 32; - u64: 64; + if N <= 8 { + // Safety: bitmask matches length + unsafe { self.to_bitmask_impl::() as u64 } + } else if N <= 16 { + // Safety: bitmask matches length + unsafe { self.to_bitmask_impl::() as u64 } + } else if N <= 32 { + // Safety: bitmask matches length + unsafe { self.to_bitmask_impl::() as u64 } + } else { + // Safety: bitmask matches length + unsafe { self.to_bitmask_impl::() } } } #[inline] pub(crate) fn from_bitmask_integer(bitmask: u64) -> Self { // TODO modify simd_bitmask_select to truncate input, making this unnecessary - macro_rules! bitmask { - { $($ty:ty: $($len:literal),*;)* } => { - match N { - $($( - // Safety: bitmask matches length - $len => unsafe { Self::from_bitmask_impl::<$ty, $len>(bitmask as $ty) }, - )*)* - // Safety: bitmask matches length - _ => unsafe { Self::from_bitmask_impl::(bitmask) }, - } - } - } - #[cfg(all_lane_counts)] - bitmask! { - u8: 1, 2, 3, 4, 5, 6, 7, 8; - u16: 9, 10, 11, 12, 13, 14, 15, 16; - u32: 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32; - u64: 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64; - } - #[cfg(not(all_lane_counts))] - bitmask! { - u8: 1, 2, 4, 8; - u16: 16; - u32: 32; - u64: 64; + if N <= 8 { + // Safety: bitmask matches length + unsafe { Self::from_bitmask_impl::(bitmask as u8) } + } else if N <= 16 { + // Safety: bitmask matches length + unsafe { Self::from_bitmask_impl::(bitmask as u16) } + } else if N <= 32 { + // Safety: bitmask matches length + unsafe { Self::from_bitmask_impl::(bitmask as u32) } + } else { + // Safety: bitmask matches length + unsafe { Self::from_bitmask_impl::(bitmask) } } }