From c077bf3c07280d1026fa8a5a1e36c9fbbdaec10b Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Fri, 25 Jun 2021 03:34:10 +0000 Subject: [PATCH 1/6] Rename SimdArray to Vector, remove its generic parameter, and remove LanesAtMost32 --- crates/core_simd/src/array.rs | 253 ----------------------- crates/core_simd/src/comparisons.rs | 6 +- crates/core_simd/src/first.rs | 160 ++++++++++++-- crates/core_simd/src/fmt.rs | 2 +- crates/core_simd/src/iter.rs | 8 +- crates/core_simd/src/lanes_at_most_32.rs | 54 ----- crates/core_simd/src/lib.rs | 6 - crates/core_simd/src/masks/bitmask.rs | 16 +- crates/core_simd/src/masks/full_masks.rs | 30 +-- crates/core_simd/src/masks/mod.rs | 60 +++--- crates/core_simd/src/math.rs | 4 +- crates/core_simd/src/ops.rs | 78 +++---- crates/core_simd/src/reduction.rs | 8 +- crates/core_simd/src/round.rs | 6 +- crates/core_simd/src/select.rs | 12 +- crates/core_simd/src/to_bytes.rs | 8 +- crates/core_simd/src/vector.rs | 10 - crates/core_simd/src/vector/float.rs | 14 +- crates/core_simd/src/vector/int.rs | 20 +- crates/core_simd/src/vector/mod.rs | 132 ++++++++++++ crates/core_simd/src/vector/ptr.rs | 4 +- crates/core_simd/src/vector/uint.rs | 16 +- crates/test_helpers/src/lib.rs | 48 ++--- 23 files changed, 450 insertions(+), 505 deletions(-) delete mode 100644 crates/core_simd/src/array.rs delete mode 100644 crates/core_simd/src/lanes_at_most_32.rs delete mode 100644 crates/core_simd/src/vector.rs create mode 100644 crates/core_simd/src/vector/mod.rs diff --git a/crates/core_simd/src/array.rs b/crates/core_simd/src/array.rs deleted file mode 100644 index 25c53097bebe..000000000000 --- a/crates/core_simd/src/array.rs +++ /dev/null @@ -1,253 +0,0 @@ -use crate::intrinsics; -use crate::masks::*; -use crate::vector::ptr::{SimdConstPtr, SimdMutPtr}; -use crate::vector::*; - -/// A representation of a vector as an "array" with indices, implementing -/// operations applicable to any vector type based solely on "having lanes", -/// and describing relationships between vector and scalar types. -pub trait SimdArray: crate::LanesAtMost32 -where - SimdUsize: crate::LanesAtMost32, - SimdIsize: crate::LanesAtMost32, - MaskSize: crate::Mask, - Self: Sized, -{ - /// The scalar type in every lane of this vector type. - type Scalar: Copy + Sized; - /// The number of lanes for this vector. - const LANES: usize = LANES; - - /// Generates a SIMD vector with the same value in every lane. - #[must_use] - fn splat(val: Self::Scalar) -> Self; - - /// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices. - /// If an index is out of bounds, that lane instead selects the value from the "or" vector. - /// ``` - /// # #![feature(portable_simd)] - /// # use core_simd::*; - /// let vec: Vec = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; - /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 5]); - /// let alt = SimdI32::from_array([-5, -4, -3, -2]); - /// - /// let result = SimdI32::<4>::gather_or(&vec, idxs, alt); // Note the lane that is out-of-bounds. - /// assert_eq!(result, SimdI32::from_array([-5, 13, 10, 15])); - /// ``` - #[must_use] - #[inline] - fn gather_or(slice: &[Self::Scalar], idxs: SimdUsize, or: Self) -> Self { - Self::gather_select(slice, MaskSize::splat(true), idxs, or) - } - - /// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices. - /// Out-of-bounds indices instead use the default value for that lane (0). - /// ``` - /// # #![feature(portable_simd)] - /// # use core_simd::*; - /// let vec: Vec = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; - /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 5]); - /// - /// let result = SimdI32::<4>::gather_or_default(&vec, idxs); // Note the lane that is out-of-bounds. - /// assert_eq!(result, SimdI32::from_array([0, 13, 10, 15])); - /// ``` - #[must_use] - #[inline] - fn gather_or_default(slice: &[Self::Scalar], idxs: SimdUsize) -> Self - where - Self::Scalar: Default, - { - Self::gather_or(slice, idxs, Self::splat(Self::Scalar::default())) - } - - /// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices. - /// Out-of-bounds or masked indices instead select the value from the "or" vector. - /// ``` - /// # #![feature(portable_simd)] - /// # use core_simd::*; - /// let vec: Vec = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; - /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 5]); - /// let alt = SimdI32::from_array([-5, -4, -3, -2]); - /// let mask = MaskSize::from_array([true, true, true, false]); // Note the mask of the last lane. - /// - /// let result = SimdI32::<4>::gather_select(&vec, mask, idxs, alt); // Note the lane that is out-of-bounds. - /// assert_eq!(result, SimdI32::from_array([-5, 13, 10, -2])); - /// ``` - #[must_use] - #[inline] - fn gather_select( - slice: &[Self::Scalar], - mask: MaskSize, - idxs: SimdUsize, - or: Self, - ) -> Self { - let mask = (mask & idxs.lanes_lt(SimdUsize::splat(slice.len()))).to_int(); - let base_ptr = SimdConstPtr::splat(slice.as_ptr()); - // Ferris forgive me, I have done pointer arithmetic here. - let ptrs = base_ptr.wrapping_add(idxs); - // SAFETY: The ptrs have been bounds-masked to prevent memory-unsafe reads insha'allah - unsafe { intrinsics::simd_gather(or, ptrs, mask) } - } - - /// SIMD scatter: write a SIMD vector's values into a slice, using potentially discontiguous indices. - /// Out-of-bounds indices are not written. - /// `scatter` writes "in order", so if an index receives two writes, only the last is guaranteed. - /// ``` - /// # #![feature(portable_simd)] - /// # use core_simd::*; - /// let mut vec: Vec = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; - /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 0]); - /// let vals = SimdI32::from_array([-27, 82, -41, 124]); - /// - /// vals.scatter(&mut vec, idxs); // index 0 receives two writes. - /// assert_eq!(vec, vec![124, 11, 12, 82, 14, 15, 16, 17, 18]); - /// ``` - #[inline] - fn scatter(self, slice: &mut [Self::Scalar], idxs: SimdUsize) { - self.scatter_select(slice, MaskSize::splat(true), idxs) - } - - /// SIMD scatter: write a SIMD vector's values into a slice, using potentially discontiguous indices. - /// Out-of-bounds or masked indices are not written. - /// `scatter_select` writes "in order", so if an index receives two writes, only the last is guaranteed. - /// ``` - /// # #![feature(portable_simd)] - /// # use core_simd::*; - /// let mut vec: Vec = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; - /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 0]); - /// let vals = SimdI32::from_array([-27, 82, -41, 124]); - /// let mask = MaskSize::from_array([true, true, true, false]); // Note the mask of the last lane. - /// - /// vals.scatter_select(&mut vec, mask, idxs); // index 0's second write is masked, thus omitted. - /// assert_eq!(vec, vec![-41, 11, 12, 82, 14, 15, 16, 17, 18]); - /// ``` - #[inline] - fn scatter_select( - self, - slice: &mut [Self::Scalar], - mask: MaskSize, - idxs: SimdUsize, - ) { - // We must construct our scatter mask before we derive a pointer! - let mask = (mask & idxs.lanes_lt(SimdUsize::splat(slice.len()))).to_int(); - // SAFETY: This block works with *mut T derived from &mut 'a [T], - // which means it is delicate in Rust's borrowing model, circa 2021: - // &mut 'a [T] asserts uniqueness, so deriving &'a [T] invalidates live *mut Ts! - // Even though this block is largely safe methods, it must be almost exactly this way - // to prevent invalidating the raw ptrs while they're live. - // Thus, entering this block requires all values to use being already ready: - // 0. idxs we want to write to, which are used to construct the mask. - // 1. mask, which depends on an initial &'a [T] and the idxs. - // 2. actual values to scatter (self). - // 3. &mut [T] which will become our base ptr. - unsafe { - // Now Entering ☢️ *mut T Zone - let base_ptr = SimdMutPtr::splat(slice.as_mut_ptr()); - // Ferris forgive me, I have done pointer arithmetic here. - let ptrs = base_ptr.wrapping_add(idxs); - // The ptrs have been bounds-masked to prevent memory-unsafe writes insha'allah - intrinsics::simd_scatter(self, ptrs, mask) - // Cleared ☢️ *mut T Zone - } - } -} - -macro_rules! impl_simdarray_for { - ($simd:ident {type Scalar = $scalar:ident;}) => { - impl SimdArray for $simd - where SimdUsize: crate::LanesAtMost32, - SimdIsize: crate::LanesAtMost32, - MaskSize: crate::Mask, - Self: crate::LanesAtMost32, - { - type Scalar = $scalar; - - #[must_use] - #[inline] - fn splat(val: Self::Scalar) -> Self { - [val; LANES].into() - } - } - }; - - ($simd:ident $impl:tt) => { - impl SimdArray for $simd - where SimdUsize: crate::LanesAtMost32, - SimdIsize: crate::LanesAtMost32, - MaskSize: crate::Mask, - Self: crate::LanesAtMost32, - $impl - } -} - -impl_simdarray_for! { - SimdUsize { - type Scalar = usize; - } -} - -impl_simdarray_for! { - SimdIsize { - type Scalar = isize; - } -} - -impl_simdarray_for! { - SimdI8 { - type Scalar = i8; - } -} - -impl_simdarray_for! { - SimdI16 { - type Scalar = i16; - } -} - -impl_simdarray_for! { - SimdI32 { - type Scalar = i32; - } -} - -impl_simdarray_for! { - SimdI64 { - type Scalar = i64; - } -} - -impl_simdarray_for! { - SimdU8 { - type Scalar = u8; - } -} - -impl_simdarray_for! { - SimdU16 { - type Scalar = u16; - } -} - -impl_simdarray_for! { - SimdU32 { - type Scalar = u32; - } -} - -impl_simdarray_for! { - SimdU64 { - type Scalar = u64; - } -} - -impl_simdarray_for! { - SimdF32 { - type Scalar = f32; - } -} - -impl_simdarray_for! { - SimdF64 { - type Scalar = f64; - } -} diff --git a/crates/core_simd/src/comparisons.rs b/crates/core_simd/src/comparisons.rs index e8d11406c097..c3bf07fc4320 100644 --- a/crates/core_simd/src/comparisons.rs +++ b/crates/core_simd/src/comparisons.rs @@ -1,12 +1,12 @@ -use crate::LanesAtMost32; +use crate::Vector; macro_rules! implement_mask_ops { { $($vector:ident => $mask:ident ($inner_ty:ident),)* } => { $( impl crate::$vector where - crate::$vector: LanesAtMost32, - crate::$inner_ty: LanesAtMost32, + crate::$vector: Vector, + crate::$inner_ty: Vector, crate::$mask: crate::Mask, { /// Test if each lane is equal to the corresponding lane in `other`. diff --git a/crates/core_simd/src/first.rs b/crates/core_simd/src/first.rs index 50602829d482..7721b87ecc0b 100644 --- a/crates/core_simd/src/first.rs +++ b/crates/core_simd/src/first.rs @@ -1,7 +1,7 @@ /// Implements common traits on the specified vector `$name`, holding multiple `$lanes` of `$type`. macro_rules! impl_vector { { $name:ident, $type:ty } => { - impl $name where Self: crate::LanesAtMost32 { + impl $name where Self: crate::Vector { /// Construct a SIMD vector by setting all lanes to the given value. pub const fn splat(value: $type) -> Self { Self([value; LANES]) @@ -44,23 +44,159 @@ macro_rules! impl_vector { } } - impl Copy for $name where Self: crate::LanesAtMost32 {} + impl $name + where + Self: crate::Vector, + crate::MaskSize: crate::Mask, + crate::SimdIsize: crate::Vector, + crate::SimdUsize: crate::Vector, + { + /// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices. + /// If an index is out of bounds, that lane instead selects the value from the "or" vector. + /// ``` + /// # #![feature(portable_simd)] + /// # use core_simd::*; + /// let vec: Vec = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; + /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 5]); + /// let alt = SimdI32::from_array([-5, -4, -3, -2]); + /// + /// let result = SimdI32::<4>::gather_or(&vec, idxs, alt); // Note the lane that is out-of-bounds. + /// assert_eq!(result, SimdI32::from_array([-5, 13, 10, 15])); + /// ``` + #[must_use] + #[inline] + pub fn gather_or(slice: &[$type], idxs: crate::SimdUsize, or: Self) -> Self { + Self::gather_select(slice, crate::MaskSize::splat(true), idxs, or) + } - impl Clone for $name where Self: crate::LanesAtMost32 { + /// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices. + /// Out-of-bounds indices instead use the default value for that lane (0). + /// ``` + /// # #![feature(portable_simd)] + /// # use core_simd::*; + /// let vec: Vec = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; + /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 5]); + /// + /// let result = SimdI32::<4>::gather_or_default(&vec, idxs); // Note the lane that is out-of-bounds. + /// assert_eq!(result, SimdI32::from_array([0, 13, 10, 15])); + /// ``` + #[must_use] + #[inline] + pub fn gather_or_default(slice: &[$type], idxs: crate::SimdUsize) -> Self { + Self::gather_or(slice, idxs, Self::splat(<$type>::default())) + } + + /// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices. + /// Out-of-bounds or masked indices instead select the value from the "or" vector. + /// ``` + /// # #![feature(portable_simd)] + /// # use core_simd::*; + /// let vec: Vec = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; + /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 5]); + /// let alt = SimdI32::from_array([-5, -4, -3, -2]); + /// let mask = MaskSize::from_array([true, true, true, false]); // Note the mask of the last lane. + /// + /// let result = SimdI32::<4>::gather_select(&vec, mask, idxs, alt); // Note the lane that is out-of-bounds. + /// assert_eq!(result, SimdI32::from_array([-5, 13, 10, -2])); + /// ``` + #[must_use] + #[inline] + pub fn gather_select( + slice: &[$type], + mask: crate::MaskSize, + idxs: crate::SimdUsize, + or: Self, + ) -> Self + { + let mask = (mask & idxs.lanes_lt(crate::SimdUsize::splat(slice.len()))).to_int(); + let base_ptr = crate::vector::ptr::SimdConstPtr::splat(slice.as_ptr()); + // Ferris forgive me, I have done pointer arithmetic here. + let ptrs = base_ptr.wrapping_add(idxs); + // SAFETY: The ptrs have been bounds-masked to prevent memory-unsafe reads insha'allah + unsafe { crate::intrinsics::simd_gather(or, ptrs, mask) } + } + + /// SIMD scatter: write a SIMD vector's values into a slice, using potentially discontiguous indices. + /// Out-of-bounds indices are not written. + /// `scatter` writes "in order", so if an index receives two writes, only the last is guaranteed. + /// ``` + /// # #![feature(portable_simd)] + /// # use core_simd::*; + /// let mut vec: Vec = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; + /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 0]); + /// let vals = SimdI32::from_array([-27, 82, -41, 124]); + /// + /// vals.scatter(&mut vec, idxs); // index 0 receives two writes. + /// assert_eq!(vec, vec![124, 11, 12, 82, 14, 15, 16, 17, 18]); + /// ``` + #[inline] + pub fn scatter(self, slice: &mut [$type], idxs: crate::SimdUsize) { + self.scatter_select(slice, crate::MaskSize::splat(true), idxs) + } + + /// SIMD scatter: write a SIMD vector's values into a slice, using potentially discontiguous indices. + /// Out-of-bounds or masked indices are not written. + /// `scatter_select` writes "in order", so if an index receives two writes, only the last is guaranteed. + /// ``` + /// # #![feature(portable_simd)] + /// # use core_simd::*; + /// let mut vec: Vec = vec![10, 11, 12, 13, 14, 15, 16, 17, 18]; + /// let idxs = SimdUsize::<4>::from_array([9, 3, 0, 0]); + /// let vals = SimdI32::from_array([-27, 82, -41, 124]); + /// let mask = MaskSize::from_array([true, true, true, false]); // Note the mask of the last lane. + /// + /// vals.scatter_select(&mut vec, mask, idxs); // index 0's second write is masked, thus omitted. + /// assert_eq!(vec, vec![-41, 11, 12, 82, 14, 15, 16, 17, 18]); + /// ``` + #[inline] + pub fn scatter_select( + self, + slice: &mut [$type], + mask: crate::MaskSize, + idxs: crate::SimdUsize, + ) + { + // We must construct our scatter mask before we derive a pointer! + let mask = (mask & idxs.lanes_lt(crate::SimdUsize::splat(slice.len()))).to_int(); + // SAFETY: This block works with *mut T derived from &mut 'a [T], + // which means it is delicate in Rust's borrowing model, circa 2021: + // &mut 'a [T] asserts uniqueness, so deriving &'a [T] invalidates live *mut Ts! + // Even though this block is largely safe methods, it must be almost exactly this way + // to prevent invalidating the raw ptrs while they're live. + // Thus, entering this block requires all values to use being already ready: + // 0. idxs we want to write to, which are used to construct the mask. + // 1. mask, which depends on an initial &'a [T] and the idxs. + // 2. actual values to scatter (self). + // 3. &mut [T] which will become our base ptr. + unsafe { + // Now Entering ☢️ *mut T Zone + let base_ptr = crate::vector::ptr::SimdMutPtr::splat(slice.as_mut_ptr()); + // Ferris forgive me, I have done pointer arithmetic here. + let ptrs = base_ptr.wrapping_add(idxs); + // The ptrs have been bounds-masked to prevent memory-unsafe writes insha'allah + crate::intrinsics::simd_scatter(self, ptrs, mask) + // Cleared ☢️ *mut T Zone + } + } + } + + impl Copy for $name where Self: crate::Vector {} + + impl Clone for $name where Self: crate::Vector { #[inline] fn clone(&self) -> Self { *self } } - impl Default for $name where Self: crate::LanesAtMost32 { + impl Default for $name where Self: crate::Vector { #[inline] fn default() -> Self { Self::splat(<$type>::default()) } } - impl PartialEq for $name where Self: crate::LanesAtMost32 { + impl PartialEq for $name where Self: crate::Vector { #[inline] fn eq(&self, other: &Self) -> bool { // TODO use SIMD equality @@ -68,7 +204,7 @@ macro_rules! impl_vector { } } - impl PartialOrd for $name where Self: crate::LanesAtMost32 { + impl PartialOrd for $name where Self: crate::Vector { #[inline] fn partial_cmp(&self, other: &Self) -> Option { // TODO use SIMD equalitya @@ -77,14 +213,14 @@ macro_rules! impl_vector { } // array references - impl AsRef<[$type; LANES]> for $name where Self: crate::LanesAtMost32 { + impl AsRef<[$type; LANES]> for $name where Self: crate::Vector { #[inline] fn as_ref(&self) -> &[$type; LANES] { &self.0 } } - impl AsMut<[$type; LANES]> for $name where Self: crate::LanesAtMost32 { + impl AsMut<[$type; LANES]> for $name where Self: crate::Vector { #[inline] fn as_mut(&mut self) -> &mut [$type; LANES] { &mut self.0 @@ -92,14 +228,14 @@ macro_rules! impl_vector { } // slice references - impl AsRef<[$type]> for $name where Self: crate::LanesAtMost32 { + impl AsRef<[$type]> for $name where Self: crate::Vector { #[inline] fn as_ref(&self) -> &[$type] { &self.0 } } - impl AsMut<[$type]> for $name where Self: crate::LanesAtMost32 { + impl AsMut<[$type]> for $name where Self: crate::Vector { #[inline] fn as_mut(&mut self) -> &mut [$type] { &mut self.0 @@ -107,13 +243,13 @@ macro_rules! impl_vector { } // vector/array conversion - impl From<[$type; LANES]> for $name where Self: crate::LanesAtMost32 { + impl From<[$type; LANES]> for $name where Self: crate::Vector { fn from(array: [$type; LANES]) -> Self { Self(array) } } - impl From<$name> for [$type; LANES] where $name: crate::LanesAtMost32 { + impl From<$name> for [$type; LANES] where $name: crate::Vector { fn from(vector: $name) -> Self { vector.to_array() } diff --git a/crates/core_simd/src/fmt.rs b/crates/core_simd/src/fmt.rs index 1d5010843eb7..554aa91a5f0c 100644 --- a/crates/core_simd/src/fmt.rs +++ b/crates/core_simd/src/fmt.rs @@ -35,7 +35,7 @@ macro_rules! impl_fmt_trait { $( // repeat trait impl core::fmt::$trait for crate::$type where - Self: crate::LanesAtMost32, + Self: crate::Vector, { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { $format(self.as_ref(), f) diff --git a/crates/core_simd/src/iter.rs b/crates/core_simd/src/iter.rs index c1c4c645db6b..460c061be69f 100644 --- a/crates/core_simd/src/iter.rs +++ b/crates/core_simd/src/iter.rs @@ -2,7 +2,7 @@ macro_rules! impl_traits { { $type:ident } => { impl core::iter::Sum for crate::$type where - Self: crate::LanesAtMost32, + Self: crate::Vector, { fn sum>(iter: I) -> Self { iter.fold(Default::default(), core::ops::Add::add) @@ -11,7 +11,7 @@ macro_rules! impl_traits { impl core::iter::Product for crate::$type where - Self: crate::LanesAtMost32, + Self: crate::Vector, { fn product>(iter: I) -> Self { iter.fold(Default::default(), core::ops::Mul::mul) @@ -20,7 +20,7 @@ macro_rules! impl_traits { impl<'a, const LANES: usize> core::iter::Sum<&'a Self> for crate::$type where - Self: crate::LanesAtMost32, + Self: crate::Vector, { fn sum>(iter: I) -> Self { iter.fold(Default::default(), core::ops::Add::add) @@ -29,7 +29,7 @@ macro_rules! impl_traits { impl<'a, const LANES: usize> core::iter::Product<&'a Self> for crate::$type where - Self: crate::LanesAtMost32, + Self: crate::Vector, { fn product>(iter: I) -> Self { iter.fold(Default::default(), core::ops::Mul::mul) diff --git a/crates/core_simd/src/lanes_at_most_32.rs b/crates/core_simd/src/lanes_at_most_32.rs deleted file mode 100644 index 2d84b1306ea5..000000000000 --- a/crates/core_simd/src/lanes_at_most_32.rs +++ /dev/null @@ -1,54 +0,0 @@ -/// Implemented for vectors that are supported by the implementation. -pub trait LanesAtMost32: sealed::Sealed { - #[doc(hidden)] - type BitMask: Into; -} - -mod sealed { - pub trait Sealed {} -} - -macro_rules! impl_for { - { $name:ident } => { - impl sealed::Sealed for $name - where - $name: LanesAtMost32, - {} - - impl LanesAtMost32 for $name<1> { - type BitMask = u8; - } - impl LanesAtMost32 for $name<2> { - type BitMask = u8; - } - impl LanesAtMost32 for $name<4> { - type BitMask = u8; - } - impl LanesAtMost32 for $name<8> { - type BitMask = u8; - } - impl LanesAtMost32 for $name<16> { - type BitMask = u16; - } - impl LanesAtMost32 for $name<32> { - type BitMask = u32; - } - } -} - -use crate::*; - -impl_for! { SimdU8 } -impl_for! { SimdU16 } -impl_for! { SimdU32 } -impl_for! { SimdU64 } -impl_for! { SimdUsize } - -impl_for! { SimdI8 } -impl_for! { SimdI16 } -impl_for! { SimdI32 } -impl_for! { SimdI64 } -impl_for! { SimdIsize } - -impl_for! { SimdF32 } -impl_for! { SimdF64 } diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs index e48f8062d2c8..eb580dcf14d8 100644 --- a/crates/core_simd/src/lib.rs +++ b/crates/core_simd/src/lib.rs @@ -35,14 +35,8 @@ mod vendor; mod math; -mod lanes_at_most_32; -pub use lanes_at_most_32::LanesAtMost32; - mod masks; pub use masks::*; mod vector; pub use vector::*; - -mod array; -pub use array::SimdArray; diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs index fab136d2b241..a64750a623f7 100644 --- a/crates/core_simd/src/masks/bitmask.rs +++ b/crates/core_simd/src/masks/bitmask.rs @@ -3,11 +3,11 @@ use core::marker::PhantomData; /// Helper trait for limiting int conversion types pub trait ConvertToInt {} -impl ConvertToInt for crate::SimdI8 where Self: crate::LanesAtMost32 {} -impl ConvertToInt for crate::SimdI16 where Self: crate::LanesAtMost32 {} -impl ConvertToInt for crate::SimdI32 where Self: crate::LanesAtMost32 {} -impl ConvertToInt for crate::SimdI64 where Self: crate::LanesAtMost32 {} -impl ConvertToInt for crate::SimdIsize where Self: crate::LanesAtMost32 {} +impl ConvertToInt for crate::SimdI8 where Self: crate::Vector {} +impl ConvertToInt for crate::SimdI16 where Self: crate::Vector {} +impl ConvertToInt for crate::SimdI32 where Self: crate::Vector {} +impl ConvertToInt for crate::SimdI64 where Self: crate::Vector {} +impl ConvertToInt for crate::SimdIsize where Self: crate::Vector {} /// A mask where each lane is represented by a single bit. #[repr(transparent)] @@ -80,7 +80,7 @@ impl BitMask { #[inline] pub unsafe fn from_int_unchecked(value: V) -> Self where - V: crate::LanesAtMost32, + V: crate::Vector, { // TODO remove the transmute when rustc is more flexible assert_eq!( @@ -184,8 +184,8 @@ macro_rules! impl_from { $( impl From<$from, LANES>> for $to, LANES> where - crate::$from_inner: crate::LanesAtMost32, - crate::$to_inner: crate::LanesAtMost32, + crate::$from_inner: crate::Vector, + crate::$to_inner: crate::Vector, crate::$from: crate::Mask, crate::$to: crate::Mask, { diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index 7d98333ef607..f083284df8fa 100644 --- a/crates/core_simd/src/masks/full_masks.rs +++ b/crates/core_simd/src/masks/full_masks.rs @@ -14,18 +14,18 @@ macro_rules! define_mask { #[repr(transparent)] pub struct $name(crate::$type<$lanes2>, PhantomData) where - crate::$type: crate::LanesAtMost32; + crate::$type: crate::Vector; impl_full_mask_reductions! { $name, $type } impl Copy for $name where - crate::$type: crate::LanesAtMost32, + crate::$type: crate::Vector, {} impl Clone for $name where - crate::$type: crate::LanesAtMost32, + crate::$type: crate::Vector, { #[inline] fn clone(&self) -> Self { @@ -35,7 +35,7 @@ macro_rules! define_mask { impl PartialEq for $name where - crate::$type: crate::LanesAtMost32, + crate::$type: crate::Vector, { fn eq(&self, other: &Self) -> bool { self.0 == other.0 @@ -44,7 +44,7 @@ macro_rules! define_mask { impl PartialOrd for $name where - crate::$type: crate::LanesAtMost32, + crate::$type: crate::Vector, { fn partial_cmp(&self, other: &Self) -> Option { self.0.partial_cmp(&other.0) @@ -53,12 +53,12 @@ macro_rules! define_mask { impl Eq for $name where - crate::$type: crate::LanesAtMost32, + crate::$type: crate::Vector, {} impl Ord for $name where - crate::$type: crate::LanesAtMost32, + crate::$type: crate::Vector, { fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.0.cmp(&other.0) @@ -67,7 +67,7 @@ macro_rules! define_mask { impl $name where - crate::$type: crate::LanesAtMost32, + crate::$type: crate::Vector, { pub fn splat(value: bool) -> Self { Self( @@ -154,7 +154,7 @@ macro_rules! define_mask { impl core::convert::From<$name> for crate::$type where - crate::$type: crate::LanesAtMost32, + crate::$type: crate::Vector, { fn from(value: $name) -> Self { value.0 @@ -163,7 +163,7 @@ macro_rules! define_mask { impl core::ops::BitAnd for $name where - crate::$type: crate::LanesAtMost32, + crate::$type: crate::Vector, { type Output = Self; #[inline] @@ -174,7 +174,7 @@ macro_rules! define_mask { impl core::ops::BitOr for $name where - crate::$type: crate::LanesAtMost32, + crate::$type: crate::Vector, { type Output = Self; #[inline] @@ -185,7 +185,7 @@ macro_rules! define_mask { impl core::ops::BitXor for $name where - crate::$type: crate::LanesAtMost32, + crate::$type: crate::Vector, { type Output = Self; #[inline] @@ -196,7 +196,7 @@ macro_rules! define_mask { impl core::ops::Not for $name where - crate::$type: crate::LanesAtMost32, + crate::$type: crate::Vector, { type Output = Self; #[inline] @@ -242,8 +242,8 @@ macro_rules! impl_from { $( impl From<$from> for $to where - crate::$from_inner: crate::LanesAtMost32, - crate::$to_inner: crate::LanesAtMost32, + crate::$from_inner: crate::Vector, + crate::$to_inner: crate::Vector, T: crate::Mask, U: crate::Mask, { diff --git a/crates/core_simd/src/masks/mod.rs b/crates/core_simd/src/masks/mod.rs index 1d6b2e45224a..43e689d45bc7 100644 --- a/crates/core_simd/src/masks/mod.rs +++ b/crates/core_simd/src/masks/mod.rs @@ -12,7 +12,7 @@ )] mod mask_impl; -use crate::{LanesAtMost32, SimdI16, SimdI32, SimdI64, SimdI8, SimdIsize}; +use crate::{SimdI16, SimdI32, SimdI64, SimdI8, SimdIsize, Vector}; mod sealed { pub trait Sealed {} @@ -38,12 +38,12 @@ macro_rules! define_opaque_mask { #[allow(non_camel_case_types)] pub struct $name($inner_ty) where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask; impl sealed::Sealed for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, {} impl Mask for $name<1> { @@ -75,7 +75,7 @@ macro_rules! define_opaque_mask { impl $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { /// Construct a mask by setting all lanes to the given value. @@ -188,7 +188,7 @@ macro_rules! define_opaque_mask { // vector/array conversion impl From<[bool; LANES]> for $name where - $bits_ty: crate::LanesAtMost32, + $bits_ty: crate::Vector, Self: Mask, { fn from(array: [bool; LANES]) -> Self { @@ -198,7 +198,7 @@ macro_rules! define_opaque_mask { impl From<$name> for [bool; LANES] where - $bits_ty: crate::LanesAtMost32, + $bits_ty: crate::Vector, $name: Mask, { fn from(vector: $name) -> Self { @@ -208,13 +208,13 @@ macro_rules! define_opaque_mask { impl Copy for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, {} impl Clone for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { #[inline] @@ -225,7 +225,7 @@ macro_rules! define_opaque_mask { impl Default for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { #[inline] @@ -236,7 +236,7 @@ macro_rules! define_opaque_mask { impl PartialEq for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { #[inline] @@ -247,7 +247,7 @@ macro_rules! define_opaque_mask { impl PartialOrd for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { #[inline] @@ -258,7 +258,7 @@ macro_rules! define_opaque_mask { impl core::fmt::Debug for $name where - $bits_ty: crate::LanesAtMost32, + $bits_ty: crate::Vector, Self: Mask, { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { @@ -270,7 +270,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitAnd for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { type Output = Self; @@ -282,7 +282,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitAnd for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { type Output = Self; @@ -294,7 +294,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitAnd<$name> for bool where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, $name: Mask, { type Output = $name; @@ -306,7 +306,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitOr for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { type Output = Self; @@ -318,7 +318,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitOr for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { type Output = Self; @@ -330,7 +330,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitOr<$name> for bool where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, $name: Mask, { type Output = $name; @@ -342,7 +342,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitXor for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { type Output = Self; @@ -354,7 +354,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitXor for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { type Output = Self; @@ -366,7 +366,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitXor<$name> for bool where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, $name: Mask, { type Output = $name; @@ -378,7 +378,7 @@ macro_rules! define_opaque_mask { impl core::ops::Not for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { type Output = $name; @@ -390,7 +390,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitAndAssign for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { #[inline] @@ -401,7 +401,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitAndAssign for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { #[inline] @@ -412,7 +412,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitOrAssign for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { #[inline] @@ -423,7 +423,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitOrAssign for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { #[inline] @@ -434,7 +434,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitXorAssign for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { #[inline] @@ -445,7 +445,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitXorAssign for $name where - $bits_ty: LanesAtMost32, + $bits_ty: Vector, Self: Mask, { #[inline] @@ -555,8 +555,8 @@ macro_rules! impl_from { $( impl From<$from> for $to where - crate::$from_inner: crate::LanesAtMost32, - crate::$to_inner: crate::LanesAtMost32, + crate::$from_inner: crate::Vector, + crate::$to_inner: crate::Vector, $from: Mask, Self: Mask, { diff --git a/crates/core_simd/src/math.rs b/crates/core_simd/src/math.rs index 7290a28362f9..cc0330871136 100644 --- a/crates/core_simd/src/math.rs +++ b/crates/core_simd/src/math.rs @@ -1,6 +1,6 @@ macro_rules! impl_uint_arith { ($(($name:ident, $n:ident)),+) => { - $( impl $name where Self: crate::LanesAtMost32 { + $( impl $name where Self: crate::Vector { /// Lanewise saturating add. /// @@ -44,7 +44,7 @@ macro_rules! impl_uint_arith { macro_rules! impl_int_arith { ($(($name:ident, $n:ident)),+) => { - $( impl $name where Self: crate::LanesAtMost32 { + $( impl $name where Self: crate::Vector { /// Lanewise saturating add. /// diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs index c7037d2acbc6..a41782a1464f 100644 --- a/crates/core_simd/src/ops.rs +++ b/crates/core_simd/src/ops.rs @@ -1,4 +1,4 @@ -use crate::LanesAtMost32; +use crate::Vector; /// Checks if the right-hand side argument of a left- or right-shift would cause overflow. fn invalid_shift_rhs(rhs: T) -> bool @@ -16,7 +16,7 @@ macro_rules! impl_ref_ops { { impl core::ops::$trait:ident<$rhs:ty> for $type:ty where - $($bound:path: LanesAtMost32,)* + $($bound:path: Vector,)* { type Output = $output:ty; @@ -26,7 +26,7 @@ macro_rules! impl_ref_ops { } => { impl core::ops::$trait<$rhs> for $type where - $($bound: LanesAtMost32,)* + $($bound: Vector,)* { type Output = $output; @@ -36,7 +36,7 @@ macro_rules! impl_ref_ops { impl core::ops::$trait<&'_ $rhs> for $type where - $($bound: LanesAtMost32,)* + $($bound: Vector,)* { type Output = <$type as core::ops::$trait<$rhs>>::Output; @@ -48,7 +48,7 @@ macro_rules! impl_ref_ops { impl core::ops::$trait<$rhs> for &'_ $type where - $($bound: LanesAtMost32,)* + $($bound: Vector,)* { type Output = <$type as core::ops::$trait<$rhs>>::Output; @@ -60,7 +60,7 @@ macro_rules! impl_ref_ops { impl core::ops::$trait<&'_ $rhs> for &'_ $type where - $($bound: LanesAtMost32,)* + $($bound: Vector,)* { type Output = <$type as core::ops::$trait<$rhs>>::Output; @@ -75,7 +75,7 @@ macro_rules! impl_ref_ops { { impl core::ops::$trait:ident<$rhs:ty> for $type:ty where - $($bound:path: LanesAtMost32,)* + $($bound:path: Vector,)* { $(#[$attrs:meta])* fn $fn:ident(&mut $self_tok:ident, $rhs_arg:ident: $rhs_arg_ty:ty) $body:tt @@ -83,7 +83,7 @@ macro_rules! impl_ref_ops { } => { impl core::ops::$trait<$rhs> for $type where - $($bound: LanesAtMost32,)* + $($bound: Vector,)* { $(#[$attrs])* fn $fn(&mut $self_tok, $rhs_arg: $rhs_arg_ty) $body @@ -91,7 +91,7 @@ macro_rules! impl_ref_ops { impl core::ops::$trait<&'_ $rhs> for $type where - $($bound: LanesAtMost32,)* + $($bound: Vector,)* { $(#[$attrs])* fn $fn(&mut $self_tok, $rhs_arg: &$rhs_arg_ty) { @@ -104,7 +104,7 @@ macro_rules! impl_ref_ops { { impl core::ops::$trait:ident for $type:ty where - $($bound:path: LanesAtMost32,)* + $($bound:path: Vector,)* { type Output = $output:ty; fn $fn:ident($self_tok:ident) -> Self::Output $body:tt @@ -112,7 +112,7 @@ macro_rules! impl_ref_ops { } => { impl core::ops::$trait for $type where - $($bound: LanesAtMost32,)* + $($bound: Vector,)* { type Output = $output; fn $fn($self_tok) -> Self::Output $body @@ -120,7 +120,7 @@ macro_rules! impl_ref_ops { impl core::ops::$trait for &'_ $type where - $($bound: LanesAtMost32,)* + $($bound: Vector,)* { type Output = <$type as core::ops::$trait>::Output; fn $fn($self_tok) -> Self::Output { @@ -167,7 +167,7 @@ macro_rules! impl_op { impl_ref_ops! { impl core::ops::Not for crate::$type where - crate::$type: LanesAtMost32, + crate::$type: Vector, { type Output = Self; fn not(self) -> Self::Output { @@ -181,7 +181,7 @@ macro_rules! impl_op { impl_ref_ops! { impl core::ops::Neg for crate::$type where - crate::$type: LanesAtMost32, + crate::$type: Vector, { type Output = Self; fn neg(self) -> Self::Output { @@ -194,7 +194,7 @@ macro_rules! impl_op { { impl Index for $type:ident, $scalar:ty } => { impl core::ops::Index for crate::$type where - Self: LanesAtMost32, + Self: Vector, I: core::slice::SliceIndex<[$scalar]>, { type Output = I::Output; @@ -206,7 +206,7 @@ macro_rules! impl_op { impl core::ops::IndexMut for crate::$type where - Self: LanesAtMost32, + Self: Vector, I: core::slice::SliceIndex<[$scalar]>, { fn index_mut(&mut self, index: I) -> &mut Self::Output { @@ -221,7 +221,7 @@ macro_rules! impl_op { impl_ref_ops! { impl core::ops::$trait for crate::$type where - crate::$type: LanesAtMost32, + crate::$type: Vector, { type Output = Self; @@ -237,7 +237,7 @@ macro_rules! impl_op { impl_ref_ops! { impl core::ops::$trait<$scalar> for crate::$type where - crate::$type: LanesAtMost32, + crate::$type: Vector, { type Output = Self; @@ -251,7 +251,7 @@ macro_rules! impl_op { impl_ref_ops! { impl core::ops::$trait> for $scalar where - crate::$type: LanesAtMost32, + crate::$type: Vector, { type Output = crate::$type; @@ -265,7 +265,7 @@ macro_rules! impl_op { impl_ref_ops! { impl core::ops::$assign_trait for crate::$type where - crate::$type: LanesAtMost32, + crate::$type: Vector, { #[inline] fn $assign_trait_fn(&mut self, rhs: Self) { @@ -279,7 +279,7 @@ macro_rules! impl_op { impl_ref_ops! { impl core::ops::$assign_trait<$scalar> for crate::$type where - crate::$type: LanesAtMost32, + crate::$type: Vector, { #[inline] fn $assign_trait_fn(&mut self, rhs: $scalar) { @@ -325,7 +325,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Div for crate::$vector where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { type Output = Self; @@ -353,7 +353,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Div<$scalar> for crate::$vector where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { type Output = Self; @@ -376,7 +376,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Div> for $scalar where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { type Output = crate::$vector; @@ -390,7 +390,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::DivAssign for crate::$vector where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { #[inline] fn div_assign(&mut self, rhs: Self) { @@ -402,7 +402,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::DivAssign<$scalar> for crate::$vector where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { #[inline] fn div_assign(&mut self, rhs: $scalar) { @@ -415,7 +415,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Rem for crate::$vector where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { type Output = Self; @@ -443,7 +443,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Rem<$scalar> for crate::$vector where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { type Output = Self; @@ -466,7 +466,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Rem> for $scalar where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { type Output = crate::$vector; @@ -480,7 +480,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::RemAssign for crate::$vector where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { #[inline] fn rem_assign(&mut self, rhs: Self) { @@ -492,7 +492,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::RemAssign<$scalar> for crate::$vector where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { #[inline] fn rem_assign(&mut self, rhs: $scalar) { @@ -505,7 +505,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Shl for crate::$vector where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { type Output = Self; @@ -527,7 +527,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Shl<$scalar> for crate::$vector where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { type Output = Self; @@ -546,7 +546,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::ShlAssign for crate::$vector where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { #[inline] fn shl_assign(&mut self, rhs: Self) { @@ -558,7 +558,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::ShlAssign<$scalar> for crate::$vector where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { #[inline] fn shl_assign(&mut self, rhs: $scalar) { @@ -570,7 +570,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Shr for crate::$vector where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { type Output = Self; @@ -592,7 +592,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Shr<$scalar> for crate::$vector where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { type Output = Self; @@ -611,7 +611,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::ShrAssign for crate::$vector where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { #[inline] fn shr_assign(&mut self, rhs: Self) { @@ -623,7 +623,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::ShrAssign<$scalar> for crate::$vector where - crate::$vector: LanesAtMost32, + crate::$vector: Vector, { #[inline] fn shr_assign(&mut self, rhs: $scalar) { diff --git a/crates/core_simd/src/reduction.rs b/crates/core_simd/src/reduction.rs index 8687d1af5167..548d280b22b5 100644 --- a/crates/core_simd/src/reduction.rs +++ b/crates/core_simd/src/reduction.rs @@ -2,7 +2,7 @@ macro_rules! impl_integer_reductions { { $name:ident, $scalar:ty } => { impl crate::$name where - Self: crate::LanesAtMost32 + Self: crate::Vector { /// Horizontal wrapping add. Returns the sum of the lanes of the vector, with wrapping addition. #[inline] @@ -56,7 +56,7 @@ macro_rules! impl_float_reductions { { $name:ident, $scalar:ty } => { impl crate::$name where - Self: crate::LanesAtMost32 + Self: crate::Vector { /// Horizontal add. Returns the sum of the lanes of the vector. @@ -106,7 +106,7 @@ macro_rules! impl_full_mask_reductions { { $name:ident, $bits_ty:ident } => { impl $name where - crate::$bits_ty: crate::LanesAtMost32 + crate::$bits_ty: crate::Vector { #[inline] pub fn any(self) -> bool { @@ -125,7 +125,7 @@ macro_rules! impl_opaque_mask_reductions { { $name:ident, $bits_ty:ident } => { impl $name where - crate::$bits_ty: crate::LanesAtMost32, + crate::$bits_ty: crate::Vector, $name: crate::Mask, { /// Returns true if any lane is set, or false otherwise. diff --git a/crates/core_simd/src/round.rs b/crates/core_simd/src/round.rs index 281851c68ace..5cd7a898eaf4 100644 --- a/crates/core_simd/src/round.rs +++ b/crates/core_simd/src/round.rs @@ -5,7 +5,7 @@ macro_rules! implement { #[cfg(feature = "std")] impl crate::$type where - Self: crate::LanesAtMost32, + Self: crate::Vector, { /// Returns the smallest integer greater than or equal to each lane. #[must_use = "method returns a new vector and does not mutate the original value"] @@ -45,8 +45,8 @@ macro_rules! implement { impl crate::$type where - Self: crate::LanesAtMost32, - crate::$int_type: crate::LanesAtMost32, + Self: crate::Vector, + crate::$int_type: crate::Vector, { /// Rounds toward zero and converts to the same-width integer type, assuming that /// the value is finite and fits in that type. diff --git a/crates/core_simd/src/select.rs b/crates/core_simd/src/select.rs index dee1d775eb82..1558eb169351 100644 --- a/crates/core_simd/src/select.rs +++ b/crates/core_simd/src/select.rs @@ -14,12 +14,12 @@ macro_rules! impl_select { $mask:ident ($bits_ty:ident): $($type:ident),* } => { $( - impl Sealed for crate::$type where Self: crate::LanesAtMost32 {} + impl Sealed for crate::$type where Self: crate::Vector {} impl Select> for crate::$type where crate::$mask: crate::Mask, - crate::$bits_ty: crate::LanesAtMost32, - Self: crate::LanesAtMost32, + crate::$bits_ty: crate::Vector, + Self: crate::Vector, { #[doc(hidden)] #[inline] @@ -32,12 +32,12 @@ macro_rules! impl_select { impl Sealed for crate::$mask where Self: crate::Mask, - crate::$bits_ty: crate::LanesAtMost32, + crate::$bits_ty: crate::Vector, {} impl Select for crate::$mask where Self: crate::Mask, - crate::$bits_ty: crate::LanesAtMost32, + crate::$bits_ty: crate::Vector, { #[doc(hidden)] #[inline] @@ -49,7 +49,7 @@ macro_rules! impl_select { impl crate::$mask where Self: crate::Mask, - crate::$bits_ty: crate::LanesAtMost32, + crate::$bits_ty: crate::Vector, { /// Choose lanes from two vectors. /// diff --git a/crates/core_simd/src/to_bytes.rs b/crates/core_simd/src/to_bytes.rs index a2d9cc4ef56c..c4f112c9ee7e 100644 --- a/crates/core_simd/src/to_bytes.rs +++ b/crates/core_simd/src/to_bytes.rs @@ -18,11 +18,11 @@ pub trait ToBytes: Sealed { macro_rules! impl_to_bytes { { $name:ident, $($int_width:literal -> $byte_width:literal),* } => { $( - impl Sealed for crate::$name<$int_width> where Self: crate::LanesAtMost32 {} + impl Sealed for crate::$name<$int_width> where Self: crate::Vector {} impl ToBytes for crate::$name<$int_width> where - Self: crate::LanesAtMost32, - crate::SimdU8<$byte_width>: crate::LanesAtMost32, + Self: crate::Vector, + crate::SimdU8<$byte_width>: crate::Vector, { type Bytes = crate::SimdU8<$byte_width>; fn to_bytes_impl(self) -> Self::Bytes { @@ -36,7 +36,7 @@ macro_rules! impl_to_bytes { impl crate::$name where - Self: ToBytes + crate::LanesAtMost32, + Self: ToBytes + crate::Vector, { /// Return the memory representation of this integer as a byte array in native byte /// order. diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs deleted file mode 100644 index 95214ea88642..000000000000 --- a/crates/core_simd/src/vector.rs +++ /dev/null @@ -1,10 +0,0 @@ -mod float; -mod int; -mod uint; - -pub use float::*; -pub use int::*; -pub use uint::*; - -// Vectors of pointers are not for public use at the current time. -pub(crate) mod ptr; diff --git a/crates/core_simd/src/vector/float.rs b/crates/core_simd/src/vector/float.rs index b6e9b61f71f6..4b069a4fab83 100644 --- a/crates/core_simd/src/vector/float.rs +++ b/crates/core_simd/src/vector/float.rs @@ -10,8 +10,8 @@ macro_rules! impl_float_vector { impl $name where - Self: crate::LanesAtMost32, - crate::$bits_ty: crate::LanesAtMost32, + Self: crate::Vector, + crate::$bits_ty: crate::Vector, { /// Raw transmutation to an unsigned integer vector type with the /// same size and number of lanes. @@ -78,9 +78,9 @@ macro_rules! impl_float_vector { impl $name where - Self: crate::LanesAtMost32, - crate::$bits_ty: crate::LanesAtMost32, - crate::$mask_impl_ty: crate::LanesAtMost32, + Self: crate::Vector, + crate::$bits_ty: crate::Vector, + crate::$mask_impl_ty: crate::Vector, crate::$mask_ty: crate::Mask, { /// Returns true for each lane if it has a positive sign, including @@ -197,7 +197,7 @@ macro_rules! impl_float_vector { #[repr(simd)] pub struct SimdF32([f32; LANES]) where - Self: crate::LanesAtMost32; + Self: crate::Vector; impl_float_vector! { SimdF32, f32, SimdU32, Mask32, SimdI32 } @@ -205,7 +205,7 @@ impl_float_vector! { SimdF32, f32, SimdU32, Mask32, SimdI32 } #[repr(simd)] pub struct SimdF64([f64; LANES]) where - Self: crate::LanesAtMost32; + Self: crate::Vector; impl_float_vector! { SimdF64, f64, SimdU64, Mask64, SimdI64 } diff --git a/crates/core_simd/src/vector/int.rs b/crates/core_simd/src/vector/int.rs index 15ad1a7193af..60b3f56d4c4a 100644 --- a/crates/core_simd/src/vector/int.rs +++ b/crates/core_simd/src/vector/int.rs @@ -6,9 +6,9 @@ macro_rules! impl_integer_vector { impl_vector! { $name, $type } impl_integer_reductions! { $name, $type } - impl Eq for $name where Self: crate::LanesAtMost32 {} + impl Eq for $name where Self: crate::Vector {} - impl Ord for $name where Self: crate::LanesAtMost32 { + impl Ord for $name where Self: crate::Vector { #[inline] fn cmp(&self, other: &Self) -> core::cmp::Ordering { // TODO use SIMD cmp @@ -16,7 +16,7 @@ macro_rules! impl_integer_vector { } } - impl core::hash::Hash for $name where Self: crate::LanesAtMost32 { + impl core::hash::Hash for $name where Self: crate::Vector { #[inline] fn hash(&self, state: &mut H) where @@ -28,8 +28,8 @@ macro_rules! impl_integer_vector { impl $name where - Self: crate::LanesAtMost32, - crate::$mask_impl_ty: crate::LanesAtMost32, + Self: crate::Vector, + crate::$mask_impl_ty: crate::Vector, crate::$mask_ty: crate::Mask, { /// Returns true for each positive lane and false if it is zero or negative. @@ -63,7 +63,7 @@ macro_rules! impl_integer_vector { #[repr(simd)] pub struct SimdIsize([isize; LANES]) where - Self: crate::LanesAtMost32; + Self: crate::Vector; impl_integer_vector! { SimdIsize, isize, MaskSize, SimdIsize } @@ -71,7 +71,7 @@ impl_integer_vector! { SimdIsize, isize, MaskSize, SimdIsize } #[repr(simd)] pub struct SimdI16([i16; LANES]) where - Self: crate::LanesAtMost32; + Self: crate::Vector; impl_integer_vector! { SimdI16, i16, Mask16, SimdI16 } @@ -79,7 +79,7 @@ impl_integer_vector! { SimdI16, i16, Mask16, SimdI16 } #[repr(simd)] pub struct SimdI32([i32; LANES]) where - Self: crate::LanesAtMost32; + Self: crate::Vector; impl_integer_vector! { SimdI32, i32, Mask32, SimdI32 } @@ -87,7 +87,7 @@ impl_integer_vector! { SimdI32, i32, Mask32, SimdI32 } #[repr(simd)] pub struct SimdI64([i64; LANES]) where - Self: crate::LanesAtMost32; + Self: crate::Vector; impl_integer_vector! { SimdI64, i64, Mask64, SimdI64 } @@ -95,7 +95,7 @@ impl_integer_vector! { SimdI64, i64, Mask64, SimdI64 } #[repr(simd)] pub struct SimdI8([i8; LANES]) where - Self: crate::LanesAtMost32; + Self: crate::Vector; impl_integer_vector! { SimdI8, i8, Mask8, SimdI8 } diff --git a/crates/core_simd/src/vector/mod.rs b/crates/core_simd/src/vector/mod.rs new file mode 100644 index 000000000000..1af82d9c76ff --- /dev/null +++ b/crates/core_simd/src/vector/mod.rs @@ -0,0 +1,132 @@ +mod float; +mod int; +mod uint; + +pub use float::*; +pub use int::*; +pub use uint::*; + +// Vectors of pointers are not for public use at the current time. +pub(crate) mod ptr; + +mod sealed { + pub trait Sealed {} +} + +/// A representation of a vector as an "array" with indices, implementing +/// operations applicable to any vector type based solely on "having lanes", +/// and describing relationships between vector and scalar types. +pub trait Vector: sealed::Sealed { + /// The scalar type in every lane of this vector type. + type Scalar: Copy + Sized; + + /// The number of lanes for this vector. + const LANES: usize; + + // Implementation detail until the compiler can support bitmasks of any integer width + #[doc(hidden)] + type BitMask: Into; + + /// Generates a SIMD vector with the same value in every lane. + #[must_use] + fn splat(val: Self::Scalar) -> Self; + +} + +macro_rules! impl_vector_for { + ($simd:ident {type Scalar = $scalar:ident;}) => { + impl_vector_for! { $simd<1> { type Scalar = $scalar; type BitMask = u8; } } + impl_vector_for! { $simd<2> { type Scalar = $scalar; type BitMask = u8; } } + impl_vector_for! { $simd<4> { type Scalar = $scalar; type BitMask = u8; } } + impl_vector_for! { $simd<8> { type Scalar = $scalar; type BitMask = u8; } } + impl_vector_for! { $simd<16> { type Scalar = $scalar; type BitMask = u16; } } + impl_vector_for! { $simd<32> { type Scalar = $scalar; type BitMask = u32; } } + }; + ($simd:ident<$lanes:literal> {type Scalar = $scalar:ident; type BitMask = $bitmask:ident; }) => { + impl sealed::Sealed for $simd<$lanes> {} + + impl Vector for $simd<$lanes> { + type Scalar = $scalar; + const LANES: usize = $lanes; + + type BitMask = $bitmask; + + #[inline] + fn splat(val: Self::Scalar) -> Self { + [val; $lanes].into() + } + } + }; +} + +impl_vector_for! { + SimdUsize { + type Scalar = usize; + } +} + +impl_vector_for! { + SimdIsize { + type Scalar = isize; + } +} + +impl_vector_for! { + SimdI8 { + type Scalar = i8; + } +} + +impl_vector_for! { + SimdI16 { + type Scalar = i16; + } +} + +impl_vector_for! { + SimdI32 { + type Scalar = i32; + } +} + +impl_vector_for! { + SimdI64 { + type Scalar = i64; + } +} + +impl_vector_for! { + SimdU8 { + type Scalar = u8; + } +} + +impl_vector_for! { + SimdU16 { + type Scalar = u16; + } +} + +impl_vector_for! { + SimdU32 { + type Scalar = u32; + } +} + +impl_vector_for! { + SimdU64 { + type Scalar = u64; + } +} + +impl_vector_for! { + SimdF32 { + type Scalar = f32; + } +} + +impl_vector_for! { + SimdF64 { + type Scalar = f64; + } +} diff --git a/crates/core_simd/src/vector/ptr.rs b/crates/core_simd/src/vector/ptr.rs index 30bef038b333..bdd5c24eac85 100644 --- a/crates/core_simd/src/vector/ptr.rs +++ b/crates/core_simd/src/vector/ptr.rs @@ -9,7 +9,7 @@ pub(crate) struct SimdConstPtr([*const T; LANES]); impl SimdConstPtr where - SimdUsize: crate::LanesAtMost32, + SimdUsize: crate::Vector, T: Sized, { #[inline] @@ -35,7 +35,7 @@ pub(crate) struct SimdMutPtr([*mut T; LANES]); impl SimdMutPtr where - SimdUsize: crate::LanesAtMost32, + SimdUsize: crate::Vector, T: Sized, { #[inline] diff --git a/crates/core_simd/src/vector/uint.rs b/crates/core_simd/src/vector/uint.rs index 0429410ed6d6..1340bec06f36 100644 --- a/crates/core_simd/src/vector/uint.rs +++ b/crates/core_simd/src/vector/uint.rs @@ -6,9 +6,9 @@ macro_rules! impl_unsigned_vector { impl_vector! { $name, $type } impl_integer_reductions! { $name, $type } - impl Eq for $name where Self: crate::LanesAtMost32 {} + impl Eq for $name where Self: crate::Vector {} - impl Ord for $name where Self: crate::LanesAtMost32 { + impl Ord for $name where Self: crate::Vector { #[inline] fn cmp(&self, other: &Self) -> core::cmp::Ordering { // TODO use SIMD cmp @@ -16,7 +16,7 @@ macro_rules! impl_unsigned_vector { } } - impl core::hash::Hash for $name where Self: crate::LanesAtMost32 { + impl core::hash::Hash for $name where Self: crate::Vector { #[inline] fn hash(&self, state: &mut H) where @@ -32,7 +32,7 @@ macro_rules! impl_unsigned_vector { #[repr(simd)] pub struct SimdUsize([usize; LANES]) where - Self: crate::LanesAtMost32; + Self: crate::Vector; impl_unsigned_vector! { SimdUsize, usize } @@ -40,7 +40,7 @@ impl_unsigned_vector! { SimdUsize, usize } #[repr(simd)] pub struct SimdU16([u16; LANES]) where - Self: crate::LanesAtMost32; + Self: crate::Vector; impl_unsigned_vector! { SimdU16, u16 } @@ -48,7 +48,7 @@ impl_unsigned_vector! { SimdU16, u16 } #[repr(simd)] pub struct SimdU32([u32; LANES]) where - Self: crate::LanesAtMost32; + Self: crate::Vector; impl_unsigned_vector! { SimdU32, u32 } @@ -56,7 +56,7 @@ impl_unsigned_vector! { SimdU32, u32 } #[repr(simd)] pub struct SimdU64([u64; LANES]) where - Self: crate::LanesAtMost32; + Self: crate::Vector; impl_unsigned_vector! { SimdU64, u64 } @@ -64,7 +64,7 @@ impl_unsigned_vector! { SimdU64, u64 } #[repr(simd)] pub struct SimdU8([u8; LANES]) where - Self: crate::LanesAtMost32; + Self: crate::Vector; impl_unsigned_vector! { SimdU8, u8 } diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs index 318a7b3005e3..5691bf4538ce 100644 --- a/crates/test_helpers/src/lib.rs +++ b/crates/test_helpers/src/lib.rs @@ -335,18 +335,18 @@ macro_rules! test_lanes { fn implementation() where - core_simd::SimdU8<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdU16<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdU32<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdU64<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdUsize<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdI8<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdI16<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdI32<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdI64<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdIsize<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdF32<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdF64<$lanes>: core_simd::LanesAtMost32, + core_simd::SimdU8<$lanes>: core_simd::Vector, + core_simd::SimdU16<$lanes>: core_simd::Vector, + core_simd::SimdU32<$lanes>: core_simd::Vector, + core_simd::SimdU64<$lanes>: core_simd::Vector, + core_simd::SimdUsize<$lanes>: core_simd::Vector, + core_simd::SimdI8<$lanes>: core_simd::Vector, + core_simd::SimdI16<$lanes>: core_simd::Vector, + core_simd::SimdI32<$lanes>: core_simd::Vector, + core_simd::SimdI64<$lanes>: core_simd::Vector, + core_simd::SimdIsize<$lanes>: core_simd::Vector, + core_simd::SimdF32<$lanes>: core_simd::Vector, + core_simd::SimdF64<$lanes>: core_simd::Vector, core_simd::Mask8<$lanes>: core_simd::Mask, core_simd::Mask16<$lanes>: core_simd::Mask, core_simd::Mask32<$lanes>: core_simd::Mask, @@ -409,18 +409,18 @@ macro_rules! test_lanes_panic { fn implementation() where - core_simd::SimdU8<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdU16<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdU32<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdU64<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdUsize<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdI8<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdI16<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdI32<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdI64<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdIsize<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdF32<$lanes>: core_simd::LanesAtMost32, - core_simd::SimdF64<$lanes>: core_simd::LanesAtMost32, + core_simd::SimdU8<$lanes>: core_simd::Vector, + core_simd::SimdU16<$lanes>: core_simd::Vector, + core_simd::SimdU32<$lanes>: core_simd::Vector, + core_simd::SimdU64<$lanes>: core_simd::Vector, + core_simd::SimdUsize<$lanes>: core_simd::Vector, + core_simd::SimdI8<$lanes>: core_simd::Vector, + core_simd::SimdI16<$lanes>: core_simd::Vector, + core_simd::SimdI32<$lanes>: core_simd::Vector, + core_simd::SimdI64<$lanes>: core_simd::Vector, + core_simd::SimdIsize<$lanes>: core_simd::Vector, + core_simd::SimdF32<$lanes>: core_simd::Vector, + core_simd::SimdF64<$lanes>: core_simd::Vector, core_simd::Mask8<$lanes>: core_simd::Mask, core_simd::Mask16<$lanes>: core_simd::Mask, core_simd::Mask32<$lanes>: core_simd::Mask, From f178dda187c479f463e74f92e3bdd8be13bad9e7 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sun, 27 Jun 2021 19:38:30 +0000 Subject: [PATCH 2/6] Add as_slice/as_mut_slice to Vector --- crates/core_simd/src/vector/mod.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/crates/core_simd/src/vector/mod.rs b/crates/core_simd/src/vector/mod.rs index 1af82d9c76ff..d1940ab9833d 100644 --- a/crates/core_simd/src/vector/mod.rs +++ b/crates/core_simd/src/vector/mod.rs @@ -31,6 +31,11 @@ pub trait Vector: sealed::Sealed { #[must_use] fn splat(val: Self::Scalar) -> Self; + /// Returns a slice containing the entire SIMD vector. + fn as_slice(&self) -> &[Self::Scalar]; + + /// Returns a mutable slice containing the entire SIMD vector. + fn as_mut_slice(&mut self) -> &mut [Self::Scalar]; } macro_rules! impl_vector_for { @@ -53,7 +58,17 @@ macro_rules! impl_vector_for { #[inline] fn splat(val: Self::Scalar) -> Self { - [val; $lanes].into() + Self::splat(val) + } + + #[inline] + fn as_slice(&self) -> &[Self::Scalar] { + self.as_slice() + } + + #[inline] + fn as_mut_slice(&mut self) -> &mut [Self::Scalar] { + self.as_mut_slice() } } }; From fdd7d6e2529fe5a4921f6ec03e42bacf924246aa Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Mon, 28 Jun 2021 00:41:21 +0000 Subject: [PATCH 3/6] Change as_slice to as_array --- crates/core_simd/src/first.rs | 26 +++++--------------------- crates/core_simd/src/ops.rs | 20 ++++++++++---------- crates/core_simd/src/reduction.rs | 4 ++-- crates/core_simd/src/vector/int.rs | 4 ++-- crates/core_simd/src/vector/mod.rs | 16 ---------------- crates/core_simd/src/vector/uint.rs | 4 ++-- 6 files changed, 21 insertions(+), 53 deletions(-) diff --git a/crates/core_simd/src/first.rs b/crates/core_simd/src/first.rs index 7721b87ecc0b..4560a0a1467c 100644 --- a/crates/core_simd/src/first.rs +++ b/crates/core_simd/src/first.rs @@ -7,13 +7,13 @@ macro_rules! impl_vector { Self([value; LANES]) } - /// Returns a slice containing the entire SIMD vector. - pub const fn as_slice(&self) -> &[$type] { + /// Returns an array reference containing the entire SIMD vector. + pub const fn as_array(&self) -> &[$type; LANES] { &self.0 } - /// Returns a mutable slice containing the entire SIMD vector. - pub fn as_mut_slice(&mut self) -> &mut [$type] { + /// Returns a mutable array reference containing the entire SIMD vector. + pub fn as_mut_array(&mut self) -> &mut [$type; LANES] { &mut self.0 } @@ -24,23 +24,7 @@ macro_rules! impl_vector { /// Converts a SIMD vector to an array. pub const fn to_array(self) -> [$type; LANES] { - // workaround for rust-lang/rust#80108 - // TODO fix this - #[cfg(target_arch = "wasm32")] - { - let mut arr = [self.0[0]; LANES]; - let mut i = 0; - while i < LANES { - arr[i] = self.0[i]; - i += 1; - } - arr - } - - #[cfg(not(target_arch = "wasm32"))] - { - self.0 - } + self.0 } } diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs index a41782a1464f..9491bdd1d5a6 100644 --- a/crates/core_simd/src/ops.rs +++ b/crates/core_simd/src/ops.rs @@ -331,7 +331,7 @@ macro_rules! impl_unsigned_int_ops { #[inline] fn div(self, rhs: Self) -> Self::Output { - if rhs.as_slice() + if rhs.as_array() .iter() .any(|x| *x == 0) { @@ -340,8 +340,8 @@ macro_rules! impl_unsigned_int_ops { // Guards for div(MIN, -1), // this check only applies to signed ints - if <$scalar>::MIN != 0 && self.as_slice().iter() - .zip(rhs.as_slice().iter()) + if <$scalar>::MIN != 0 && self.as_array().iter() + .zip(rhs.as_array().iter()) .any(|(x,y)| *x == <$scalar>::MIN && *y == -1 as _) { panic!("attempt to divide with overflow"); } @@ -363,7 +363,7 @@ macro_rules! impl_unsigned_int_ops { panic!("attempt to divide by zero"); } if <$scalar>::MIN != 0 && - self.as_slice().iter().any(|x| *x == <$scalar>::MIN) && + self.as_array().iter().any(|x| *x == <$scalar>::MIN) && rhs == -1 as _ { panic!("attempt to divide with overflow"); } @@ -421,7 +421,7 @@ macro_rules! impl_unsigned_int_ops { #[inline] fn rem(self, rhs: Self) -> Self::Output { - if rhs.as_slice() + if rhs.as_array() .iter() .any(|x| *x == 0) { @@ -430,8 +430,8 @@ macro_rules! impl_unsigned_int_ops { // Guards for rem(MIN, -1) // this branch applies the check only to signed ints - if <$scalar>::MIN != 0 && self.as_slice().iter() - .zip(rhs.as_slice().iter()) + if <$scalar>::MIN != 0 && self.as_array().iter() + .zip(rhs.as_array().iter()) .any(|(x,y)| *x == <$scalar>::MIN && *y == -1 as _) { panic!("attempt to calculate the remainder with overflow"); } @@ -453,7 +453,7 @@ macro_rules! impl_unsigned_int_ops { panic!("attempt to calculate the remainder with a divisor of zero"); } if <$scalar>::MIN != 0 && - self.as_slice().iter().any(|x| *x == <$scalar>::MIN) && + self.as_array().iter().any(|x| *x == <$scalar>::MIN) && rhs == -1 as _ { panic!("attempt to calculate the remainder with overflow"); } @@ -512,7 +512,7 @@ macro_rules! impl_unsigned_int_ops { #[inline] fn shl(self, rhs: Self) -> Self::Output { // TODO there is probably a better way of doing this - if rhs.as_slice() + if rhs.as_array() .iter() .copied() .any(invalid_shift_rhs) @@ -577,7 +577,7 @@ macro_rules! impl_unsigned_int_ops { #[inline] fn shr(self, rhs: Self) -> Self::Output { // TODO there is probably a better way of doing this - if rhs.as_slice() + if rhs.as_array() .iter() .copied() .any(invalid_shift_rhs) diff --git a/crates/core_simd/src/reduction.rs b/crates/core_simd/src/reduction.rs index 548d280b22b5..41cf6fab612a 100644 --- a/crates/core_simd/src/reduction.rs +++ b/crates/core_simd/src/reduction.rs @@ -64,7 +64,7 @@ macro_rules! impl_float_reductions { pub fn horizontal_sum(self) -> $scalar { // LLVM sum is inaccurate on i586 if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) { - self.as_slice().iter().sum() + self.as_array().iter().sum() } else { unsafe { crate::intrinsics::simd_reduce_add_ordered(self, 0.) } } @@ -75,7 +75,7 @@ macro_rules! impl_float_reductions { pub fn horizontal_product(self) -> $scalar { // LLVM product is inaccurate on i586 if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) { - self.as_slice().iter().product() + self.as_array().iter().product() } else { unsafe { crate::intrinsics::simd_reduce_mul_ordered(self, 1.) } } diff --git a/crates/core_simd/src/vector/int.rs b/crates/core_simd/src/vector/int.rs index 60b3f56d4c4a..0ca1ea14e2d5 100644 --- a/crates/core_simd/src/vector/int.rs +++ b/crates/core_simd/src/vector/int.rs @@ -12,7 +12,7 @@ macro_rules! impl_integer_vector { #[inline] fn cmp(&self, other: &Self) -> core::cmp::Ordering { // TODO use SIMD cmp - self.to_array().cmp(other.as_ref()) + self.as_array().cmp(other.as_ref()) } } @@ -22,7 +22,7 @@ macro_rules! impl_integer_vector { where H: core::hash::Hasher { - self.as_slice().hash(state) + self.as_array().hash(state) } } diff --git a/crates/core_simd/src/vector/mod.rs b/crates/core_simd/src/vector/mod.rs index d1940ab9833d..a7adca80f8bd 100644 --- a/crates/core_simd/src/vector/mod.rs +++ b/crates/core_simd/src/vector/mod.rs @@ -30,12 +30,6 @@ pub trait Vector: sealed::Sealed { /// Generates a SIMD vector with the same value in every lane. #[must_use] fn splat(val: Self::Scalar) -> Self; - - /// Returns a slice containing the entire SIMD vector. - fn as_slice(&self) -> &[Self::Scalar]; - - /// Returns a mutable slice containing the entire SIMD vector. - fn as_mut_slice(&mut self) -> &mut [Self::Scalar]; } macro_rules! impl_vector_for { @@ -60,16 +54,6 @@ macro_rules! impl_vector_for { fn splat(val: Self::Scalar) -> Self { Self::splat(val) } - - #[inline] - fn as_slice(&self) -> &[Self::Scalar] { - self.as_slice() - } - - #[inline] - fn as_mut_slice(&mut self) -> &mut [Self::Scalar] { - self.as_mut_slice() - } } }; } diff --git a/crates/core_simd/src/vector/uint.rs b/crates/core_simd/src/vector/uint.rs index 1340bec06f36..e7a6a8880121 100644 --- a/crates/core_simd/src/vector/uint.rs +++ b/crates/core_simd/src/vector/uint.rs @@ -12,7 +12,7 @@ macro_rules! impl_unsigned_vector { #[inline] fn cmp(&self, other: &Self) -> core::cmp::Ordering { // TODO use SIMD cmp - self.to_array().cmp(other.as_ref()) + self.as_array().cmp(other.as_ref()) } } @@ -22,7 +22,7 @@ macro_rules! impl_unsigned_vector { where H: core::hash::Hasher { - self.as_slice().hash(state) + self.as_array().hash(state) } } } From 529ffe05d6111afe110226ba6ebc577d1414d452 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Tue, 29 Jun 2021 21:48:54 +0000 Subject: [PATCH 4/6] Use new module naming --- crates/core_simd/src/{masks/mod.rs => masks.rs} | 4 ++-- crates/core_simd/src/{vector/mod.rs => vector.rs} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename crates/core_simd/src/{masks/mod.rs => masks.rs} (99%) rename crates/core_simd/src/{vector/mod.rs => vector.rs} (100%) diff --git a/crates/core_simd/src/masks/mod.rs b/crates/core_simd/src/masks.rs similarity index 99% rename from crates/core_simd/src/masks/mod.rs rename to crates/core_simd/src/masks.rs index 43e689d45bc7..a4ed3b4a071c 100644 --- a/crates/core_simd/src/masks/mod.rs +++ b/crates/core_simd/src/masks.rs @@ -4,11 +4,11 @@ #[cfg_attr( not(all(target_arch = "x86_64", target_feature = "avx512f")), - path = "full_masks.rs" + path = "masks/full_masks.rs" )] #[cfg_attr( all(target_arch = "x86_64", target_feature = "avx512f"), - path = "bitmask.rs" + path = "masks/bitmask.rs" )] mod mask_impl; diff --git a/crates/core_simd/src/vector/mod.rs b/crates/core_simd/src/vector.rs similarity index 100% rename from crates/core_simd/src/vector/mod.rs rename to crates/core_simd/src/vector.rs From f93bef35f35579b60c8b919844a2021f3f035daa Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Tue, 29 Jun 2021 22:08:50 +0000 Subject: [PATCH 5/6] Move vector implementation --- crates/core_simd/src/lib.rs | 2 - crates/core_simd/src/vector.rs | 101 +----------------- .../src/{first.rs => vector/vector_impl.rs} | 30 ++++++ 3 files changed, 33 insertions(+), 100 deletions(-) rename crates/core_simd/src/{first.rs => vector/vector_impl.rs} (90%) diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs index eb580dcf14d8..2f0f851a92f1 100644 --- a/crates/core_simd/src/lib.rs +++ b/crates/core_simd/src/lib.rs @@ -12,8 +12,6 @@ #![unstable(feature = "portable_simd", issue = "86656")] //! Portable SIMD module. -#[macro_use] -mod first; #[macro_use] mod permute; #[macro_use] diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs index a7adca80f8bd..2bc7c1cd2b74 100644 --- a/crates/core_simd/src/vector.rs +++ b/crates/core_simd/src/vector.rs @@ -1,3 +1,6 @@ +#[macro_use] +mod vector_impl; + mod float; mod int; mod uint; @@ -31,101 +34,3 @@ pub trait Vector: sealed::Sealed { #[must_use] fn splat(val: Self::Scalar) -> Self; } - -macro_rules! impl_vector_for { - ($simd:ident {type Scalar = $scalar:ident;}) => { - impl_vector_for! { $simd<1> { type Scalar = $scalar; type BitMask = u8; } } - impl_vector_for! { $simd<2> { type Scalar = $scalar; type BitMask = u8; } } - impl_vector_for! { $simd<4> { type Scalar = $scalar; type BitMask = u8; } } - impl_vector_for! { $simd<8> { type Scalar = $scalar; type BitMask = u8; } } - impl_vector_for! { $simd<16> { type Scalar = $scalar; type BitMask = u16; } } - impl_vector_for! { $simd<32> { type Scalar = $scalar; type BitMask = u32; } } - }; - ($simd:ident<$lanes:literal> {type Scalar = $scalar:ident; type BitMask = $bitmask:ident; }) => { - impl sealed::Sealed for $simd<$lanes> {} - - impl Vector for $simd<$lanes> { - type Scalar = $scalar; - const LANES: usize = $lanes; - - type BitMask = $bitmask; - - #[inline] - fn splat(val: Self::Scalar) -> Self { - Self::splat(val) - } - } - }; -} - -impl_vector_for! { - SimdUsize { - type Scalar = usize; - } -} - -impl_vector_for! { - SimdIsize { - type Scalar = isize; - } -} - -impl_vector_for! { - SimdI8 { - type Scalar = i8; - } -} - -impl_vector_for! { - SimdI16 { - type Scalar = i16; - } -} - -impl_vector_for! { - SimdI32 { - type Scalar = i32; - } -} - -impl_vector_for! { - SimdI64 { - type Scalar = i64; - } -} - -impl_vector_for! { - SimdU8 { - type Scalar = u8; - } -} - -impl_vector_for! { - SimdU16 { - type Scalar = u16; - } -} - -impl_vector_for! { - SimdU32 { - type Scalar = u32; - } -} - -impl_vector_for! { - SimdU64 { - type Scalar = u64; - } -} - -impl_vector_for! { - SimdF32 { - type Scalar = f32; - } -} - -impl_vector_for! { - SimdF64 { - type Scalar = f64; - } -} diff --git a/crates/core_simd/src/first.rs b/crates/core_simd/src/vector/vector_impl.rs similarity index 90% rename from crates/core_simd/src/first.rs rename to crates/core_simd/src/vector/vector_impl.rs index 4560a0a1467c..e166a93670b8 100644 --- a/crates/core_simd/src/first.rs +++ b/crates/core_simd/src/vector/vector_impl.rs @@ -1,6 +1,36 @@ +macro_rules! impl_vector_trait { + ($simd:ident {type Scalar = $scalar:ty;}) => { + impl_vector_trait! { $simd<1> { type Scalar = $scalar; type BitMask = u8; } } + impl_vector_trait! { $simd<2> { type Scalar = $scalar; type BitMask = u8; } } + impl_vector_trait! { $simd<4> { type Scalar = $scalar; type BitMask = u8; } } + impl_vector_trait! { $simd<8> { type Scalar = $scalar; type BitMask = u8; } } + impl_vector_trait! { $simd<16> { type Scalar = $scalar; type BitMask = u16; } } + impl_vector_trait! { $simd<32> { type Scalar = $scalar; type BitMask = u32; } } + }; + ($simd:ident<$lanes:literal> {type Scalar = $scalar:ty; type BitMask = $bitmask:ident; }) => { + impl crate::vector::sealed::Sealed for $simd<$lanes> {} + + impl crate::vector::Vector for $simd<$lanes> { + type Scalar = $scalar; + const LANES: usize = $lanes; + + type BitMask = $bitmask; + + #[inline] + fn splat(val: Self::Scalar) -> Self { + Self::splat(val) + } + } + }; +} + /// Implements common traits on the specified vector `$name`, holding multiple `$lanes` of `$type`. macro_rules! impl_vector { { $name:ident, $type:ty } => { + impl_vector_trait! { + $name { type Scalar = $type; } + } + impl $name where Self: crate::Vector { /// Construct a SIMD vector by setting all lanes to the given value. pub const fn splat(value: $type) -> Self { From 97c25dd7465f4db60c013d7688b809a7da5388a6 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sat, 24 Jul 2021 02:54:19 +0000 Subject: [PATCH 6/6] Add lane count marker type --- crates/core_simd/src/comparisons.rs | 6 +- crates/core_simd/src/fmt.rs | 2 +- crates/core_simd/src/iter.rs | 10 +- crates/core_simd/src/lane_count.rs | 43 ++++++ crates/core_simd/src/lib.rs | 4 +- crates/core_simd/src/masks.rs | 150 ++++++++------------ crates/core_simd/src/masks/bitmask.rs | 151 +++++++++++---------- crates/core_simd/src/masks/full_masks.rs | 101 +++++++------- crates/core_simd/src/math.rs | 4 +- crates/core_simd/src/ops.rs | 78 +++++------ crates/core_simd/src/reduction.rs | 11 +- crates/core_simd/src/round.rs | 8 +- crates/core_simd/src/select.rs | 16 +-- crates/core_simd/src/to_bytes.rs | 12 +- crates/core_simd/src/vector.rs | 4 - crates/core_simd/src/vector/float.rs | 17 +-- crates/core_simd/src/vector/int.rs | 25 ++-- crates/core_simd/src/vector/ptr.rs | 6 +- crates/core_simd/src/vector/uint.rs | 21 +-- crates/core_simd/src/vector/vector_impl.rs | 73 ++++------ crates/test_helpers/src/lib.rs | 36 +---- 21 files changed, 367 insertions(+), 411 deletions(-) create mode 100644 crates/core_simd/src/lane_count.rs diff --git a/crates/core_simd/src/comparisons.rs b/crates/core_simd/src/comparisons.rs index c3bf07fc4320..c5e9be9015fe 100644 --- a/crates/core_simd/src/comparisons.rs +++ b/crates/core_simd/src/comparisons.rs @@ -1,13 +1,11 @@ -use crate::Vector; +use crate::{LaneCount, SupportedLaneCount}; macro_rules! implement_mask_ops { { $($vector:ident => $mask:ident ($inner_ty:ident),)* } => { $( impl crate::$vector where - crate::$vector: Vector, - crate::$inner_ty: Vector, - crate::$mask: crate::Mask, + LaneCount: SupportedLaneCount, { /// Test if each lane is equal to the corresponding lane in `other`. #[inline] diff --git a/crates/core_simd/src/fmt.rs b/crates/core_simd/src/fmt.rs index 554aa91a5f0c..78ae5ce3fcea 100644 --- a/crates/core_simd/src/fmt.rs +++ b/crates/core_simd/src/fmt.rs @@ -35,7 +35,7 @@ macro_rules! impl_fmt_trait { $( // repeat trait impl core::fmt::$trait for crate::$type where - Self: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { $format(self.as_ref(), f) diff --git a/crates/core_simd/src/iter.rs b/crates/core_simd/src/iter.rs index 460c061be69f..0020ea5f2016 100644 --- a/crates/core_simd/src/iter.rs +++ b/crates/core_simd/src/iter.rs @@ -1,8 +1,10 @@ +use crate::{LaneCount, SupportedLaneCount}; + macro_rules! impl_traits { { $type:ident } => { impl core::iter::Sum for crate::$type where - Self: crate::Vector, + LaneCount: SupportedLaneCount, { fn sum>(iter: I) -> Self { iter.fold(Default::default(), core::ops::Add::add) @@ -11,7 +13,7 @@ macro_rules! impl_traits { impl core::iter::Product for crate::$type where - Self: crate::Vector, + LaneCount: SupportedLaneCount, { fn product>(iter: I) -> Self { iter.fold(Default::default(), core::ops::Mul::mul) @@ -20,7 +22,7 @@ macro_rules! impl_traits { impl<'a, const LANES: usize> core::iter::Sum<&'a Self> for crate::$type where - Self: crate::Vector, + LaneCount: SupportedLaneCount, { fn sum>(iter: I) -> Self { iter.fold(Default::default(), core::ops::Add::add) @@ -29,7 +31,7 @@ macro_rules! impl_traits { impl<'a, const LANES: usize> core::iter::Product<&'a Self> for crate::$type where - Self: crate::Vector, + LaneCount: SupportedLaneCount, { fn product>(iter: I) -> Self { iter.fold(Default::default(), core::ops::Mul::mul) diff --git a/crates/core_simd/src/lane_count.rs b/crates/core_simd/src/lane_count.rs new file mode 100644 index 000000000000..8fe204dff98e --- /dev/null +++ b/crates/core_simd/src/lane_count.rs @@ -0,0 +1,43 @@ +mod sealed { + pub trait Sealed {} +} +use sealed::Sealed; + +/// A type representing a vector lane count. +pub struct LaneCount; + +/// Helper trait for vector lane counts. +pub trait SupportedLaneCount: Sealed { + /// The bitmask representation of a mask. + type BitMask: Copy + Default + AsRef<[u8]> + AsMut<[u8]>; + + #[doc(hidden)] + type IntBitMask; +} + +impl Sealed for LaneCount {} + +impl SupportedLaneCount for LaneCount<1> { + type BitMask = [u8; 1]; + type IntBitMask = u8; +} +impl SupportedLaneCount for LaneCount<2> { + type BitMask = [u8; 1]; + type IntBitMask = u8; +} +impl SupportedLaneCount for LaneCount<4> { + type BitMask = [u8; 1]; + type IntBitMask = u8; +} +impl SupportedLaneCount for LaneCount<8> { + type BitMask = [u8; 1]; + type IntBitMask = u8; +} +impl SupportedLaneCount for LaneCount<16> { + type BitMask = [u8; 2]; + type IntBitMask = u16; +} +impl SupportedLaneCount for LaneCount<32> { + type BitMask = [u8; 4]; + type IntBitMask = u32; +} diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs index 2f0f851a92f1..d8149efe9c7f 100644 --- a/crates/core_simd/src/lib.rs +++ b/crates/core_simd/src/lib.rs @@ -27,11 +27,13 @@ mod comparisons; mod fmt; mod intrinsics; mod iter; +mod math; mod ops; mod round; mod vendor; -mod math; +mod lane_count; +pub use lane_count::*; mod masks; pub use masks::*; diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks.rs index a4ed3b4a071c..d3338a6d366e 100644 --- a/crates/core_simd/src/masks.rs +++ b/crates/core_simd/src/masks.rs @@ -12,7 +12,7 @@ )] mod mask_impl; -use crate::{SimdI16, SimdI32, SimdI64, SimdI8, SimdIsize, Vector}; +use crate::{SimdI16, SimdI32, SimdI64, SimdI8, SimdIsize}; mod sealed { pub trait Sealed {} @@ -20,12 +20,12 @@ mod sealed { /// Helper trait for mask types. pub trait Mask: sealed::Sealed { - /// The bitmask representation of a mask. - type BitMask: Copy + Default + AsRef<[u8]> + AsMut<[u8]>; + /// The number of lanes for this mask. + const LANES: usize; - // TODO remove this when rustc intrinsics are more flexible - #[doc(hidden)] - type IntBitMask; + /// Generates a mask with the same value in every lane. + #[must_use] + fn splat(val: bool) -> Self; } macro_rules! define_opaque_mask { @@ -38,45 +38,30 @@ macro_rules! define_opaque_mask { #[allow(non_camel_case_types)] pub struct $name($inner_ty) where - $bits_ty: Vector, - Self: Mask; + crate::LaneCount: crate::SupportedLaneCount; impl sealed::Sealed for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, {} - impl Mask for $name<1> { - type BitMask = [u8; 1]; - type IntBitMask = u8; - } - impl Mask for $name<2> { - type BitMask = [u8; 1]; - type IntBitMask = u8; - } - impl Mask for $name<4> { - type BitMask = [u8; 1]; - type IntBitMask = u8; - } - impl Mask for $name<8> { - type BitMask = [u8; 1]; - type IntBitMask = u8; - } - impl Mask for $name<16> { - type BitMask = [u8; 2]; - type IntBitMask = u16; - } - impl Mask for $name<32> { - type BitMask = [u8; 4]; - type IntBitMask = u32; + + impl Mask for $name + where + crate::LaneCount: crate::SupportedLaneCount, + { + const LANES: usize = LANES; + + #[inline] + fn splat(value: bool) -> Self { + Self::splat(value) + } } impl_opaque_mask_reductions! { $name, $bits_ty } impl $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { /// Construct a mask by setting all lanes to the given value. pub fn splat(value: bool) -> Self { @@ -175,21 +160,20 @@ macro_rules! define_opaque_mask { } /// Convert this mask to a bitmask, with one bit set per lane. - pub fn to_bitmask(self) -> ::BitMask { - self.0.to_bitmask::() + pub fn to_bitmask(self) -> as crate::SupportedLaneCount>::BitMask { + self.0.to_bitmask() } /// Convert a bitmask to a mask. - pub fn from_bitmask(bitmask: ::BitMask) -> Self { - Self(<$inner_ty>::from_bitmask::(bitmask)) + pub fn from_bitmask(bitmask: as crate::SupportedLaneCount>::BitMask) -> Self { + Self(<$inner_ty>::from_bitmask(bitmask)) } } // vector/array conversion impl From<[bool; LANES]> for $name where - $bits_ty: crate::Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { fn from(array: [bool; LANES]) -> Self { Self::from_array(array) @@ -198,8 +182,7 @@ macro_rules! define_opaque_mask { impl From<$name> for [bool; LANES] where - $bits_ty: crate::Vector, - $name: Mask, + crate::LaneCount: crate::SupportedLaneCount, { fn from(vector: $name) -> Self { vector.to_array() @@ -208,14 +191,12 @@ macro_rules! define_opaque_mask { impl Copy for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, {} impl Clone for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { #[inline] fn clone(&self) -> Self { @@ -225,8 +206,7 @@ macro_rules! define_opaque_mask { impl Default for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { #[inline] fn default() -> Self { @@ -236,8 +216,7 @@ macro_rules! define_opaque_mask { impl PartialEq for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { #[inline] fn eq(&self, other: &Self) -> bool { @@ -247,8 +226,7 @@ macro_rules! define_opaque_mask { impl PartialOrd for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { #[inline] fn partial_cmp(&self, other: &Self) -> Option { @@ -258,8 +236,7 @@ macro_rules! define_opaque_mask { impl core::fmt::Debug for $name where - $bits_ty: crate::Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { f.debug_list() @@ -270,8 +247,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitAnd for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { type Output = Self; #[inline] @@ -282,8 +258,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitAnd for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { type Output = Self; #[inline] @@ -294,8 +269,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitAnd<$name> for bool where - $bits_ty: Vector, - $name: Mask, + crate::LaneCount: crate::SupportedLaneCount, { type Output = $name; #[inline] @@ -306,8 +280,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitOr for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { type Output = Self; #[inline] @@ -318,8 +291,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitOr for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { type Output = Self; #[inline] @@ -330,8 +302,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitOr<$name> for bool where - $bits_ty: Vector, - $name: Mask, + crate::LaneCount: crate::SupportedLaneCount, { type Output = $name; #[inline] @@ -342,8 +313,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitXor for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { type Output = Self; #[inline] @@ -354,8 +324,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitXor for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { type Output = Self; #[inline] @@ -366,8 +335,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitXor<$name> for bool where - $bits_ty: Vector, - $name: Mask, + crate::LaneCount: crate::SupportedLaneCount, { type Output = $name; #[inline] @@ -378,8 +346,7 @@ macro_rules! define_opaque_mask { impl core::ops::Not for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { type Output = $name; #[inline] @@ -390,8 +357,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitAndAssign for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { #[inline] fn bitand_assign(&mut self, rhs: Self) { @@ -401,8 +367,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitAndAssign for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { #[inline] fn bitand_assign(&mut self, rhs: bool) { @@ -412,8 +377,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitOrAssign for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { #[inline] fn bitor_assign(&mut self, rhs: Self) { @@ -423,8 +387,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitOrAssign for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { #[inline] fn bitor_assign(&mut self, rhs: bool) { @@ -434,8 +397,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitXorAssign for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { #[inline] fn bitxor_assign(&mut self, rhs: Self) { @@ -445,8 +407,7 @@ macro_rules! define_opaque_mask { impl core::ops::BitXorAssign for $name where - $bits_ty: Vector, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { #[inline] fn bitxor_assign(&mut self, rhs: bool) { @@ -460,7 +421,7 @@ define_opaque_mask! { /// Mask for vectors with `LANES` 8-bit elements. /// /// The layout of this type is unspecified. - struct Mask8(mask_impl::Mask8); + struct Mask8(mask_impl::Mask8); @bits SimdI8 } @@ -468,7 +429,7 @@ define_opaque_mask! { /// Mask for vectors with `LANES` 16-bit elements. /// /// The layout of this type is unspecified. - struct Mask16(mask_impl::Mask16); + struct Mask16(mask_impl::Mask16); @bits SimdI16 } @@ -476,7 +437,7 @@ define_opaque_mask! { /// Mask for vectors with `LANES` 32-bit elements. /// /// The layout of this type is unspecified. - struct Mask32(mask_impl::Mask32); + struct Mask32(mask_impl::Mask32); @bits SimdI32 } @@ -484,7 +445,7 @@ define_opaque_mask! { /// Mask for vectors with `LANES` 64-bit elements. /// /// The layout of this type is unspecified. - struct Mask64(mask_impl::Mask64); + struct Mask64(mask_impl::Mask64); @bits SimdI64 } @@ -492,7 +453,7 @@ define_opaque_mask! { /// Mask for vectors with `LANES` pointer-width elements. /// /// The layout of this type is unspecified. - struct MaskSize(mask_impl::MaskSize); + struct MaskSize(mask_impl::MaskSize); @bits SimdIsize } @@ -555,10 +516,7 @@ macro_rules! impl_from { $( impl From<$from> for $to where - crate::$from_inner: crate::Vector, - crate::$to_inner: crate::Vector, - $from: Mask, - Self: Mask, + crate::LaneCount: crate::SupportedLaneCount, { fn from(value: $from) -> Self { Self(value.0.into()) diff --git a/crates/core_simd/src/masks/bitmask.rs b/crates/core_simd/src/masks/bitmask.rs index a64750a623f7..b6897728988b 100644 --- a/crates/core_simd/src/masks/bitmask.rs +++ b/crates/core_simd/src/masks/bitmask.rs @@ -1,50 +1,81 @@ -use crate::Mask; -use core::marker::PhantomData; +use crate::{LaneCount, SupportedLaneCount}; /// Helper trait for limiting int conversion types pub trait ConvertToInt {} -impl ConvertToInt for crate::SimdI8 where Self: crate::Vector {} -impl ConvertToInt for crate::SimdI16 where Self: crate::Vector {} -impl ConvertToInt for crate::SimdI32 where Self: crate::Vector {} -impl ConvertToInt for crate::SimdI64 where Self: crate::Vector {} -impl ConvertToInt for crate::SimdIsize where Self: crate::Vector {} +impl ConvertToInt for crate::SimdI8 where + LaneCount: SupportedLaneCount +{ +} +impl ConvertToInt for crate::SimdI16 where + LaneCount: SupportedLaneCount +{ +} +impl ConvertToInt for crate::SimdI32 where + LaneCount: SupportedLaneCount +{ +} +impl ConvertToInt for crate::SimdI64 where + LaneCount: SupportedLaneCount +{ +} +impl ConvertToInt for crate::SimdIsize where + LaneCount: SupportedLaneCount +{ +} /// A mask where each lane is represented by a single bit. #[repr(transparent)] -pub struct BitMask(T::BitMask, PhantomData<[(); LANES]>); +pub struct BitMask( as SupportedLaneCount>::BitMask) +where + LaneCount: SupportedLaneCount; -impl Copy for BitMask {} +impl Copy for BitMask where LaneCount: SupportedLaneCount {} -impl Clone for BitMask { +impl Clone for BitMask +where + LaneCount: SupportedLaneCount, +{ fn clone(&self) -> Self { *self } } -impl PartialEq for BitMask { +impl PartialEq for BitMask +where + LaneCount: SupportedLaneCount, +{ fn eq(&self, other: &Self) -> bool { self.0.as_ref() == other.0.as_ref() } } -impl PartialOrd for BitMask { +impl PartialOrd for BitMask +where + LaneCount: SupportedLaneCount, +{ fn partial_cmp(&self, other: &Self) -> Option { self.0.as_ref().partial_cmp(other.0.as_ref()) } } -impl Eq for BitMask {} +impl Eq for BitMask where LaneCount: SupportedLaneCount {} -impl Ord for BitMask { +impl Ord for BitMask +where + LaneCount: SupportedLaneCount, +{ fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.0.as_ref().cmp(other.0.as_ref()) } } -impl BitMask { +impl BitMask +where + LaneCount: SupportedLaneCount, +{ #[inline] pub fn splat(value: bool) -> Self { - let mut mask = T::BitMask::default(); + let mut mask = as SupportedLaneCount>::BitMask::default(); if value { mask.as_mut().fill(u8::MAX) } else { @@ -53,12 +84,12 @@ impl BitMask { if LANES % 8 > 0 { *mask.as_mut().last_mut().unwrap() &= u8::MAX >> (8 - LANES % 8); } - Self(mask, PhantomData) + Self(mask) } #[inline] pub unsafe fn test_unchecked(&self, lane: usize) -> bool { - (self.0.as_ref()[lane / 8] >> lane % 8) & 0x1 > 0 + (self.0.as_ref()[lane / 8] >> (lane % 8)) & 0x1 > 0 } #[inline] @@ -72,7 +103,8 @@ impl BitMask { V: ConvertToInt + Default + core::ops::Not, { unsafe { - let mask: T::IntBitMask = core::mem::transmute_copy(&self); + let mask: as SupportedLaneCount>::IntBitMask = + core::mem::transmute_copy(&self); crate::intrinsics::simd_select_bitmask(mask, !V::default(), V::default()) } } @@ -84,29 +116,25 @@ impl BitMask { { // TODO remove the transmute when rustc is more flexible assert_eq!( - core::mem::size_of::(), - core::mem::size_of::() + core::mem::size_of::< as crate::SupportedLaneCount>::BitMask>( + ), + core::mem::size_of::< + as crate::SupportedLaneCount>::IntBitMask, + >(), ); - let mask: T::IntBitMask = crate::intrinsics::simd_bitmask(value); - Self(core::mem::transmute_copy(&mask), PhantomData) + let mask: as SupportedLaneCount>::IntBitMask = + crate::intrinsics::simd_bitmask(value); + Self(core::mem::transmute_copy(&mask)) } #[inline] - pub fn to_bitmask(self) -> U::BitMask { - assert_eq!( - core::mem::size_of::(), - core::mem::size_of::() - ); - unsafe { core::mem::transmute_copy(&self.0) } + pub fn to_bitmask(self) -> as SupportedLaneCount>::BitMask { + self.0 } #[inline] - pub fn from_bitmask(bitmask: U::BitMask) -> Self { - assert_eq!( - core::mem::size_of::(), - core::mem::size_of::() - ); - unsafe { core::mem::transmute_copy(&bitmask) } + pub fn from_bitmask(bitmask: as SupportedLaneCount>::BitMask) -> Self { + Self(bitmask) } #[inline] @@ -120,9 +148,10 @@ impl BitMask { } } -impl core::ops::BitAnd for BitMask +impl core::ops::BitAnd for BitMask where - T::BitMask: Default + AsRef<[u8]> + AsMut<[u8]>, + LaneCount: SupportedLaneCount, + as SupportedLaneCount>::BitMask: Default + AsRef<[u8]> + AsMut<[u8]>, { type Output = Self; #[inline] @@ -134,9 +163,10 @@ where } } -impl core::ops::BitOr for BitMask +impl core::ops::BitOr for BitMask where - T::BitMask: Default + AsRef<[u8]> + AsMut<[u8]>, + LaneCount: SupportedLaneCount, + as SupportedLaneCount>::BitMask: Default + AsRef<[u8]> + AsMut<[u8]>, { type Output = Self; #[inline] @@ -148,7 +178,10 @@ where } } -impl core::ops::BitXor for BitMask { +impl core::ops::BitXor for BitMask +where + LaneCount: SupportedLaneCount, +{ type Output = Self; #[inline] fn bitxor(mut self, rhs: Self) -> Self::Output { @@ -159,7 +192,10 @@ impl core::ops::BitXor for BitMask { } } -impl core::ops::Not for BitMask { +impl core::ops::Not for BitMask +where + LaneCount: SupportedLaneCount, +{ type Output = Self; #[inline] fn not(mut self) -> Self::Output { @@ -173,31 +209,8 @@ impl core::ops::Not for BitMask { } } -pub type Mask8 = BitMask; -pub type Mask16 = BitMask; -pub type Mask32 = BitMask; -pub type Mask64 = BitMask; -pub type MaskSize = BitMask; - -macro_rules! impl_from { - { $from:ident ($from_inner:ident) => $($to:ident ($to_inner:ident)),* } => { - $( - impl From<$from, LANES>> for $to, LANES> - where - crate::$from_inner: crate::Vector, - crate::$to_inner: crate::Vector, - crate::$from: crate::Mask, - crate::$to: crate::Mask, - { - fn from(value: $from, 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) } +pub type Mask8 = BitMask; +pub type Mask16 = BitMask; +pub type Mask32 = BitMask; +pub type Mask64 = BitMask; +pub type MaskSize = BitMask; diff --git a/crates/core_simd/src/masks/full_masks.rs b/crates/core_simd/src/masks/full_masks.rs index f083284df8fa..af36571134ee 100644 --- a/crates/core_simd/src/masks/full_masks.rs +++ b/crates/core_simd/src/masks/full_masks.rs @@ -1,8 +1,5 @@ //! Masks that take up full SIMD vector registers. -use crate::Mask; -use core::marker::PhantomData; - macro_rules! define_mask { { $(#[$attr:meta])* @@ -12,20 +9,20 @@ macro_rules! define_mask { } => { $(#[$attr])* #[repr(transparent)] - pub struct $name(crate::$type<$lanes2>, PhantomData) + pub struct $name(crate::$type<$lanes>) where - crate::$type: crate::Vector; + crate::LaneCount<$lanes>: crate::SupportedLaneCount; impl_full_mask_reductions! { $name, $type } - impl Copy for $name + impl Copy for $name where - crate::$type: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, {} - impl Clone for $name + impl Clone for $name where - crate::$type: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, { #[inline] fn clone(&self) -> Self { @@ -33,41 +30,41 @@ macro_rules! define_mask { } } - impl PartialEq for $name + impl PartialEq for $name where - crate::$type: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } - impl PartialOrd for $name + impl PartialOrd for $name where - crate::$type: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, { fn partial_cmp(&self, other: &Self) -> Option { self.0.partial_cmp(&other.0) } } - impl Eq for $name + impl Eq for $name where - crate::$type: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, {} - impl Ord for $name + impl Ord for $name where - crate::$type: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, { fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.0.cmp(&other.0) } } - impl $name + impl $name where - crate::$type: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, { pub fn splat(value: bool) -> Self { Self( @@ -78,7 +75,6 @@ macro_rules! define_mask { 0 } ), - PhantomData, ) } @@ -103,16 +99,19 @@ macro_rules! define_mask { #[inline] pub unsafe fn from_int_unchecked(value: crate::$type) -> Self { - Self(value, PhantomData) + Self(value) } #[inline] - pub fn to_bitmask(self) -> U::BitMask { + pub fn to_bitmask(self) -> as crate::SupportedLaneCount>::BitMask { unsafe { - // TODO remove the transmute when rustc is more flexible - assert_eq!(core::mem::size_of::(), core::mem::size_of::()); - let mask: U::IntBitMask = crate::intrinsics::simd_bitmask(self.0); - let mut bitmask: U::BitMask = core::mem::transmute_copy(&mask); + // TODO remove the transmute when rustc can use arrays of u8 as bitmasks + assert_eq!( + core::mem::size_of::< as crate::SupportedLaneCount>::BitMask>(), + core::mem::size_of::< as crate::SupportedLaneCount>::IntBitMask>(), + ); + let bitmask: as crate::SupportedLaneCount>::IntBitMask = crate::intrinsics::simd_bitmask(self.0); + let mut bitmask: as crate::SupportedLaneCount>::BitMask = core::mem::transmute_copy(&bitmask); // There is a bug where LLVM appears to implement this operation with the wrong // bit order. @@ -128,7 +127,7 @@ macro_rules! define_mask { } #[inline] - pub fn from_bitmask(mut bitmask: U::BitMask) -> Self { + pub fn from_bitmask(mut bitmask: as crate::SupportedLaneCount>::BitMask) -> Self { unsafe { // There is a bug where LLVM appears to implement this operation with the wrong // bit order. @@ -139,9 +138,12 @@ macro_rules! define_mask { } } - // TODO remove the transmute when rustc is more flexible - assert_eq!(core::mem::size_of::(), core::mem::size_of::()); - let bitmask: U::IntBitMask = core::mem::transmute_copy(&bitmask); + // TODO remove the transmute when rustc can use arrays of u8 as bitmasks + assert_eq!( + core::mem::size_of::< as crate::SupportedLaneCount>::BitMask>(), + core::mem::size_of::< as crate::SupportedLaneCount>::IntBitMask>(), + ); + let bitmask: as crate::SupportedLaneCount>::IntBitMask = core::mem::transmute_copy(&bitmask); Self::from_int_unchecked(crate::intrinsics::simd_select_bitmask( bitmask, @@ -152,56 +154,56 @@ macro_rules! define_mask { } } - impl core::convert::From<$name> for crate::$type + impl core::convert::From<$name> for crate::$type where - crate::$type: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, { - fn from(value: $name) -> Self { + fn from(value: $name) -> Self { value.0 } } - impl core::ops::BitAnd for $name + impl core::ops::BitAnd for $name where - crate::$type: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, { type Output = Self; #[inline] fn bitand(self, rhs: Self) -> Self { - Self(self.0 & rhs.0, PhantomData) + Self(self.0 & rhs.0) } } - impl core::ops::BitOr for $name + impl core::ops::BitOr for $name where - crate::$type: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, { type Output = Self; #[inline] fn bitor(self, rhs: Self) -> Self { - Self(self.0 | rhs.0, PhantomData) + Self(self.0 | rhs.0) } } - impl core::ops::BitXor for $name + impl core::ops::BitXor for $name where - crate::$type: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, { type Output = Self; #[inline] fn bitxor(self, rhs: Self) -> Self::Output { - Self(self.0 ^ rhs.0, PhantomData) + Self(self.0 ^ rhs.0) } } - impl core::ops::Not for $name + impl core::ops::Not for $name where - crate::$type: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, { type Output = Self; #[inline] fn not(self) -> Self::Output { - Self(!self.0, PhantomData) + Self(!self.0) } } } @@ -240,14 +242,11 @@ define_mask! { macro_rules! impl_from { { $from:ident ($from_inner:ident) => $($to:ident ($to_inner:ident)),* } => { $( - impl From<$from> for $to + impl From<$from> for $to where - crate::$from_inner: crate::Vector, - crate::$to_inner: crate::Vector, - T: crate::Mask, - U: crate::Mask, + crate::LaneCount: crate::SupportedLaneCount, { - fn from(value: $from) -> Self { + fn from(value: $from) -> Self { let mut new = Self::splat(false); for i in 0..LANES { unsafe { new.set_unchecked(i, value.test_unchecked(i)) } diff --git a/crates/core_simd/src/math.rs b/crates/core_simd/src/math.rs index cc0330871136..28720eb13e3c 100644 --- a/crates/core_simd/src/math.rs +++ b/crates/core_simd/src/math.rs @@ -1,6 +1,6 @@ macro_rules! impl_uint_arith { ($(($name:ident, $n:ident)),+) => { - $( impl $name where Self: crate::Vector { + $( impl $name where crate::LaneCount: crate::SupportedLaneCount { /// Lanewise saturating add. /// @@ -44,7 +44,7 @@ macro_rules! impl_uint_arith { macro_rules! impl_int_arith { ($(($name:ident, $n:ident)),+) => { - $( impl $name where Self: crate::Vector { + $( impl $name where crate::LaneCount: crate::SupportedLaneCount { /// Lanewise saturating add. /// diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs index 9491bdd1d5a6..c75090aab9c5 100644 --- a/crates/core_simd/src/ops.rs +++ b/crates/core_simd/src/ops.rs @@ -1,4 +1,4 @@ -use crate::Vector; +use crate::{LaneCount, SupportedLaneCount}; /// Checks if the right-hand side argument of a left- or right-shift would cause overflow. fn invalid_shift_rhs(rhs: T) -> bool @@ -16,7 +16,7 @@ macro_rules! impl_ref_ops { { impl core::ops::$trait:ident<$rhs:ty> for $type:ty where - $($bound:path: Vector,)* + LaneCount<$lanes2:ident>: SupportedLaneCount, { type Output = $output:ty; @@ -26,7 +26,7 @@ macro_rules! impl_ref_ops { } => { impl core::ops::$trait<$rhs> for $type where - $($bound: Vector,)* + LaneCount<$lanes2>: SupportedLaneCount, { type Output = $output; @@ -36,7 +36,7 @@ macro_rules! impl_ref_ops { impl core::ops::$trait<&'_ $rhs> for $type where - $($bound: Vector,)* + LaneCount<$lanes2>: SupportedLaneCount, { type Output = <$type as core::ops::$trait<$rhs>>::Output; @@ -48,7 +48,7 @@ macro_rules! impl_ref_ops { impl core::ops::$trait<$rhs> for &'_ $type where - $($bound: Vector,)* + LaneCount<$lanes2>: SupportedLaneCount, { type Output = <$type as core::ops::$trait<$rhs>>::Output; @@ -60,7 +60,7 @@ macro_rules! impl_ref_ops { impl core::ops::$trait<&'_ $rhs> for &'_ $type where - $($bound: Vector,)* + LaneCount<$lanes2>: SupportedLaneCount, { type Output = <$type as core::ops::$trait<$rhs>>::Output; @@ -75,7 +75,7 @@ macro_rules! impl_ref_ops { { impl core::ops::$trait:ident<$rhs:ty> for $type:ty where - $($bound:path: Vector,)* + LaneCount<$lanes2:ident>: SupportedLaneCount, { $(#[$attrs:meta])* fn $fn:ident(&mut $self_tok:ident, $rhs_arg:ident: $rhs_arg_ty:ty) $body:tt @@ -83,7 +83,7 @@ macro_rules! impl_ref_ops { } => { impl core::ops::$trait<$rhs> for $type where - $($bound: Vector,)* + LaneCount<$lanes2>: SupportedLaneCount, { $(#[$attrs])* fn $fn(&mut $self_tok, $rhs_arg: $rhs_arg_ty) $body @@ -91,7 +91,7 @@ macro_rules! impl_ref_ops { impl core::ops::$trait<&'_ $rhs> for $type where - $($bound: Vector,)* + LaneCount<$lanes2>: SupportedLaneCount, { $(#[$attrs])* fn $fn(&mut $self_tok, $rhs_arg: &$rhs_arg_ty) { @@ -104,7 +104,7 @@ macro_rules! impl_ref_ops { { impl core::ops::$trait:ident for $type:ty where - $($bound:path: Vector,)* + LaneCount<$lanes2:ident>: SupportedLaneCount, { type Output = $output:ty; fn $fn:ident($self_tok:ident) -> Self::Output $body:tt @@ -112,7 +112,7 @@ macro_rules! impl_ref_ops { } => { impl core::ops::$trait for $type where - $($bound: Vector,)* + LaneCount<$lanes2>: SupportedLaneCount, { type Output = $output; fn $fn($self_tok) -> Self::Output $body @@ -120,7 +120,7 @@ macro_rules! impl_ref_ops { impl core::ops::$trait for &'_ $type where - $($bound: Vector,)* + LaneCount<$lanes2>: SupportedLaneCount, { type Output = <$type as core::ops::$trait>::Output; fn $fn($self_tok) -> Self::Output { @@ -167,7 +167,7 @@ macro_rules! impl_op { impl_ref_ops! { impl core::ops::Not for crate::$type where - crate::$type: Vector, + LaneCount: SupportedLaneCount, { type Output = Self; fn not(self) -> Self::Output { @@ -181,7 +181,7 @@ macro_rules! impl_op { impl_ref_ops! { impl core::ops::Neg for crate::$type where - crate::$type: Vector, + LaneCount: SupportedLaneCount, { type Output = Self; fn neg(self) -> Self::Output { @@ -194,7 +194,7 @@ macro_rules! impl_op { { impl Index for $type:ident, $scalar:ty } => { impl core::ops::Index for crate::$type where - Self: Vector, + LaneCount: SupportedLaneCount, I: core::slice::SliceIndex<[$scalar]>, { type Output = I::Output; @@ -206,7 +206,7 @@ macro_rules! impl_op { impl core::ops::IndexMut for crate::$type where - Self: Vector, + LaneCount: SupportedLaneCount, I: core::slice::SliceIndex<[$scalar]>, { fn index_mut(&mut self, index: I) -> &mut Self::Output { @@ -221,7 +221,7 @@ macro_rules! impl_op { impl_ref_ops! { impl core::ops::$trait for crate::$type where - crate::$type: Vector, + LaneCount: SupportedLaneCount, { type Output = Self; @@ -237,7 +237,7 @@ macro_rules! impl_op { impl_ref_ops! { impl core::ops::$trait<$scalar> for crate::$type where - crate::$type: Vector, + LaneCount: SupportedLaneCount, { type Output = Self; @@ -251,7 +251,7 @@ macro_rules! impl_op { impl_ref_ops! { impl core::ops::$trait> for $scalar where - crate::$type: Vector, + LaneCount: SupportedLaneCount, { type Output = crate::$type; @@ -265,7 +265,7 @@ macro_rules! impl_op { impl_ref_ops! { impl core::ops::$assign_trait for crate::$type where - crate::$type: Vector, + LaneCount: SupportedLaneCount, { #[inline] fn $assign_trait_fn(&mut self, rhs: Self) { @@ -279,7 +279,7 @@ macro_rules! impl_op { impl_ref_ops! { impl core::ops::$assign_trait<$scalar> for crate::$type where - crate::$type: Vector, + LaneCount: SupportedLaneCount, { #[inline] fn $assign_trait_fn(&mut self, rhs: $scalar) { @@ -325,7 +325,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Div for crate::$vector where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { type Output = Self; @@ -353,7 +353,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Div<$scalar> for crate::$vector where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { type Output = Self; @@ -376,7 +376,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Div> for $scalar where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { type Output = crate::$vector; @@ -390,7 +390,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::DivAssign for crate::$vector where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { #[inline] fn div_assign(&mut self, rhs: Self) { @@ -402,7 +402,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::DivAssign<$scalar> for crate::$vector where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { #[inline] fn div_assign(&mut self, rhs: $scalar) { @@ -415,7 +415,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Rem for crate::$vector where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { type Output = Self; @@ -443,7 +443,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Rem<$scalar> for crate::$vector where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { type Output = Self; @@ -466,7 +466,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Rem> for $scalar where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { type Output = crate::$vector; @@ -480,7 +480,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::RemAssign for crate::$vector where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { #[inline] fn rem_assign(&mut self, rhs: Self) { @@ -492,7 +492,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::RemAssign<$scalar> for crate::$vector where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { #[inline] fn rem_assign(&mut self, rhs: $scalar) { @@ -505,7 +505,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Shl for crate::$vector where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { type Output = Self; @@ -527,7 +527,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Shl<$scalar> for crate::$vector where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { type Output = Self; @@ -546,7 +546,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::ShlAssign for crate::$vector where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { #[inline] fn shl_assign(&mut self, rhs: Self) { @@ -558,7 +558,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::ShlAssign<$scalar> for crate::$vector where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { #[inline] fn shl_assign(&mut self, rhs: $scalar) { @@ -570,7 +570,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Shr for crate::$vector where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { type Output = Self; @@ -592,7 +592,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::Shr<$scalar> for crate::$vector where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { type Output = Self; @@ -611,7 +611,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::ShrAssign for crate::$vector where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { #[inline] fn shr_assign(&mut self, rhs: Self) { @@ -623,7 +623,7 @@ macro_rules! impl_unsigned_int_ops { impl_ref_ops! { impl core::ops::ShrAssign<$scalar> for crate::$vector where - crate::$vector: Vector, + LaneCount: SupportedLaneCount, { #[inline] fn shr_assign(&mut self, rhs: $scalar) { diff --git a/crates/core_simd/src/reduction.rs b/crates/core_simd/src/reduction.rs index 41cf6fab612a..df227d09e342 100644 --- a/crates/core_simd/src/reduction.rs +++ b/crates/core_simd/src/reduction.rs @@ -2,7 +2,7 @@ macro_rules! impl_integer_reductions { { $name:ident, $scalar:ty } => { impl crate::$name where - Self: crate::Vector + crate::LaneCount: crate::SupportedLaneCount, { /// Horizontal wrapping add. Returns the sum of the lanes of the vector, with wrapping addition. #[inline] @@ -56,7 +56,7 @@ macro_rules! impl_float_reductions { { $name:ident, $scalar:ty } => { impl crate::$name where - Self: crate::Vector + crate::LaneCount: crate::SupportedLaneCount, { /// Horizontal add. Returns the sum of the lanes of the vector. @@ -104,9 +104,9 @@ macro_rules! impl_float_reductions { macro_rules! impl_full_mask_reductions { { $name:ident, $bits_ty:ident } => { - impl $name + impl $name where - crate::$bits_ty: crate::Vector + crate::LaneCount: crate::SupportedLaneCount, { #[inline] pub fn any(self) -> bool { @@ -125,8 +125,7 @@ macro_rules! impl_opaque_mask_reductions { { $name:ident, $bits_ty:ident } => { impl $name where - crate::$bits_ty: crate::Vector, - $name: crate::Mask, + crate::LaneCount: crate::SupportedLaneCount, { /// Returns true if any lane is set, or false otherwise. #[inline] diff --git a/crates/core_simd/src/round.rs b/crates/core_simd/src/round.rs index 5cd7a898eaf4..74cae0cf9898 100644 --- a/crates/core_simd/src/round.rs +++ b/crates/core_simd/src/round.rs @@ -5,7 +5,7 @@ macro_rules! implement { #[cfg(feature = "std")] impl crate::$type where - Self: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, { /// Returns the smallest integer greater than or equal to each lane. #[must_use = "method returns a new vector and does not mutate the original value"] @@ -41,13 +41,7 @@ macro_rules! implement { pub fn fract(self) -> Self { self - self.trunc() } - } - impl crate::$type - where - Self: crate::Vector, - crate::$int_type: crate::Vector, - { /// Rounds toward zero and converts to the same-width integer type, assuming that /// the value is finite and fits in that type. /// diff --git a/crates/core_simd/src/select.rs b/crates/core_simd/src/select.rs index 1558eb169351..d70e8a66b95f 100644 --- a/crates/core_simd/src/select.rs +++ b/crates/core_simd/src/select.rs @@ -14,12 +14,10 @@ macro_rules! impl_select { $mask:ident ($bits_ty:ident): $($type:ident),* } => { $( - impl Sealed for crate::$type where Self: crate::Vector {} + impl Sealed for crate::$type where crate::LaneCount: crate::SupportedLaneCount {} impl Select> for crate::$type where - crate::$mask: crate::Mask, - crate::$bits_ty: crate::Vector, - Self: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, { #[doc(hidden)] #[inline] @@ -31,13 +29,12 @@ macro_rules! impl_select { impl Sealed for crate::$mask where - Self: crate::Mask, - crate::$bits_ty: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, {} + impl Select for crate::$mask where - Self: crate::Mask, - crate::$bits_ty: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, { #[doc(hidden)] #[inline] @@ -48,8 +45,7 @@ macro_rules! impl_select { impl crate::$mask where - Self: crate::Mask, - crate::$bits_ty: crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, { /// Choose lanes from two vectors. /// diff --git a/crates/core_simd/src/to_bytes.rs b/crates/core_simd/src/to_bytes.rs index c4f112c9ee7e..0823391049fd 100644 --- a/crates/core_simd/src/to_bytes.rs +++ b/crates/core_simd/src/to_bytes.rs @@ -18,11 +18,14 @@ pub trait ToBytes: Sealed { macro_rules! impl_to_bytes { { $name:ident, $($int_width:literal -> $byte_width:literal),* } => { $( - impl Sealed for crate::$name<$int_width> where Self: crate::Vector {} + impl Sealed for crate::$name<$int_width> + where + crate::LaneCount<$int_width>: crate::SupportedLaneCount, + {} + impl ToBytes for crate::$name<$int_width> where - Self: crate::Vector, - crate::SimdU8<$byte_width>: crate::Vector, + crate::LaneCount<$int_width>: crate::SupportedLaneCount, { type Bytes = crate::SimdU8<$byte_width>; fn to_bytes_impl(self) -> Self::Bytes { @@ -36,7 +39,8 @@ macro_rules! impl_to_bytes { impl crate::$name where - Self: ToBytes + crate::Vector, + crate::LaneCount: crate::SupportedLaneCount, + Self: ToBytes, { /// Return the memory representation of this integer as a byte array in native byte /// order. diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs index 2bc7c1cd2b74..1f6df533767e 100644 --- a/crates/core_simd/src/vector.rs +++ b/crates/core_simd/src/vector.rs @@ -26,10 +26,6 @@ pub trait Vector: sealed::Sealed { /// The number of lanes for this vector. const LANES: usize; - // Implementation detail until the compiler can support bitmasks of any integer width - #[doc(hidden)] - type BitMask: Into; - /// Generates a SIMD vector with the same value in every lane. #[must_use] fn splat(val: Self::Scalar) -> Self; diff --git a/crates/core_simd/src/vector/float.rs b/crates/core_simd/src/vector/float.rs index 4b069a4fab83..bdeccd037a80 100644 --- a/crates/core_simd/src/vector/float.rs +++ b/crates/core_simd/src/vector/float.rs @@ -1,5 +1,7 @@ #![allow(non_camel_case_types)] +use crate::{LaneCount, SupportedLaneCount}; + /// Implements inherent methods for a float vector `$name` containing multiple /// `$lanes` of float `$type`, which uses `$bits_ty` as its binary /// representation. Called from `define_float_vector!`. @@ -10,8 +12,7 @@ macro_rules! impl_float_vector { impl $name where - Self: crate::Vector, - crate::$bits_ty: crate::Vector, + LaneCount: SupportedLaneCount, { /// Raw transmutation to an unsigned integer vector type with the /// same size and number of lanes. @@ -74,15 +75,7 @@ macro_rules! impl_float_vector { pub fn to_radians(self) -> Self { self * Self::splat($type::to_radians(1.)) } - } - impl $name - where - Self: crate::Vector, - crate::$bits_ty: crate::Vector, - crate::$mask_impl_ty: crate::Vector, - crate::$mask_ty: crate::Mask, - { /// Returns true for each lane if it has a positive sign, including /// `+0.0`, `NaN`s with positive sign bit and positive infinity. #[inline] @@ -197,7 +190,7 @@ macro_rules! impl_float_vector { #[repr(simd)] pub struct SimdF32([f32; LANES]) where - Self: crate::Vector; + LaneCount: SupportedLaneCount; impl_float_vector! { SimdF32, f32, SimdU32, Mask32, SimdI32 } @@ -205,7 +198,7 @@ impl_float_vector! { SimdF32, f32, SimdU32, Mask32, SimdI32 } #[repr(simd)] pub struct SimdF64([f64; LANES]) where - Self: crate::Vector; + LaneCount: SupportedLaneCount; impl_float_vector! { SimdF64, f64, SimdU64, Mask64, SimdI64 } diff --git a/crates/core_simd/src/vector/int.rs b/crates/core_simd/src/vector/int.rs index 0ca1ea14e2d5..73c737762fb6 100644 --- a/crates/core_simd/src/vector/int.rs +++ b/crates/core_simd/src/vector/int.rs @@ -1,14 +1,16 @@ #![allow(non_camel_case_types)] +use crate::{LaneCount, SupportedLaneCount}; + /// Implements additional integer traits (Eq, Ord, Hash) on the specified vector `$name`, holding multiple `$lanes` of `$type`. macro_rules! impl_integer_vector { { $name:ident, $type:ty, $mask_ty:ident, $mask_impl_ty:ident } => { impl_vector! { $name, $type } impl_integer_reductions! { $name, $type } - impl Eq for $name where Self: crate::Vector {} + impl Eq for $name where LaneCount: SupportedLaneCount {} - impl Ord for $name where Self: crate::Vector { + impl Ord for $name where LaneCount: SupportedLaneCount { #[inline] fn cmp(&self, other: &Self) -> core::cmp::Ordering { // TODO use SIMD cmp @@ -16,7 +18,10 @@ macro_rules! impl_integer_vector { } } - impl core::hash::Hash for $name where Self: crate::Vector { + impl core::hash::Hash for $name + where + LaneCount: SupportedLaneCount, + { #[inline] fn hash(&self, state: &mut H) where @@ -28,9 +33,7 @@ macro_rules! impl_integer_vector { impl $name where - Self: crate::Vector, - crate::$mask_impl_ty: crate::Vector, - crate::$mask_ty: crate::Mask, + LaneCount: SupportedLaneCount, { /// Returns true for each positive lane and false if it is zero or negative. #[inline] @@ -63,7 +66,7 @@ macro_rules! impl_integer_vector { #[repr(simd)] pub struct SimdIsize([isize; LANES]) where - Self: crate::Vector; + LaneCount: SupportedLaneCount; impl_integer_vector! { SimdIsize, isize, MaskSize, SimdIsize } @@ -71,7 +74,7 @@ impl_integer_vector! { SimdIsize, isize, MaskSize, SimdIsize } #[repr(simd)] pub struct SimdI16([i16; LANES]) where - Self: crate::Vector; + LaneCount: SupportedLaneCount; impl_integer_vector! { SimdI16, i16, Mask16, SimdI16 } @@ -79,7 +82,7 @@ impl_integer_vector! { SimdI16, i16, Mask16, SimdI16 } #[repr(simd)] pub struct SimdI32([i32; LANES]) where - Self: crate::Vector; + LaneCount: SupportedLaneCount; impl_integer_vector! { SimdI32, i32, Mask32, SimdI32 } @@ -87,7 +90,7 @@ impl_integer_vector! { SimdI32, i32, Mask32, SimdI32 } #[repr(simd)] pub struct SimdI64([i64; LANES]) where - Self: crate::Vector; + LaneCount: SupportedLaneCount; impl_integer_vector! { SimdI64, i64, Mask64, SimdI64 } @@ -95,7 +98,7 @@ impl_integer_vector! { SimdI64, i64, Mask64, SimdI64 } #[repr(simd)] pub struct SimdI8([i8; LANES]) where - Self: crate::Vector; + LaneCount: SupportedLaneCount; impl_integer_vector! { SimdI8, i8, Mask8, SimdI8 } diff --git a/crates/core_simd/src/vector/ptr.rs b/crates/core_simd/src/vector/ptr.rs index bdd5c24eac85..9dd1bfd0f365 100644 --- a/crates/core_simd/src/vector/ptr.rs +++ b/crates/core_simd/src/vector/ptr.rs @@ -1,5 +1,5 @@ //! Private implementation details of public gather/scatter APIs. -use crate::SimdUsize; +use crate::{LaneCount, SimdUsize, SupportedLaneCount}; use core::mem; /// A vector of *const T. @@ -9,7 +9,7 @@ pub(crate) struct SimdConstPtr([*const T; LANES]); impl SimdConstPtr where - SimdUsize: crate::Vector, + LaneCount: SupportedLaneCount, T: Sized, { #[inline] @@ -35,7 +35,7 @@ pub(crate) struct SimdMutPtr([*mut T; LANES]); impl SimdMutPtr where - SimdUsize: crate::Vector, + LaneCount: SupportedLaneCount, T: Sized, { #[inline] diff --git a/crates/core_simd/src/vector/uint.rs b/crates/core_simd/src/vector/uint.rs index e7a6a8880121..b19f694872ae 100644 --- a/crates/core_simd/src/vector/uint.rs +++ b/crates/core_simd/src/vector/uint.rs @@ -1,14 +1,16 @@ #![allow(non_camel_case_types)] +use crate::{LaneCount, SupportedLaneCount}; + /// Implements additional integer traits (Eq, Ord, Hash) on the specified vector `$name`, holding multiple `$lanes` of `$type`. macro_rules! impl_unsigned_vector { { $name:ident, $type:ty } => { impl_vector! { $name, $type } impl_integer_reductions! { $name, $type } - impl Eq for $name where Self: crate::Vector {} + impl Eq for $name where LaneCount: SupportedLaneCount {} - impl Ord for $name where Self: crate::Vector { + impl Ord for $name where LaneCount: SupportedLaneCount { #[inline] fn cmp(&self, other: &Self) -> core::cmp::Ordering { // TODO use SIMD cmp @@ -16,7 +18,10 @@ macro_rules! impl_unsigned_vector { } } - impl core::hash::Hash for $name where Self: crate::Vector { + impl core::hash::Hash for $name + where + LaneCount: SupportedLaneCount, + { #[inline] fn hash(&self, state: &mut H) where @@ -32,7 +37,7 @@ macro_rules! impl_unsigned_vector { #[repr(simd)] pub struct SimdUsize([usize; LANES]) where - Self: crate::Vector; + LaneCount: SupportedLaneCount; impl_unsigned_vector! { SimdUsize, usize } @@ -40,7 +45,7 @@ impl_unsigned_vector! { SimdUsize, usize } #[repr(simd)] pub struct SimdU16([u16; LANES]) where - Self: crate::Vector; + LaneCount: SupportedLaneCount; impl_unsigned_vector! { SimdU16, u16 } @@ -48,7 +53,7 @@ impl_unsigned_vector! { SimdU16, u16 } #[repr(simd)] pub struct SimdU32([u32; LANES]) where - Self: crate::Vector; + LaneCount: SupportedLaneCount; impl_unsigned_vector! { SimdU32, u32 } @@ -56,7 +61,7 @@ impl_unsigned_vector! { SimdU32, u32 } #[repr(simd)] pub struct SimdU64([u64; LANES]) where - Self: crate::Vector; + LaneCount: SupportedLaneCount; impl_unsigned_vector! { SimdU64, u64 } @@ -64,7 +69,7 @@ impl_unsigned_vector! { SimdU64, u64 } #[repr(simd)] pub struct SimdU8([u8; LANES]) where - Self: crate::Vector; + LaneCount: SupportedLaneCount; impl_unsigned_vector! { SimdU8, u8 } diff --git a/crates/core_simd/src/vector/vector_impl.rs b/crates/core_simd/src/vector/vector_impl.rs index e166a93670b8..58ea244adfcb 100644 --- a/crates/core_simd/src/vector/vector_impl.rs +++ b/crates/core_simd/src/vector/vector_impl.rs @@ -1,37 +1,28 @@ -macro_rules! impl_vector_trait { - ($simd:ident {type Scalar = $scalar:ty;}) => { - impl_vector_trait! { $simd<1> { type Scalar = $scalar; type BitMask = u8; } } - impl_vector_trait! { $simd<2> { type Scalar = $scalar; type BitMask = u8; } } - impl_vector_trait! { $simd<4> { type Scalar = $scalar; type BitMask = u8; } } - impl_vector_trait! { $simd<8> { type Scalar = $scalar; type BitMask = u8; } } - impl_vector_trait! { $simd<16> { type Scalar = $scalar; type BitMask = u16; } } - impl_vector_trait! { $simd<32> { type Scalar = $scalar; type BitMask = u32; } } - }; - ($simd:ident<$lanes:literal> {type Scalar = $scalar:ty; type BitMask = $bitmask:ident; }) => { - impl crate::vector::sealed::Sealed for $simd<$lanes> {} +/// Implements common traits on the specified vector `$name`, holding multiple `$lanes` of `$type`. +macro_rules! impl_vector { + { $name:ident, $type:ty } => { + impl crate::vector::sealed::Sealed for $name + where + crate::LaneCount: crate::SupportedLaneCount, + {} - impl crate::vector::Vector for $simd<$lanes> { - type Scalar = $scalar; - const LANES: usize = $lanes; - - type BitMask = $bitmask; + impl crate::vector::Vector for $name + where + crate::LaneCount: crate::SupportedLaneCount, + { + type Scalar = $type; + const LANES: usize = LANES; #[inline] fn splat(val: Self::Scalar) -> Self { Self::splat(val) } } - }; -} -/// Implements common traits on the specified vector `$name`, holding multiple `$lanes` of `$type`. -macro_rules! impl_vector { - { $name:ident, $type:ty } => { - impl_vector_trait! { - $name { type Scalar = $type; } - } - - impl $name where Self: crate::Vector { + impl $name + where + crate::LaneCount: crate::SupportedLaneCount, + { /// Construct a SIMD vector by setting all lanes to the given value. pub const fn splat(value: $type) -> Self { Self([value; LANES]) @@ -56,15 +47,7 @@ macro_rules! impl_vector { pub const fn to_array(self) -> [$type; LANES] { self.0 } - } - impl $name - where - Self: crate::Vector, - crate::MaskSize: crate::Mask, - crate::SimdIsize: crate::Vector, - crate::SimdUsize: crate::Vector, - { /// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices. /// If an index is out of bounds, that lane instead selects the value from the "or" vector. /// ``` @@ -194,23 +177,23 @@ macro_rules! impl_vector { } } - impl Copy for $name where Self: crate::Vector {} + impl Copy for $name where crate::LaneCount: crate::SupportedLaneCount {} - impl Clone for $name where Self: crate::Vector { + impl Clone for $name where crate::LaneCount: crate::SupportedLaneCount { #[inline] fn clone(&self) -> Self { *self } } - impl Default for $name where Self: crate::Vector { + impl Default for $name where crate::LaneCount: crate::SupportedLaneCount { #[inline] fn default() -> Self { Self::splat(<$type>::default()) } } - impl PartialEq for $name where Self: crate::Vector { + impl PartialEq for $name where crate::LaneCount: crate::SupportedLaneCount { #[inline] fn eq(&self, other: &Self) -> bool { // TODO use SIMD equality @@ -218,7 +201,7 @@ macro_rules! impl_vector { } } - impl PartialOrd for $name where Self: crate::Vector { + impl PartialOrd for $name where crate::LaneCount: crate::SupportedLaneCount { #[inline] fn partial_cmp(&self, other: &Self) -> Option { // TODO use SIMD equalitya @@ -227,14 +210,14 @@ macro_rules! impl_vector { } // array references - impl AsRef<[$type; LANES]> for $name where Self: crate::Vector { + impl AsRef<[$type; LANES]> for $name where crate::LaneCount: crate::SupportedLaneCount { #[inline] fn as_ref(&self) -> &[$type; LANES] { &self.0 } } - impl AsMut<[$type; LANES]> for $name where Self: crate::Vector { + impl AsMut<[$type; LANES]> for $name where crate::LaneCount: crate::SupportedLaneCount { #[inline] fn as_mut(&mut self) -> &mut [$type; LANES] { &mut self.0 @@ -242,14 +225,14 @@ macro_rules! impl_vector { } // slice references - impl AsRef<[$type]> for $name where Self: crate::Vector { + impl AsRef<[$type]> for $name where crate::LaneCount: crate::SupportedLaneCount { #[inline] fn as_ref(&self) -> &[$type] { &self.0 } } - impl AsMut<[$type]> for $name where Self: crate::Vector { + impl AsMut<[$type]> for $name where crate::LaneCount: crate::SupportedLaneCount { #[inline] fn as_mut(&mut self) -> &mut [$type] { &mut self.0 @@ -257,13 +240,13 @@ macro_rules! impl_vector { } // vector/array conversion - impl From<[$type; LANES]> for $name where Self: crate::Vector { + impl From<[$type; LANES]> for $name where crate::LaneCount: crate::SupportedLaneCount { fn from(array: [$type; LANES]) -> Self { Self(array) } } - impl From<$name> for [$type; LANES] where $name: crate::Vector { + impl From<$name> for [$type; LANES] where crate::LaneCount: crate::SupportedLaneCount { fn from(vector: $name) -> Self { vector.to_array() } diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs index 5691bf4538ce..5c6478876f30 100644 --- a/crates/test_helpers/src/lib.rs +++ b/crates/test_helpers/src/lib.rs @@ -335,23 +335,7 @@ macro_rules! test_lanes { fn implementation() where - core_simd::SimdU8<$lanes>: core_simd::Vector, - core_simd::SimdU16<$lanes>: core_simd::Vector, - core_simd::SimdU32<$lanes>: core_simd::Vector, - core_simd::SimdU64<$lanes>: core_simd::Vector, - core_simd::SimdUsize<$lanes>: core_simd::Vector, - core_simd::SimdI8<$lanes>: core_simd::Vector, - core_simd::SimdI16<$lanes>: core_simd::Vector, - core_simd::SimdI32<$lanes>: core_simd::Vector, - core_simd::SimdI64<$lanes>: core_simd::Vector, - core_simd::SimdIsize<$lanes>: core_simd::Vector, - core_simd::SimdF32<$lanes>: core_simd::Vector, - core_simd::SimdF64<$lanes>: core_simd::Vector, - core_simd::Mask8<$lanes>: core_simd::Mask, - core_simd::Mask16<$lanes>: core_simd::Mask, - core_simd::Mask32<$lanes>: core_simd::Mask, - core_simd::Mask64<$lanes>: core_simd::Mask, - core_simd::MaskSize<$lanes>: core_simd::Mask, + core_simd::LaneCount<$lanes>: core_simd::SupportedLaneCount, $body #[cfg(target_arch = "wasm32")] @@ -409,23 +393,7 @@ macro_rules! test_lanes_panic { fn implementation() where - core_simd::SimdU8<$lanes>: core_simd::Vector, - core_simd::SimdU16<$lanes>: core_simd::Vector, - core_simd::SimdU32<$lanes>: core_simd::Vector, - core_simd::SimdU64<$lanes>: core_simd::Vector, - core_simd::SimdUsize<$lanes>: core_simd::Vector, - core_simd::SimdI8<$lanes>: core_simd::Vector, - core_simd::SimdI16<$lanes>: core_simd::Vector, - core_simd::SimdI32<$lanes>: core_simd::Vector, - core_simd::SimdI64<$lanes>: core_simd::Vector, - core_simd::SimdIsize<$lanes>: core_simd::Vector, - core_simd::SimdF32<$lanes>: core_simd::Vector, - core_simd::SimdF64<$lanes>: core_simd::Vector, - core_simd::Mask8<$lanes>: core_simd::Mask, - core_simd::Mask16<$lanes>: core_simd::Mask, - core_simd::Mask32<$lanes>: core_simd::Mask, - core_simd::Mask64<$lanes>: core_simd::Mask, - core_simd::MaskSize<$lanes>: core_simd::Mask, + core_simd::LaneCount<$lanes>: core_simd::SupportedLaneCount, $body #[test]