diff options
| author | Caleb Zulawski <caleb.zulawski@gmail.com> | 2022-02-06 03:25:27 +0000 |
|---|---|---|
| committer | Jubilee Young <workingjubilee@gmail.com> | 2022-02-24 18:03:40 -0800 |
| commit | 11c3eefa3594055192612d0d6f844e764dcbda15 (patch) | |
| tree | 4147eaaccf8c9f9b4814856deaf1b6fb6f1c8e78 | |
| parent | 842ac87747c4a6f8002ada6bab04d97320d206fc (diff) | |
| download | rust-11c3eefa3594055192612d0d6f844e764dcbda15.tar.gz rust-11c3eefa3594055192612d0d6f844e764dcbda15.zip | |
Manually implement for supported lanes
| -rw-r--r-- | crates/core_simd/src/masks/bitmask.rs | 5 | ||||
| -rw-r--r-- | crates/core_simd/src/masks/full_masks.rs | 6 | ||||
| -rw-r--r-- | crates/core_simd/src/masks/to_bitmask.rs | 84 | ||||
| -rw-r--r-- | crates/core_simd/tests/masks.rs | 2 |
4 files changed, 38 insertions, 59 deletions
diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs index f20f83ecb38..e27b2689606 100644 --- a/crates/core_simd/src/masks/bitmask.rs +++ b/crates/core_simd/src/masks/bitmask.rs @@ -116,12 +116,13 @@ where } #[inline] - pub unsafe fn to_bitmask_intrinsic<U>(self) -> U { + pub unsafe fn to_bitmask_integer<U>(self) -> U { unsafe { core::mem::transmute_copy(&self.0) } } + // Safety: U must be the integer with the exact number of bits required to hold the bitmask for #[inline] - pub unsafe fn from_bitmask_intrinsic<U>(bitmask: U) -> Self { + pub unsafe fn from_bitmask_integer<U>(bitmask: U) -> Self { unsafe { Self(core::mem::transmute_copy(&bitmask), PhantomData) } } diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index b20b0a4b708..90af486a887 100644 --- a/crates/core_simd/src/masks/full_masks.rs +++ b/crates/core_simd/src/masks/full_masks.rs @@ -110,13 +110,15 @@ where } #[inline] - pub unsafe fn to_bitmask_intrinsic<U>(self) -> U { + pub unsafe fn to_bitmask_integer<U>(self) -> U { // Safety: caller must only return bitmask types unsafe { intrinsics::simd_bitmask(self.0) } } + // Safety: U must be the integer with the exact number of bits required to hold the bitmask for + // this mask #[inline] - pub unsafe fn from_bitmask_intrinsic<U>(bitmask: U) -> Self { + pub unsafe fn from_bitmask_integer<U>(bitmask: U) -> Self { // Safety: caller must only pass bitmask types unsafe { Self::from_int_unchecked(intrinsics::simd_select_bitmask( diff --git a/crates/core_simd/src/masks/to_bitmask.rs b/crates/core_simd/src/masks/to_bitmask.rs index 3a9f89f19eb..86143f2331f 100644 --- a/crates/core_simd/src/masks/to_bitmask.rs +++ b/crates/core_simd/src/masks/to_bitmask.rs @@ -1,78 +1,54 @@ use super::{mask_impl, Mask, MaskElement}; -/// Converts masks to and from bitmasks. +/// Converts masks to and from integer bitmasks. /// -/// In a bitmask, each bit represents if the corresponding lane in the mask is set. -pub trait ToBitMask<BitMask> { +/// Each bit of the bitmask corresponds to a mask lane, starting with the LSB. +pub trait ToBitMask { + /// The integer bitmask type. + type BitMask; + /// Converts a mask to a bitmask. - fn to_bitmask(self) -> BitMask; + fn to_bitmask(self) -> Self::BitMask; /// Converts a bitmask to a mask. - fn from_bitmask(bitmask: BitMask) -> Self; + fn from_bitmask(bitmask: Self::BitMask) -> Self; } -macro_rules! impl_integer_intrinsic { - { $(unsafe impl ToBitMask<$int:ty> for Mask<_, $lanes:literal>)* } => { - $( - impl<T: MaskElement> ToBitMask<$int> for Mask<T, $lanes> { - fn to_bitmask(self) -> $int { - unsafe { self.0.to_bitmask_intrinsic() } - } +/// Converts masks to and from byte array bitmasks. +/// +/// Each bit of the bitmask corresponds to a mask lane, starting with the LSB of the first byte. +pub trait ToBitMaskArray { + /// The length of the bitmask array. + const BYTES: usize; - fn from_bitmask(bitmask: $int) -> Self { - unsafe { Self(mask_impl::Mask::from_bitmask_intrinsic(bitmask)) } - } - } - )* - } -} + /// Converts a mask to a bitmask. + fn to_bitmask_array(self) -> [u8; Self::BYTES]; -impl_integer_intrinsic! { - unsafe impl ToBitMask<u8> for Mask<_, 8> - unsafe impl ToBitMask<u16> for Mask<_, 16> - unsafe impl ToBitMask<u32> for Mask<_, 32> - unsafe impl ToBitMask<u64> for Mask<_, 64> + /// Converts a bitmask to a mask. + fn from_bitmask_array(bitmask: [u8; Self::BYTES]) -> Self; } -macro_rules! impl_integer_via { - { $(impl ToBitMask<$int:ty, via $via:ty> for Mask<_, $lanes:literal>)* } => { +macro_rules! impl_integer_intrinsic { + { $(unsafe impl ToBitMask<BitMask=$int:ty> for Mask<_, $lanes:literal>)* } => { $( - impl<T: MaskElement> ToBitMask<$int> for Mask<T, $lanes> { + impl<T: MaskElement> ToBitMask for Mask<T, $lanes> { + type BitMask = $int; + fn to_bitmask(self) -> $int { - let bitmask: $via = self.to_bitmask(); - bitmask as _ + unsafe { self.0.to_bitmask_integer() } } fn from_bitmask(bitmask: $int) -> Self { - Self::from_bitmask(bitmask as $via) + unsafe { Self(mask_impl::Mask::from_bitmask_integer(bitmask)) } } } )* } } -impl_integer_via! { - impl ToBitMask<u16, via u8> for Mask<_, 8> - impl ToBitMask<u32, via u8> for Mask<_, 8> - impl ToBitMask<u64, via u8> for Mask<_, 8> - - impl ToBitMask<u32, via u16> for Mask<_, 16> - impl ToBitMask<u64, via u16> for Mask<_, 16> - - impl ToBitMask<u64, via u32> for Mask<_, 32> -} - -#[cfg(target_pointer_width = "32")] -impl_integer_via! { - impl ToBitMask<usize, via u8> for Mask<_, 8> - impl ToBitMask<usize, via u16> for Mask<_, 16> - impl ToBitMask<usize, via u32> for Mask<_, 32> -} - -#[cfg(target_pointer_width = "64")] -impl_integer_via! { - impl ToBitMask<usize, via u8> for Mask<_, 8> - impl ToBitMask<usize, via u16> for Mask<_, 16> - impl ToBitMask<usize, via u32> for Mask<_, 32> - impl ToBitMask<usize, via u64> for Mask<_, 64> +impl_integer_intrinsic! { + unsafe impl ToBitMask<BitMask=u8> for Mask<_, 8> + unsafe impl ToBitMask<BitMask=u16> for Mask<_, 16> + unsafe impl ToBitMask<BitMask=u32> for Mask<_, 32> + unsafe impl ToBitMask<BitMask=u64> for Mask<_, 64> } diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs index 965c0fa2635..3aec36ca7b7 100644 --- a/crates/core_simd/tests/masks.rs +++ b/crates/core_simd/tests/masks.rs @@ -76,7 +76,7 @@ macro_rules! test_mask_api { true, true, false, false, false, false, false, true, ]; let mask = core_simd::Mask::<$type, 16>::from_array(values); - let bitmask: u16 = mask.to_bitmask(); + let bitmask = mask.to_bitmask(); assert_eq!(bitmask, 0b1000001101001001); assert_eq!(core_simd::Mask::<$type, 16>::from_bitmask(bitmask), mask); } |
