From 68393aa594b0d3c5bfecd37d94fde5795de78771 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Fri, 11 Jun 2021 18:48:05 -0400 Subject: [PATCH] Add mask width conversion (#127) --- crates/core_simd/src/masks/bitmask.rs | 23 ++++++++++++++++++++ crates/core_simd/src/masks/full_masks.rs | 27 ++++++++++++++++++++++++ crates/core_simd/src/masks/mod.rs | 23 ++++++++++++++++++++ crates/core_simd/tests/masks.rs | 9 ++++++++ 4 files changed, 82 insertions(+) diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs index 6bcb08cf9dbb7..31c7f6e7c289b 100644 --- a/crates/core_simd/src/masks/bitmask.rs +++ b/crates/core_simd/src/masks/bitmask.rs @@ -169,3 +169,26 @@ pub type Mask16 = BitMask; pub type Mask32 = BitMask; pub type Mask64 = BitMask; pub type MaskSize = BitMask; + +macro_rules! impl_from { + { $from:ident ($from_inner:ident) => $($to:ident ($to_inner:ident)),* } => { + $( + impl From<$from, LANES>> for $to, LANES> + where + crate::$from_inner: crate::LanesAtMost32, + crate::$to_inner: crate::LanesAtMost32, + crate::$from: crate::Mask, + crate::$to: crate::Mask, + { + fn from(value: $from, 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) } diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index f89bbefba631c..c2bfa03dfc6ec 100644 --- a/crates/core_simd/src/masks/full_masks.rs +++ b/crates/core_simd/src/masks/full_masks.rs @@ -212,3 +212,30 @@ define_mask! { /// or unset. struct MaskSize(crate::SimdIsize); } + +macro_rules! impl_from { + { $from:ident ($from_inner:ident) => $($to:ident ($to_inner:ident)),* } => { + $( + impl From<$from> for $to + where + crate::$from_inner: crate::LanesAtMost32, + crate::$to_inner: crate::LanesAtMost32, + T: crate::Mask, + U: crate::Mask, + { + fn from(value: $from) -> 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) } diff --git a/crates/core_simd/src/masks/mod.rs b/crates/core_simd/src/masks/mod.rs index deaf2be5dca44..81a410de200e2 100644 --- a/crates/core_simd/src/masks/mod.rs +++ b/crates/core_simd/src/masks/mod.rs @@ -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 From<$from> for $to + where + crate::$from_inner: crate::LanesAtMost32, + crate::$to_inner: crate::LanesAtMost32, + $from: Mask, + Self: Mask, + { + fn from(value: $from) -> 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) } diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs index 7021d58aa543a..5c2e60dd7c824 100644 --- a/crates/core_simd/tests/masks.rs +++ b/crates/core_simd/tests/masks.rs @@ -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() + ); +}