From 11c3eefa3594055192612d0d6f844e764dcbda15 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sun, 6 Feb 2022 03:25:27 +0000 Subject: [PATCH] Manually implement for supported lanes --- crates/core_simd/src/masks/bitmask.rs | 5 +- crates/core_simd/src/masks/full_masks.rs | 6 +- crates/core_simd/src/masks/to_bitmask.rs | 84 +++++++++--------------- 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 @@ pub unsafe fn from_int_unchecked(value: Simd) -> Self { } #[inline] - pub unsafe fn to_bitmask_intrinsic(self) -> U { + pub unsafe fn to_bitmask_integer(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(bitmask: U) -> Self { + pub unsafe fn from_bitmask_integer(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 @@ pub fn convert(self) -> Mask } #[inline] - pub unsafe fn to_bitmask_intrinsic(self) -> U { + pub unsafe fn to_bitmask_integer(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(bitmask: U) -> Self { + pub unsafe fn from_bitmask_integer(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 { +/// 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 ToBitMask<$int> for Mask { - 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 for Mask<_, 8> - unsafe impl ToBitMask for Mask<_, 16> - unsafe impl ToBitMask for Mask<_, 32> - unsafe impl ToBitMask 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 for Mask<_, $lanes:literal>)* } => { $( - impl ToBitMask<$int> for Mask { + impl ToBitMask for Mask { + 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 for Mask<_, 8> - impl ToBitMask for Mask<_, 8> - impl ToBitMask for Mask<_, 8> - - impl ToBitMask for Mask<_, 16> - impl ToBitMask for Mask<_, 16> - - impl ToBitMask for Mask<_, 32> -} - -#[cfg(target_pointer_width = "32")] -impl_integer_via! { - impl ToBitMask for Mask<_, 8> - impl ToBitMask for Mask<_, 16> - impl ToBitMask for Mask<_, 32> -} - -#[cfg(target_pointer_width = "64")] -impl_integer_via! { - impl ToBitMask for Mask<_, 8> - impl ToBitMask for Mask<_, 16> - impl ToBitMask for Mask<_, 32> - impl ToBitMask for Mask<_, 64> +impl_integer_intrinsic! { + unsafe impl ToBitMask for Mask<_, 8> + unsafe impl ToBitMask for Mask<_, 16> + unsafe impl ToBitMask for Mask<_, 32> + unsafe impl ToBitMask 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 @@ fn roundtrip_bitmask_conversion() { 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); } -- 2.44.0