about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/core_simd/src/masks/bitmask.rs23
-rw-r--r--crates/core_simd/src/masks/full_masks.rs27
-rw-r--r--crates/core_simd/src/masks/mod.rs23
-rw-r--r--crates/core_simd/tests/masks.rs9
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()
+    );
+}