Skip to content

Commit 68393aa

Browse files
Add mask width conversion (#127)
1 parent 3032a62 commit 68393aa

File tree

4 files changed

+82
-0
lines changed

4 files changed

+82
-0
lines changed

crates/core_simd/src/masks/bitmask.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,26 @@ pub type Mask16<T, const LANES: usize> = BitMask<T, LANES>;
169169
pub type Mask32<T, const LANES: usize> = BitMask<T, LANES>;
170170
pub type Mask64<T, const LANES: usize> = BitMask<T, LANES>;
171171
pub type MaskSize<T, const LANES: usize> = BitMask<T, LANES>;
172+
173+
macro_rules! impl_from {
174+
{ $from:ident ($from_inner:ident) => $($to:ident ($to_inner:ident)),* } => {
175+
$(
176+
impl<const LANES: usize> From<$from<crate::$from<LANES>, LANES>> for $to<crate::$to<LANES>, LANES>
177+
where
178+
crate::$from_inner<LANES>: crate::LanesAtMost32,
179+
crate::$to_inner<LANES>: crate::LanesAtMost32,
180+
crate::$from<LANES>: crate::Mask,
181+
crate::$to<LANES>: crate::Mask,
182+
{
183+
fn from(value: $from<crate::$from<LANES>, LANES>) -> Self {
184+
unsafe { core::mem::transmute_copy(&value) }
185+
}
186+
}
187+
)*
188+
}
189+
}
190+
impl_from! { Mask8 (SimdI8) => Mask16 (SimdI16), Mask32 (SimdI32), Mask64 (SimdI64), MaskSize (SimdIsize) }
191+
impl_from! { Mask16 (SimdI16) => Mask32 (SimdI32), Mask64 (SimdI64), MaskSize (SimdIsize), Mask8 (SimdI8) }
192+
impl_from! { Mask32 (SimdI32) => Mask64 (SimdI64), MaskSize (SimdIsize), Mask8 (SimdI8), Mask16 (SimdI16) }
193+
impl_from! { Mask64 (SimdI64) => MaskSize (SimdIsize), Mask8 (SimdI8), Mask16 (SimdI16), Mask32 (SimdI32) }
194+
impl_from! { MaskSize (SimdIsize) => Mask8 (SimdI8), Mask16 (SimdI16), Mask32 (SimdI32), Mask64 (SimdI64) }

crates/core_simd/src/masks/full_masks.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,30 @@ define_mask! {
212212
/// or unset.
213213
struct MaskSize<const LANES: usize>(crate::SimdIsize<LANES>);
214214
}
215+
216+
macro_rules! impl_from {
217+
{ $from:ident ($from_inner:ident) => $($to:ident ($to_inner:ident)),* } => {
218+
$(
219+
impl<const LANES: usize, T, U> From<$from<T, LANES>> for $to<U, LANES>
220+
where
221+
crate::$from_inner<LANES>: crate::LanesAtMost32,
222+
crate::$to_inner<LANES>: crate::LanesAtMost32,
223+
T: crate::Mask,
224+
U: crate::Mask,
225+
{
226+
fn from(value: $from<T, LANES>) -> Self {
227+
let mut new = Self::splat(false);
228+
for i in 0..LANES {
229+
unsafe { new.set_unchecked(i, value.test_unchecked(i)) }
230+
}
231+
new
232+
}
233+
}
234+
)*
235+
}
236+
}
237+
impl_from! { Mask8 (SimdI8) => Mask16 (SimdI16), Mask32 (SimdI32), Mask64 (SimdI64), MaskSize (SimdIsize) }
238+
impl_from! { Mask16 (SimdI16) => Mask32 (SimdI32), Mask64 (SimdI64), MaskSize (SimdIsize), Mask8 (SimdI8) }
239+
impl_from! { Mask32 (SimdI32) => Mask64 (SimdI64), MaskSize (SimdIsize), Mask8 (SimdI8), Mask16 (SimdI16) }
240+
impl_from! { Mask64 (SimdI64) => MaskSize (SimdIsize), Mask8 (SimdI8), Mask16 (SimdI16), Mask32 (SimdI32) }
241+
impl_from! { MaskSize (SimdIsize) => Mask8 (SimdI8), Mask16 (SimdI16), Mask32 (SimdI32), Mask64 (SimdI64) }

crates/core_simd/src/masks/mod.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,3 +544,26 @@ pub type masksizex4 = MaskSize<4>;
544544

545545
/// Vector of eight pointer-width masks
546546
pub type masksizex8 = MaskSize<8>;
547+
548+
macro_rules! impl_from {
549+
{ $from:ident ($from_inner:ident) => $($to:ident ($to_inner:ident)),* } => {
550+
$(
551+
impl<const LANES: usize> From<$from<LANES>> for $to<LANES>
552+
where
553+
crate::$from_inner<LANES>: crate::LanesAtMost32,
554+
crate::$to_inner<LANES>: crate::LanesAtMost32,
555+
$from<LANES>: Mask,
556+
Self: Mask,
557+
{
558+
fn from(value: $from<LANES>) -> Self {
559+
Self(value.0.into())
560+
}
561+
}
562+
)*
563+
}
564+
}
565+
impl_from! { Mask8 (SimdI8) => Mask16 (SimdI16), Mask32 (SimdI32), Mask64 (SimdI64), MaskSize (SimdIsize) }
566+
impl_from! { Mask16 (SimdI16) => Mask32 (SimdI32), Mask64 (SimdI64), MaskSize (SimdIsize), Mask8 (SimdI8) }
567+
impl_from! { Mask32 (SimdI32) => Mask64 (SimdI64), MaskSize (SimdIsize), Mask8 (SimdI8), Mask16 (SimdI16) }
568+
impl_from! { Mask64 (SimdI64) => MaskSize (SimdIsize), Mask8 (SimdI8), Mask16 (SimdI16), Mask32 (SimdI32) }
569+
impl_from! { MaskSize (SimdIsize) => Mask8 (SimdI8), Mask16 (SimdI16), Mask32 (SimdI32), Mask64 (SimdI64) }

crates/core_simd/tests/masks.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,12 @@ macro_rules! test_mask_api {
8282
mod mask_api {
8383
test_mask_api! { Mask8 }
8484
}
85+
86+
#[test]
87+
fn convert() {
88+
let values = [true, false, false, true, false, false, true, false];
89+
assert_eq!(
90+
core_simd::Mask8::from_array(values),
91+
core_simd::Mask32::from_array(values).into()
92+
);
93+
}

0 commit comments

Comments
 (0)