Skip to content

Commit 11c3eef

Browse files
calebzulawskiworkingjubilee
authored andcommitted
Manually implement for supported lanes
1 parent 842ac87 commit 11c3eef

File tree

4 files changed

+38
-59
lines changed

4 files changed

+38
-59
lines changed

crates/core_simd/src/masks/bitmask.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,13 @@ where
116116
}
117117

118118
#[inline]
119-
pub unsafe fn to_bitmask_intrinsic<U>(self) -> U {
119+
pub unsafe fn to_bitmask_integer<U>(self) -> U {
120120
unsafe { core::mem::transmute_copy(&self.0) }
121121
}
122122

123+
// Safety: U must be the integer with the exact number of bits required to hold the bitmask for
123124
#[inline]
124-
pub unsafe fn from_bitmask_intrinsic<U>(bitmask: U) -> Self {
125+
pub unsafe fn from_bitmask_integer<U>(bitmask: U) -> Self {
125126
unsafe { Self(core::mem::transmute_copy(&bitmask), PhantomData) }
126127
}
127128

crates/core_simd/src/masks/full_masks.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,15 @@ where
110110
}
111111

112112
#[inline]
113-
pub unsafe fn to_bitmask_intrinsic<U>(self) -> U {
113+
pub unsafe fn to_bitmask_integer<U>(self) -> U {
114114
// Safety: caller must only return bitmask types
115115
unsafe { intrinsics::simd_bitmask(self.0) }
116116
}
117117

118+
// Safety: U must be the integer with the exact number of bits required to hold the bitmask for
119+
// this mask
118120
#[inline]
119-
pub unsafe fn from_bitmask_intrinsic<U>(bitmask: U) -> Self {
121+
pub unsafe fn from_bitmask_integer<U>(bitmask: U) -> Self {
120122
// Safety: caller must only pass bitmask types
121123
unsafe {
122124
Self::from_int_unchecked(intrinsics::simd_select_bitmask(
+30-54
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,54 @@
11
use super::{mask_impl, Mask, MaskElement};
22

3-
/// Converts masks to and from bitmasks.
3+
/// Converts masks to and from integer bitmasks.
44
///
5-
/// In a bitmask, each bit represents if the corresponding lane in the mask is set.
6-
pub trait ToBitMask<BitMask> {
5+
/// Each bit of the bitmask corresponds to a mask lane, starting with the LSB.
6+
pub trait ToBitMask {
7+
/// The integer bitmask type.
8+
type BitMask;
9+
710
/// Converts a mask to a bitmask.
8-
fn to_bitmask(self) -> BitMask;
11+
fn to_bitmask(self) -> Self::BitMask;
912

1013
/// Converts a bitmask to a mask.
11-
fn from_bitmask(bitmask: BitMask) -> Self;
14+
fn from_bitmask(bitmask: Self::BitMask) -> Self;
1215
}
1316

14-
macro_rules! impl_integer_intrinsic {
15-
{ $(unsafe impl ToBitMask<$int:ty> for Mask<_, $lanes:literal>)* } => {
16-
$(
17-
impl<T: MaskElement> ToBitMask<$int> for Mask<T, $lanes> {
18-
fn to_bitmask(self) -> $int {
19-
unsafe { self.0.to_bitmask_intrinsic() }
20-
}
17+
/// Converts masks to and from byte array bitmasks.
18+
///
19+
/// Each bit of the bitmask corresponds to a mask lane, starting with the LSB of the first byte.
20+
pub trait ToBitMaskArray {
21+
/// The length of the bitmask array.
22+
const BYTES: usize;
2123

22-
fn from_bitmask(bitmask: $int) -> Self {
23-
unsafe { Self(mask_impl::Mask::from_bitmask_intrinsic(bitmask)) }
24-
}
25-
}
26-
)*
27-
}
28-
}
24+
/// Converts a mask to a bitmask.
25+
fn to_bitmask_array(self) -> [u8; Self::BYTES];
2926

30-
impl_integer_intrinsic! {
31-
unsafe impl ToBitMask<u8> for Mask<_, 8>
32-
unsafe impl ToBitMask<u16> for Mask<_, 16>
33-
unsafe impl ToBitMask<u32> for Mask<_, 32>
34-
unsafe impl ToBitMask<u64> for Mask<_, 64>
27+
/// Converts a bitmask to a mask.
28+
fn from_bitmask_array(bitmask: [u8; Self::BYTES]) -> Self;
3529
}
3630

37-
macro_rules! impl_integer_via {
38-
{ $(impl ToBitMask<$int:ty, via $via:ty> for Mask<_, $lanes:literal>)* } => {
31+
macro_rules! impl_integer_intrinsic {
32+
{ $(unsafe impl ToBitMask<BitMask=$int:ty> for Mask<_, $lanes:literal>)* } => {
3933
$(
40-
impl<T: MaskElement> ToBitMask<$int> for Mask<T, $lanes> {
34+
impl<T: MaskElement> ToBitMask for Mask<T, $lanes> {
35+
type BitMask = $int;
36+
4137
fn to_bitmask(self) -> $int {
42-
let bitmask: $via = self.to_bitmask();
43-
bitmask as _
38+
unsafe { self.0.to_bitmask_integer() }
4439
}
4540

4641
fn from_bitmask(bitmask: $int) -> Self {
47-
Self::from_bitmask(bitmask as $via)
42+
unsafe { Self(mask_impl::Mask::from_bitmask_integer(bitmask)) }
4843
}
4944
}
5045
)*
5146
}
5247
}
5348

54-
impl_integer_via! {
55-
impl ToBitMask<u16, via u8> for Mask<_, 8>
56-
impl ToBitMask<u32, via u8> for Mask<_, 8>
57-
impl ToBitMask<u64, via u8> for Mask<_, 8>
58-
59-
impl ToBitMask<u32, via u16> for Mask<_, 16>
60-
impl ToBitMask<u64, via u16> for Mask<_, 16>
61-
62-
impl ToBitMask<u64, via u32> for Mask<_, 32>
63-
}
64-
65-
#[cfg(target_pointer_width = "32")]
66-
impl_integer_via! {
67-
impl ToBitMask<usize, via u8> for Mask<_, 8>
68-
impl ToBitMask<usize, via u16> for Mask<_, 16>
69-
impl ToBitMask<usize, via u32> for Mask<_, 32>
70-
}
71-
72-
#[cfg(target_pointer_width = "64")]
73-
impl_integer_via! {
74-
impl ToBitMask<usize, via u8> for Mask<_, 8>
75-
impl ToBitMask<usize, via u16> for Mask<_, 16>
76-
impl ToBitMask<usize, via u32> for Mask<_, 32>
77-
impl ToBitMask<usize, via u64> for Mask<_, 64>
49+
impl_integer_intrinsic! {
50+
unsafe impl ToBitMask<BitMask=u8> for Mask<_, 8>
51+
unsafe impl ToBitMask<BitMask=u16> for Mask<_, 16>
52+
unsafe impl ToBitMask<BitMask=u32> for Mask<_, 32>
53+
unsafe impl ToBitMask<BitMask=u64> for Mask<_, 64>
7854
}

crates/core_simd/tests/masks.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ macro_rules! test_mask_api {
7676
true, true, false, false, false, false, false, true,
7777
];
7878
let mask = core_simd::Mask::<$type, 16>::from_array(values);
79-
let bitmask: u16 = mask.to_bitmask();
79+
let bitmask = mask.to_bitmask();
8080
assert_eq!(bitmask, 0b1000001101001001);
8181
assert_eq!(core_simd::Mask::<$type, 16>::from_bitmask(bitmask), mask);
8282
}

0 commit comments

Comments
 (0)