Skip to content

Commit

Permalink
Add mask width conversion (rust-lang#127)
Browse files Browse the repository at this point in the history
  • Loading branch information
calebzulawski authored Jun 11, 2021
1 parent 3032a62 commit 68393aa
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 0 deletions.
23 changes: 23 additions & 0 deletions crates/core_simd/src/masks/bitmask.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
27 changes: 27 additions & 0 deletions crates/core_simd/src/masks/full_masks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
23 changes: 23 additions & 0 deletions crates/core_simd/src/masks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
9 changes: 9 additions & 0 deletions crates/core_simd/tests/masks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
);
}

0 comments on commit 68393aa

Please sign in to comment.