Change bitmasks to use less opaque type
This commit is contained in:
parent
9ab050796f
commit
cca9102429
@ -6,9 +6,14 @@ use sealed::Sealed;
|
|||||||
/// A type representing a vector lane count.
|
/// A type representing a vector lane count.
|
||||||
pub struct LaneCount<const LANES: usize>;
|
pub struct LaneCount<const LANES: usize>;
|
||||||
|
|
||||||
|
impl<const LANES: usize> LaneCount<LANES> {
|
||||||
|
/// The number of bytes in a bitmask with this many lanes.
|
||||||
|
pub const BITMASK_LEN: usize = (LANES + 7) / 8;
|
||||||
|
}
|
||||||
|
|
||||||
/// Helper trait for vector lane counts.
|
/// Helper trait for vector lane counts.
|
||||||
pub trait SupportedLaneCount: Sealed {
|
pub trait SupportedLaneCount: Sealed {
|
||||||
/// The bitmask representation of a mask.
|
#[doc(hidden)]
|
||||||
type BitMask: Copy + Default + AsRef<[u8]> + AsMut<[u8]>;
|
type BitMask: Copy + Default + AsRef<[u8]> + AsMut<[u8]>;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -160,12 +160,12 @@ macro_rules! define_opaque_mask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Convert this mask to a bitmask, with one bit set per lane.
|
/// Convert this mask to a bitmask, with one bit set per lane.
|
||||||
pub fn to_bitmask(self) -> <crate::LaneCount<LANES> as crate::SupportedLaneCount>::BitMask {
|
pub fn to_bitmask(self) -> [u8; crate::LaneCount::<LANES>::BITMASK_LEN] {
|
||||||
self.0.to_bitmask()
|
self.0.to_bitmask()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a bitmask to a mask.
|
/// Convert a bitmask to a mask.
|
||||||
pub fn from_bitmask(bitmask: <crate::LaneCount<LANES> as crate::SupportedLaneCount>::BitMask) -> Self {
|
pub fn from_bitmask(bitmask: [u8; crate::LaneCount::<LANES>::BITMASK_LEN]) -> Self {
|
||||||
Self(<$inner_ty>::from_bitmask(bitmask))
|
Self(<$inner_ty>::from_bitmask(bitmask))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,13 +128,15 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_bitmask(self) -> <LaneCount<LANES> as SupportedLaneCount>::BitMask {
|
pub fn to_bitmask(self) -> [u8; LaneCount::<LANES>::BITMASK_LEN] {
|
||||||
self.0
|
// Safety: these are the same type and we are laundering the generic
|
||||||
|
unsafe { core::mem::transmute_copy(&self.0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_bitmask(bitmask: <LaneCount<LANES> as SupportedLaneCount>::BitMask) -> Self {
|
pub fn from_bitmask(bitmask: [u8; LaneCount::<LANES>::BITMASK_LEN]) -> Self {
|
||||||
Self(bitmask)
|
// Safety: these are the same type and we are laundering the generic
|
||||||
|
Self(unsafe { core::mem::transmute_copy(&bitmask) })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -103,15 +103,15 @@ macro_rules! define_mask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_bitmask(self) -> <crate::LaneCount::<LANES> as crate::SupportedLaneCount>::BitMask {
|
pub fn to_bitmask(self) -> [u8; crate::LaneCount::<LANES>::BITMASK_LEN] {
|
||||||
unsafe {
|
unsafe {
|
||||||
// TODO remove the transmute when rustc can use arrays of u8 as bitmasks
|
// TODO remove the transmute when rustc can use arrays of u8 as bitmasks
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
core::mem::size_of::<<crate::LaneCount::<LANES> as crate::SupportedLaneCount>::BitMask>(),
|
|
||||||
core::mem::size_of::<<crate::LaneCount::<LANES> as crate::SupportedLaneCount>::IntBitMask>(),
|
core::mem::size_of::<<crate::LaneCount::<LANES> as crate::SupportedLaneCount>::IntBitMask>(),
|
||||||
|
crate::LaneCount::<LANES>::BITMASK_LEN,
|
||||||
);
|
);
|
||||||
let bitmask: <crate::LaneCount::<LANES> as crate::SupportedLaneCount>::IntBitMask = crate::intrinsics::simd_bitmask(self.0);
|
let bitmask: <crate::LaneCount::<LANES> as crate::SupportedLaneCount>::IntBitMask = crate::intrinsics::simd_bitmask(self.0);
|
||||||
let mut bitmask: <crate::LaneCount::<LANES> as crate::SupportedLaneCount>::BitMask = core::mem::transmute_copy(&bitmask);
|
let mut bitmask: [u8; crate::LaneCount::<LANES>::BITMASK_LEN] = core::mem::transmute_copy(&bitmask);
|
||||||
|
|
||||||
// There is a bug where LLVM appears to implement this operation with the wrong
|
// There is a bug where LLVM appears to implement this operation with the wrong
|
||||||
// bit order.
|
// bit order.
|
||||||
@ -127,7 +127,7 @@ macro_rules! define_mask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_bitmask(mut bitmask: <crate::LaneCount::<LANES> as crate::SupportedLaneCount>::BitMask) -> Self {
|
pub fn from_bitmask(mut bitmask: [u8; crate::LaneCount::<LANES>::BITMASK_LEN]) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
// There is a bug where LLVM appears to implement this operation with the wrong
|
// There is a bug where LLVM appears to implement this operation with the wrong
|
||||||
// bit order.
|
// bit order.
|
||||||
@ -140,8 +140,8 @@ macro_rules! define_mask {
|
|||||||
|
|
||||||
// TODO remove the transmute when rustc can use arrays of u8 as bitmasks
|
// TODO remove the transmute when rustc can use arrays of u8 as bitmasks
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
core::mem::size_of::<<crate::LaneCount::<LANES> as crate::SupportedLaneCount>::BitMask>(),
|
|
||||||
core::mem::size_of::<<crate::LaneCount::<LANES> as crate::SupportedLaneCount>::IntBitMask>(),
|
core::mem::size_of::<<crate::LaneCount::<LANES> as crate::SupportedLaneCount>::IntBitMask>(),
|
||||||
|
crate::LaneCount::<LANES>::BITMASK_LEN,
|
||||||
);
|
);
|
||||||
let bitmask: <crate::LaneCount::<LANES> as crate::SupportedLaneCount>::IntBitMask = core::mem::transmute_copy(&bitmask);
|
let bitmask: <crate::LaneCount::<LANES> as crate::SupportedLaneCount>::IntBitMask = core::mem::transmute_copy(&bitmask);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user