parent
57e67c905f
commit
15b4e28004
4 changed files with 42 additions and 2 deletions
|
|
@ -100,6 +100,15 @@ impl<T: Mask, const LANES: usize> BitMask<T, LANES> {
|
|||
unsafe { core::mem::transmute_copy(&self.0) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_bitmask<U: Mask>(bitmask: U::BitMask) -> Self {
|
||||
assert_eq!(
|
||||
core::mem::size_of::<T::BitMask>(),
|
||||
core::mem::size_of::<U::BitMask>()
|
||||
);
|
||||
unsafe { core::mem::transmute_copy(&bitmask) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn any(self) -> bool {
|
||||
self != Self::splat(false)
|
||||
|
|
|
|||
|
|
@ -126,6 +126,30 @@ macro_rules! define_mask {
|
|||
bitmask
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_bitmask<U: crate::Mask>(mut bitmask: U::BitMask) -> Self {
|
||||
unsafe {
|
||||
// There is a bug where LLVM appears to implement this operation with the wrong
|
||||
// bit order.
|
||||
// TODO fix this in a better way
|
||||
if cfg!(any(target_arch = "mips", target_arch = "mips64")) {
|
||||
for x in bitmask.as_mut() {
|
||||
*x = x.reverse_bits();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO remove the transmute when rustc is more flexible
|
||||
assert_eq!(core::mem::size_of::<U::IntBitMask>(), core::mem::size_of::<U::BitMask>());
|
||||
let bitmask: U::IntBitMask = core::mem::transmute_copy(&bitmask);
|
||||
|
||||
Self::from_int_unchecked(crate::intrinsics::simd_select_bitmask(
|
||||
bitmask,
|
||||
Self::splat(true).to_int(),
|
||||
Self::splat(false).to_int(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Mask, const LANES: usize> core::convert::From<$name<T, LANES>> for crate::$type<LANES>
|
||||
|
|
|
|||
|
|
@ -178,6 +178,11 @@ macro_rules! define_opaque_mask {
|
|||
pub fn to_bitmask(self) -> <Self as Mask>::BitMask {
|
||||
self.0.to_bitmask::<Self>()
|
||||
}
|
||||
|
||||
/// Convert a bitmask to a mask.
|
||||
pub fn from_bitmask(bitmask: <Self as Mask>::BitMask) -> Self {
|
||||
Self(<$inner_ty>::from_bitmask::<Self>(bitmask))
|
||||
}
|
||||
}
|
||||
|
||||
// vector/array conversion
|
||||
|
|
|
|||
|
|
@ -67,13 +67,15 @@ macro_rules! test_mask_api {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn to_bitmask() {
|
||||
fn roundtrip_bitmask_conversion() {
|
||||
let values = [
|
||||
true, false, false, true, false, false, true, false,
|
||||
true, true, false, false, false, false, false, true,
|
||||
];
|
||||
let mask = core_simd::$name::<16>::from_array(values);
|
||||
assert_eq!(mask.to_bitmask(), [0b01001001, 0b10000011]);
|
||||
let bitmask = mask.to_bitmask();
|
||||
assert_eq!(bitmask, [0b01001001, 0b10000011]);
|
||||
assert_eq!(core_simd::$name::<16>::from_bitmask(bitmask), mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue