Add mask width conversion (#127)

This commit is contained in:
Caleb Zulawski 2021-06-11 18:48:05 -04:00 committed by GitHub
parent 3032a62d93
commit 68393aa594
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 82 additions and 0 deletions

View file

@ -169,3 +169,26 @@ pub type Mask16<T, const LANES: usize> = BitMask<T, LANES>;
pub type Mask32<T, const LANES: usize> = BitMask<T, LANES>;
pub type Mask64<T, const LANES: usize> = BitMask<T, LANES>;
pub type MaskSize<T, const LANES: usize> = BitMask<T, LANES>;
macro_rules! impl_from {
{ $from:ident ($from_inner:ident) => $($to:ident ($to_inner:ident)),* } => {
$(
impl<const LANES: usize> From<$from<crate::$from<LANES>, LANES>> for $to<crate::$to<LANES>, LANES>
where
crate::$from_inner<LANES>: crate::LanesAtMost32,
crate::$to_inner<LANES>: crate::LanesAtMost32,
crate::$from<LANES>: crate::Mask,
crate::$to<LANES>: crate::Mask,
{
fn from(value: $from<crate::$from<LANES>, LANES>) -> Self {
unsafe { core::mem::transmute_copy(&value) }
}
}
)*
}
}
impl_from! { Mask8 (SimdI8) => Mask16 (SimdI16), Mask32 (SimdI32), Mask64 (SimdI64), MaskSize (SimdIsize) }
impl_from! { Mask16 (SimdI16) => Mask32 (SimdI32), Mask64 (SimdI64), MaskSize (SimdIsize), Mask8 (SimdI8) }
impl_from! { Mask32 (SimdI32) => Mask64 (SimdI64), MaskSize (SimdIsize), Mask8 (SimdI8), Mask16 (SimdI16) }
impl_from! { Mask64 (SimdI64) => MaskSize (SimdIsize), Mask8 (SimdI8), Mask16 (SimdI16), Mask32 (SimdI32) }
impl_from! { MaskSize (SimdIsize) => Mask8 (SimdI8), Mask16 (SimdI16), Mask32 (SimdI32), Mask64 (SimdI64) }

View file

@ -212,3 +212,30 @@ define_mask! {
/// or unset.
struct MaskSize<const LANES: usize>(crate::SimdIsize<LANES>);
}
macro_rules! impl_from {
{ $from:ident ($from_inner:ident) => $($to:ident ($to_inner:ident)),* } => {
$(
impl<const LANES: usize, T, U> From<$from<T, LANES>> for $to<U, LANES>
where
crate::$from_inner<LANES>: crate::LanesAtMost32,
crate::$to_inner<LANES>: crate::LanesAtMost32,
T: crate::Mask,
U: crate::Mask,
{
fn from(value: $from<T, LANES>) -> Self {
let mut new = Self::splat(false);
for i in 0..LANES {
unsafe { new.set_unchecked(i, value.test_unchecked(i)) }
}
new
}
}
)*
}
}
impl_from! { Mask8 (SimdI8) => Mask16 (SimdI16), Mask32 (SimdI32), Mask64 (SimdI64), MaskSize (SimdIsize) }
impl_from! { Mask16 (SimdI16) => Mask32 (SimdI32), Mask64 (SimdI64), MaskSize (SimdIsize), Mask8 (SimdI8) }
impl_from! { Mask32 (SimdI32) => Mask64 (SimdI64), MaskSize (SimdIsize), Mask8 (SimdI8), Mask16 (SimdI16) }
impl_from! { Mask64 (SimdI64) => MaskSize (SimdIsize), Mask8 (SimdI8), Mask16 (SimdI16), Mask32 (SimdI32) }
impl_from! { MaskSize (SimdIsize) => Mask8 (SimdI8), Mask16 (SimdI16), Mask32 (SimdI32), Mask64 (SimdI64) }

View file

@ -544,3 +544,26 @@ pub type masksizex4 = MaskSize<4>;
/// Vector of eight pointer-width masks
pub type masksizex8 = MaskSize<8>;
macro_rules! impl_from {
{ $from:ident ($from_inner:ident) => $($to:ident ($to_inner:ident)),* } => {
$(
impl<const LANES: usize> From<$from<LANES>> for $to<LANES>
where
crate::$from_inner<LANES>: crate::LanesAtMost32,
crate::$to_inner<LANES>: crate::LanesAtMost32,
$from<LANES>: Mask,
Self: Mask,
{
fn from(value: $from<LANES>) -> Self {
Self(value.0.into())
}
}
)*
}
}
impl_from! { Mask8 (SimdI8) => Mask16 (SimdI16), Mask32 (SimdI32), Mask64 (SimdI64), MaskSize (SimdIsize) }
impl_from! { Mask16 (SimdI16) => Mask32 (SimdI32), Mask64 (SimdI64), MaskSize (SimdIsize), Mask8 (SimdI8) }
impl_from! { Mask32 (SimdI32) => Mask64 (SimdI64), MaskSize (SimdIsize), Mask8 (SimdI8), Mask16 (SimdI16) }
impl_from! { Mask64 (SimdI64) => MaskSize (SimdIsize), Mask8 (SimdI8), Mask16 (SimdI16), Mask32 (SimdI32) }
impl_from! { MaskSize (SimdIsize) => Mask8 (SimdI8), Mask16 (SimdI16), Mask32 (SimdI32), Mask64 (SimdI64) }

View file

@ -82,3 +82,12 @@ macro_rules! test_mask_api {
mod mask_api {
test_mask_api! { Mask8 }
}
#[test]
fn convert() {
let values = [true, false, false, true, false, false, true, false];
assert_eq!(
core_simd::Mask8::from_array(values),
core_simd::Mask32::from_array(values).into()
);
}