diff options
| -rw-r--r-- | crates/core_simd/src/masks/bitmask.rs | 23 | ||||
| -rw-r--r-- | crates/core_simd/src/masks/full_masks.rs | 27 | ||||
| -rw-r--r-- | crates/core_simd/src/masks/mod.rs | 23 | ||||
| -rw-r--r-- | crates/core_simd/tests/masks.rs | 9 |
4 files changed, 82 insertions, 0 deletions
diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs index 6bcb08cf9db..31c7f6e7c28 100644 --- a/crates/core_simd/src/masks/bitmask.rs +++ b/crates/core_simd/src/masks/bitmask.rs @@ -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) } diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index f89bbefba63..c2bfa03dfc6 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<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) } diff --git a/crates/core_simd/src/masks/mod.rs b/crates/core_simd/src/masks/mod.rs index deaf2be5dca..81a410de200 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<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) } diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs index 7021d58aa54..5c2e60dd7c8 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() + ); +} |
