提交 36e198b9 编写于 作者: C Caleb Zulawski 提交者: Jubilee Young

Use new bitmask intrinsics with byte arrays

上级 1ce1c645
...@@ -15,34 +15,25 @@ impl<const LANES: usize> LaneCount<LANES> { ...@@ -15,34 +15,25 @@ impl<const LANES: usize> LaneCount<LANES> {
pub trait SupportedLaneCount: Sealed { pub trait SupportedLaneCount: Sealed {
#[doc(hidden)] #[doc(hidden)]
type BitMask: Copy + Default + AsRef<[u8]> + AsMut<[u8]>; type BitMask: Copy + Default + AsRef<[u8]> + AsMut<[u8]>;
#[doc(hidden)]
type IntBitMask;
} }
impl<const LANES: usize> Sealed for LaneCount<LANES> {} impl<const LANES: usize> Sealed for LaneCount<LANES> {}
impl SupportedLaneCount for LaneCount<1> { impl SupportedLaneCount for LaneCount<1> {
type BitMask = [u8; 1]; type BitMask = [u8; 1];
type IntBitMask = u8;
} }
impl SupportedLaneCount for LaneCount<2> { impl SupportedLaneCount for LaneCount<2> {
type BitMask = [u8; 1]; type BitMask = [u8; 1];
type IntBitMask = u8;
} }
impl SupportedLaneCount for LaneCount<4> { impl SupportedLaneCount for LaneCount<4> {
type BitMask = [u8; 1]; type BitMask = [u8; 1];
type IntBitMask = u8;
} }
impl SupportedLaneCount for LaneCount<8> { impl SupportedLaneCount for LaneCount<8> {
type BitMask = [u8; 1]; type BitMask = [u8; 1];
type IntBitMask = u8;
} }
impl SupportedLaneCount for LaneCount<16> { impl SupportedLaneCount for LaneCount<16> {
type BitMask = [u8; 2]; type BitMask = [u8; 2];
type IntBitMask = u16;
} }
impl SupportedLaneCount for LaneCount<32> { impl SupportedLaneCount for LaneCount<32> {
type BitMask = [u8; 4]; type BitMask = [u8; 4];
type IntBitMask = u32;
} }
#![allow(unused_imports)]
use super::MaskElement; use super::MaskElement;
use crate::simd::intrinsics; use crate::simd::intrinsics;
use crate::simd::{LaneCount, Simd, SupportedLaneCount}; use crate::simd::{LaneCount, Simd, SupportedLaneCount};
...@@ -101,24 +102,17 @@ pub unsafe fn set_unchecked(&mut self, lane: usize, value: bool) { ...@@ -101,24 +102,17 @@ pub unsafe fn set_unchecked(&mut self, lane: usize, value: bool) {
#[inline] #[inline]
pub fn to_int(self) -> Simd<T, LANES> { pub fn to_int(self) -> Simd<T, LANES> {
unsafe { unsafe {
let mask: <LaneCount<LANES> as SupportedLaneCount>::IntBitMask = crate::intrinsics::simd_select_bitmask(
core::mem::transmute_copy(&self); self.0,
intrinsics::simd_select_bitmask(mask, Simd::splat(T::TRUE), Simd::splat(T::FALSE)) Simd::splat(T::TRUE),
Simd::splat(T::FALSE),
)
} }
} }
#[inline] #[inline]
pub unsafe fn from_int_unchecked(value: Simd<T, LANES>) -> Self { pub unsafe fn from_int_unchecked(value: Simd<T, LANES>) -> Self {
// TODO remove the transmute when rustc is more flexible unsafe { Self(crate::intrinsics::simd_bitmask(value), PhantomData) }
assert_eq!(
core::mem::size_of::<<LaneCount::<LANES> as SupportedLaneCount>::BitMask>(),
core::mem::size_of::<<LaneCount::<LANES> as SupportedLaneCount>::IntBitMask>(),
);
unsafe {
let mask: <LaneCount<LANES> as SupportedLaneCount>::IntBitMask =
intrinsics::simd_bitmask(value);
Self(core::mem::transmute_copy(&mask), PhantomData)
}
} }
#[cfg(feature = "generic_const_exprs")] #[cfg(feature = "generic_const_exprs")]
......
...@@ -106,15 +106,8 @@ pub fn convert<U>(self) -> Mask<U, LANES> ...@@ -106,15 +106,8 @@ pub fn convert<U>(self) -> Mask<U, LANES>
#[inline] #[inline]
pub fn to_bitmask(self) -> [u8; LaneCount::<LANES>::BITMASK_LEN] { pub fn to_bitmask(self) -> [u8; LaneCount::<LANES>::BITMASK_LEN] {
unsafe { unsafe {
// TODO remove the transmute when rustc can use arrays of u8 as bitmasks
assert_eq!(
core::mem::size_of::<<LaneCount::<LANES> as SupportedLaneCount>::IntBitMask>(),
LaneCount::<LANES>::BITMASK_LEN,
);
let bitmask: <LaneCount<LANES> as SupportedLaneCount>::IntBitMask =
intrinsics::simd_bitmask(self.0);
let mut bitmask: [u8; LaneCount::<LANES>::BITMASK_LEN] = let mut bitmask: [u8; LaneCount::<LANES>::BITMASK_LEN] =
core::mem::transmute_copy(&bitmask); crate::intrinsics::simd_bitmask(self.0);
// There is a bug where LLVM appears to implement this operation with the wrong // There is a bug where LLVM appears to implement this operation with the wrong
// bit order. // bit order.
...@@ -142,15 +135,7 @@ pub fn convert<U>(self) -> Mask<U, LANES> ...@@ -142,15 +135,7 @@ pub fn convert<U>(self) -> Mask<U, LANES>
} }
} }
// TODO remove the transmute when rustc can use arrays of u8 as bitmasks Self::from_int_unchecked(crate::intrinsics::simd_select_bitmask(
assert_eq!(
core::mem::size_of::<<LaneCount::<LANES> as SupportedLaneCount>::IntBitMask>(),
LaneCount::<LANES>::BITMASK_LEN,
);
let bitmask: <LaneCount<LANES> as SupportedLaneCount>::IntBitMask =
core::mem::transmute_copy(&bitmask);
Self::from_int_unchecked(intrinsics::simd_select_bitmask(
bitmask, bitmask,
Self::splat(true).to_int(), Self::splat(true).to_int(),
Self::splat(false).to_int(), Self::splat(false).to_int(),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册