From 9cc3deaa9256060868bb952ea5f850a910633f19 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sun, 13 Dec 2020 23:58:33 -0500 Subject: [PATCH] Finish refactoring vector types --- crates/core_simd/src/intrinsics.rs | 2 +- crates/core_simd/src/lib.rs | 4 +- crates/core_simd/src/masks/full_masks/mod.rs | 199 +++++ .../{wide => full_masks}/vectors_m128.rs | 0 .../masks/{wide => full_masks}/vectors_m16.rs | 0 .../masks/{wide => full_masks}/vectors_m32.rs | 0 .../masks/{wide => full_masks}/vectors_m64.rs | 0 .../masks/{wide => full_masks}/vectors_m8.rs | 3 + .../{wide => full_masks}/vectors_msize.rs | 0 crates/core_simd/src/masks/mod.rs | 682 ++++++++---------- crates/core_simd/src/masks/ops.rs | 208 ------ crates/core_simd/src/masks/wide/mod.rs | 139 ---- crates/core_simd/src/vectors_f32.rs | 9 +- crates/core_simd/src/vectors_f64.rs | 7 +- crates/core_simd/src/vectors_i128.rs | 5 +- crates/core_simd/src/vectors_i16.rs | 9 +- crates/core_simd/src/vectors_i32.rs | 9 +- crates/core_simd/src/vectors_i64.rs | 7 +- crates/core_simd/src/vectors_i8.rs | 9 +- crates/core_simd/src/vectors_isize.rs | 7 +- crates/core_simd/src/vectors_u128.rs | 5 +- crates/core_simd/src/vectors_u16.rs | 9 +- crates/core_simd/src/vectors_u32.rs | 9 +- crates/core_simd/src/vectors_u64.rs | 7 +- crates/core_simd/src/vectors_u8.rs | 9 +- crates/core_simd/src/vectors_usize.rs | 7 +- .../core_simd/tests/ops_impl/mask_macros.rs | 2 - 27 files changed, 615 insertions(+), 732 deletions(-) create mode 100644 crates/core_simd/src/masks/full_masks/mod.rs rename crates/core_simd/src/masks/{wide => full_masks}/vectors_m128.rs (100%) rename crates/core_simd/src/masks/{wide => full_masks}/vectors_m16.rs (100%) rename crates/core_simd/src/masks/{wide => full_masks}/vectors_m32.rs (100%) rename crates/core_simd/src/masks/{wide => full_masks}/vectors_m64.rs (100%) rename crates/core_simd/src/masks/{wide => full_masks}/vectors_m8.rs (82%) rename crates/core_simd/src/masks/{wide => full_masks}/vectors_msize.rs (100%) delete mode 100644 crates/core_simd/src/masks/ops.rs delete mode 100644 crates/core_simd/src/masks/wide/mod.rs diff --git a/crates/core_simd/src/intrinsics.rs b/crates/core_simd/src/intrinsics.rs index 3dfc77136f2..51689cd97be 100644 --- a/crates/core_simd/src/intrinsics.rs +++ b/crates/core_simd/src/intrinsics.rs @@ -1,7 +1,7 @@ //! This module contains the LLVM intrinsics bindings that provide the functionality for this //! crate. //! -//! The LLVM assembly language is documented here: https://llvm.org/docs/LangRef.html +//! The LLVM assembly language is documented here: /// These intrinsics aren't linked directly from LLVM and are mostly undocumented, however they are /// simply lowered to the matching LLVM instructions by the compiler. The associated instruction diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs index d23e5ad21ba..9d4ce683f22 100644 --- a/crates/core_simd/src/lib.rs +++ b/crates/core_simd/src/lib.rs @@ -11,8 +11,8 @@ mod intrinsics; mod ops; //mod round; -//pub mod masks; -//pub use masks::opaque::*; +mod masks; +pub use masks::*; mod vectors_u8; pub use vectors_u8::*; diff --git a/crates/core_simd/src/masks/full_masks/mod.rs b/crates/core_simd/src/masks/full_masks/mod.rs new file mode 100644 index 00000000000..829174669c2 --- /dev/null +++ b/crates/core_simd/src/masks/full_masks/mod.rs @@ -0,0 +1,199 @@ +//! Masks that take up full SIMD vector registers. + +/// The error type returned when converting an integer to a mask fails. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct TryFromMaskError(()); + +impl core::fmt::Display for TryFromMaskError { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "mask vector must have all bits set or unset in each lane") + } +} + +macro_rules! define_mask { + { $(#[$attr:meta])* struct $name:ident($type:ty); } => { + $(#[$attr])* + #[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash)] + #[repr(transparent)] + pub struct $name($type); + + delegate_ops_to_inner! { $name } + + impl $name<$lanes> { + /// Construct a mask by setting all lanes to the given value. + pub fn splat(value: bool) -> Self { + Self(<$type>::splat(value.into())) + } + + /// Tests the value of the specified lane. + /// + /// # Panics + /// Panics if `lane` is greater than or equal to the number of lanes in the vector. + #[inline] + pub fn test(&self, lane: usize) -> bool { + self.0[lane] > 0 + } + + /// Sets the value of the specified lane. + /// + /// # Panics + /// Panics if `lane` is greater than or equal to the number of lanes in the vector. + #[inline] + pub fn set(&mut self, lane: usize, value: bool) { + self.0[lane] = if value { + !0 + } else { + 0 + } + } + } + + impl core::convert::From for $name<$lanes> { + fn from(value: bool) -> Self { + Self::splat(value) + } + } + + impl core::convert::TryFrom<$type> for $name<$lanes> { + type Error = TryFromMaskError; + fn try_from(value: $type) -> Result { + if value.as_slice().iter().all(|x| *x == 0 || !*x == 0) { + Ok(Self(value)) + } else { + Err(TryFromMaskError(())) + } + } + } + + impl core::convert::From<$name<$lanes>> for $type { + fn from(value: $name<$lanes>) -> Self { + value.0 + } + } + + impl core::fmt::Debug for $name<$lanes> { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_list() + .entries((0..LANES).map(|lane| self.test(lane))) + .finish() + } + } + + impl core::fmt::Binary for $name<$lanes> { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + core::fmt::Binary::fmt(&self.0, f) + } + } + + impl core::fmt::Octal for $name<$lanes> { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + core::fmt::Octal::fmt(&self.0, f) + } + } + + impl core::fmt::LowerHex for $name<$lanes> { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + core::fmt::LowerHex::fmt(&self.0, f) + } + } + + impl core::fmt::UpperHex for $name<$lanes> { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + core::fmt::UpperHex::fmt(&self.0, f) + } + } + } +} + +define_mask! { + /// A mask equivalent to [SimdI8](crate::SimdI8), where all bits in the lane must be either set + /// or unset. + struct SimdI8Mask(crate::SimdI8); +} + +define_mask! { + /// A mask equivalent to [SimdI16](crate::SimdI16), where all bits in the lane must be either set + /// or unset. + struct SimdI16Mask(crate::SimdI16); +} + +define_mask! { + /// A mask equivalent to [SimdI32](crate::SimdI32), where all bits in the lane must be either set + /// or unset. + struct SimdI32Mask(crate::SimdI32); +} + +define_mask! { + /// A mask equivalent to [SimdI64](crate::SimdI64), where all bits in the lane must be either set + /// or unset. + struct SimdI64Mask(crate::SimdI64); +} + +define_mask! { + /// A mask equivalent to [SimdI128](crate::SimdI128), where all bits in the lane must be either set + /// or unset. + struct SimdI128Mask(crate::SimdI64); +} + +define_mask! { + /// A mask equivalent to [SimdIsize](crate::SimdIsize), where all bits in the lane must be either set + /// or unset. + struct SimdIsizeMask(crate::SimdI64); +} + +macro_rules! implement_mask_ext { + { $($vector:ident => $mask:ident,)* } => { + $( + impl crate::masks::MaskExt<$mask> for crate::$vector { + #[inline] + fn lanes_eq(&self, other: &Self) -> $mask { + unsafe { crate::intrinsics::simd_eq(self, other) } + } + + #[inline] + fn lanes_ne(&self, other: &Self) -> $mask { + unsafe { crate::intrinsics::simd_ne(self, other) } + } + + #[inline] + fn lanes_lt(&self, other: &Self) -> $mask { + unsafe { crate::intrinsics::simd_lt(self, other) } + } + + #[inline] + fn lanes_gt(&self, other: &Self) -> $mask { + unsafe { crate::intrinsics::simd_gt(self, other) } + } + + #[inline] + fn lanes_le(&self, other: &Self) -> $mask { + unsafe { crate::intrinsics::simd_le(self, other) } + } + + #[inline] + fn lanes_ge(&self, other: &Self) -> $mask { + unsafe { crate::intrinsics::simd_ge(self, other) } + } + } + )* + } +} + +implement_mask_ext! { + SimdI8 => SimdI8Mask, + SimdI16 => SimdI16Mask, + SimdI32 => SimdI32Mask, + SimdI64 => SimdI64Mask, + SimdI128 => SimdI128Mask, + SimdIsize => SimdIsizeMask, + + SimdU8 => SimdI8Mask, + SimdU16 => SimdI16Mask, + SimdU32 => SimdI32Mask, + SimdU64 => SimdI64Mask, + SimdU128 => SimdI128Mask, + SimdUsize => SimdIsizeMask, + + SimdF32 => SimdI32Mask, + SimdF64 => SimdI64Mask, +} diff --git a/crates/core_simd/src/masks/wide/vectors_m128.rs b/crates/core_simd/src/masks/full_masks/vectors_m128.rs similarity index 100% rename from crates/core_simd/src/masks/wide/vectors_m128.rs rename to crates/core_simd/src/masks/full_masks/vectors_m128.rs diff --git a/crates/core_simd/src/masks/wide/vectors_m16.rs b/crates/core_simd/src/masks/full_masks/vectors_m16.rs similarity index 100% rename from crates/core_simd/src/masks/wide/vectors_m16.rs rename to crates/core_simd/src/masks/full_masks/vectors_m16.rs diff --git a/crates/core_simd/src/masks/wide/vectors_m32.rs b/crates/core_simd/src/masks/full_masks/vectors_m32.rs similarity index 100% rename from crates/core_simd/src/masks/wide/vectors_m32.rs rename to crates/core_simd/src/masks/full_masks/vectors_m32.rs diff --git a/crates/core_simd/src/masks/wide/vectors_m64.rs b/crates/core_simd/src/masks/full_masks/vectors_m64.rs similarity index 100% rename from crates/core_simd/src/masks/wide/vectors_m64.rs rename to crates/core_simd/src/masks/full_masks/vectors_m64.rs diff --git a/crates/core_simd/src/masks/wide/vectors_m8.rs b/crates/core_simd/src/masks/full_masks/vectors_m8.rs similarity index 82% rename from crates/core_simd/src/masks/wide/vectors_m8.rs rename to crates/core_simd/src/masks/full_masks/vectors_m8.rs index 149e138739d..85506dd93e1 100644 --- a/crates/core_simd/src/masks/wide/vectors_m8.rs +++ b/crates/core_simd/src/masks/full_masks/vectors_m8.rs @@ -19,3 +19,6 @@ define_mask_vector! { /// Vector of 64 `m8` values struct m8x64([i8 as m8; 64]); } + +#[repr(transparent)] +struct VectorMask8(crate::SimdI8); diff --git a/crates/core_simd/src/masks/wide/vectors_msize.rs b/crates/core_simd/src/masks/full_masks/vectors_msize.rs similarity index 100% rename from crates/core_simd/src/masks/wide/vectors_msize.rs rename to crates/core_simd/src/masks/full_masks/vectors_msize.rs diff --git a/crates/core_simd/src/masks/mod.rs b/crates/core_simd/src/masks/mod.rs index 9fb3da00604..9c90373fb47 100644 --- a/crates/core_simd/src/masks/mod.rs +++ b/crates/core_simd/src/masks/mod.rs @@ -1,115 +1,151 @@ //! Types and traits associated with masking lanes of vectors. +#![allow(non_camel_case_types)] -pub mod wide; +macro_rules! delegate_ops_to_inner { + { $name:ident } => { + impl core::ops::BitAnd for $name { + type Output = Self; + #[inline] + fn bitand(self, rhs: Self) -> Self { + Self(self.0 & rhs.0) + } + } -mod ops; -pub use ops::*; + impl core::ops::BitAnd for $name { + type Output = Self; + #[inline] + fn bitand(self, rhs: bool) -> Self { + self & Self::splat(rhs) + } + } -pub(crate) trait MaskImpl { - type Mask; + impl core::ops::BitAnd<$name> for bool { + type Output = $name; + #[inline] + fn bitand(self, rhs: $name) -> $name { + $name::::splat(self) & rhs + } + } + + impl core::ops::BitOr for $name { + type Output = Self; + #[inline] + fn bitor(self, rhs: Self) -> Self { + Self(self.0 | rhs.0) + } + } + + impl core::ops::BitOr for $name { + type Output = Self; + #[inline] + fn bitor(self, rhs: bool) -> Self { + self | Self::splat(rhs) + } + } + + impl core::ops::BitOr<$name> for bool { + type Output = $name; + #[inline] + fn bitor(self, rhs: $name) -> $name { + $name::::splat(self) | rhs + } + } + + impl core::ops::BitXor for $name { + type Output = Self; + #[inline] + fn bitxor(self, rhs: Self) -> Self::Output { + Self(self.0 ^ rhs.0) + } + } + + impl core::ops::BitXor for $name { + type Output = Self; + #[inline] + fn bitxor(self, rhs: bool) -> Self::Output { + self ^ Self::splat(rhs) + } + } + + impl core::ops::BitXor<$name> for bool { + type Output = $name; + #[inline] + fn bitxor(self, rhs: $name) -> Self::Output { + $name::::splat(self) ^ rhs + } + } + + impl core::ops::Not for $name { + type Output = $name; + #[inline] + fn not(self) -> Self::Output { + Self(!self.0) + } + } + + impl core::ops::BitAndAssign for $name { + #[inline] + fn bitand_assign(&mut self, rhs: Self) { + self.0 &= rhs.0; + } + } + + impl core::ops::BitAndAssign for $name { + #[inline] + fn bitand_assign(&mut self, rhs: bool) { + *self &= Self::splat(rhs); + } + } + + impl core::ops::BitOrAssign for $name { + #[inline] + fn bitor_assign(&mut self, rhs: Self) { + self.0 |= rhs.0; + } + } + + impl core::ops::BitOrAssign for $name { + #[inline] + fn bitor_assign(&mut self, rhs: bool) { + *self |= Self::splat(rhs); + } + } + + impl core::ops::BitXorAssign for $name { + #[inline] + fn bitxor_assign(&mut self, rhs: Self) { + self.0 ^= rhs.0; + } + } + + impl core::ops::BitXorAssign for $name { + #[inline] + fn bitxor_assign(&mut self, rhs: bool) { + *self ^= Self::splat(rhs); + } + } + } } -impl MaskImpl for [u8; 8] { - type Mask = wide::m8x8; -} - -impl MaskImpl for [u8; 16] { - type Mask = wide::m8x16; -} - -impl MaskImpl for [u8; 32] { - type Mask = wide::m8x32; -} - -impl MaskImpl for [u8; 64] { - type Mask = wide::m8x64; -} - -impl MaskImpl for [u16; 4] { - type Mask = wide::m16x4; -} - -impl MaskImpl for [u16; 8] { - type Mask = wide::m16x8; -} - -impl MaskImpl for [u16; 16] { - type Mask = wide::m16x16; -} - -impl MaskImpl for [u16; 32] { - type Mask = wide::m16x32; -} - -impl MaskImpl for [u32; 2] { - type Mask = wide::m32x2; -} - -impl MaskImpl for [u32; 4] { - type Mask = wide::m32x4; -} - -impl MaskImpl for [u32; 8] { - type Mask = wide::m32x8; -} - -impl MaskImpl for [u32; 16] { - type Mask = wide::m32x16; -} - -impl MaskImpl for [u64; 2] { - type Mask = wide::m64x2; -} - -impl MaskImpl for [u64; 4] { - type Mask = wide::m64x4; -} - -impl MaskImpl for [u64; 8] { - type Mask = wide::m64x8; -} - -impl MaskImpl for [u128; 2] { - type Mask = wide::m128x2; -} - -impl MaskImpl for [u128; 4] { - type Mask = wide::m128x4; -} - -impl MaskImpl for [usize; 2] { - type Mask = wide::msizex2; -} - -impl MaskImpl for [usize; 4] { - type Mask = wide::msizex4; -} - -impl MaskImpl for [usize; 8] { - type Mask = wide::msizex8; -} +pub mod full_masks; macro_rules! define_opaque_mask { { $(#[$attr:meta])* - struct $name:ident([$width:ty; $lanes:tt]); + struct $name:ident($inner_ty:ty); } => { $(#[$attr])* #[allow(non_camel_case_types)] - pub struct $name(<[$width; $lanes] as crate::masks::MaskImpl>::Mask); + pub struct $name($inner_ty); - impl $name { - pub(crate) fn new_from_inner(inner: <[$width; $lanes] as crate::masks::MaskImpl>::Mask) -> Self { - Self(inner) - } + delegate_ops_to_inner! { $name } + impl $name<$lanes> { /// Construct a mask by setting all lanes to the given value. pub fn splat(value: bool) -> Self { - Self(<[$width; $lanes] as crate::masks::MaskImpl>::Mask::splat(value.into())) + Self(<$inner_ty>::splat(value)) } - call_counting_args! { $lanes => define_opaque_mask => new [$width; $lanes] } - /// Tests the value of the specified lane. /// /// # Panics @@ -129,312 +165,226 @@ macro_rules! define_opaque_mask { } } - impl Copy for $name {} + impl Copy for $name<$lanes> {} - impl Clone for $name { + impl Clone for $name<$lanes> { #[inline] fn clone(&self) -> Self { *self } } - impl Default for $name { + impl Default for $name<$lanes> { #[inline] fn default() -> Self { Self::splat(false) } } - impl PartialEq for $name { + impl PartialEq for $name<$lanes> { #[inline] fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } - impl PartialOrd for $name { + impl PartialOrd for $name<$lanes> { #[inline] fn partial_cmp(&self, other: &Self) -> Option { self.0.partial_cmp(&other.0) } } - impl core::fmt::Debug for $name { + impl core::fmt::Debug for $name<$lanes> { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { core::fmt::Debug::fmt(&self.0, f) } } - - impl core::ops::BitAnd for $name { - type Output = Self; - #[inline] - fn bitand(self, rhs: Self) -> Self { - Self(self.0 & rhs.0) - } - } - - impl core::ops::BitAnd for $name { - type Output = Self; - #[inline] - fn bitand(self, rhs: bool) -> Self { - self & Self::splat(rhs) - } - } - - impl core::ops::BitAnd<$name> for bool { - type Output = $name; - #[inline] - fn bitand(self, rhs: $name) -> $name { - $name::splat(self) & rhs - } - } - - impl core::ops::BitOr for $name { - type Output = Self; - #[inline] - fn bitor(self, rhs: Self) -> Self { - Self(self.0 | rhs.0) - } - } - - impl core::ops::BitOr for $name { - type Output = Self; - #[inline] - fn bitor(self, rhs: bool) -> Self { - self | Self::splat(rhs) - } - } - - impl core::ops::BitOr<$name> for bool { - type Output = $name; - #[inline] - fn bitor(self, rhs: $name) -> $name { - $name::splat(self) | rhs - } - } - - impl core::ops::BitXor for $name { - type Output = Self; - #[inline] - fn bitxor(self, rhs: Self) -> Self::Output { - Self(self.0 ^ rhs.0) - } - } - - impl core::ops::BitXor for $name { - type Output = Self; - #[inline] - fn bitxor(self, rhs: bool) -> Self::Output { - self ^ Self::splat(rhs) - } - } - - impl core::ops::BitXor<$name> for bool { - type Output = $name; - #[inline] - fn bitxor(self, rhs: $name) -> Self::Output { - $name::splat(self) ^ rhs - } - } - - impl core::ops::Not for $name { - type Output = $name; - #[inline] - fn not(self) -> Self::Output { - Self(!self.0) - } - } - - impl core::ops::BitAndAssign for $name { - #[inline] - fn bitand_assign(&mut self, rhs: Self) { - self.0 &= rhs.0; - } - } - - impl core::ops::BitAndAssign for $name { - #[inline] - fn bitand_assign(&mut self, rhs: bool) { - *self &= Self::splat(rhs); - } - } - - impl core::ops::BitOrAssign for $name { - #[inline] - fn bitor_assign(&mut self, rhs: Self) { - self.0 |= rhs.0; - } - } - - impl core::ops::BitOrAssign for $name { - #[inline] - fn bitor_assign(&mut self, rhs: bool) { - *self |= Self::splat(rhs); - } - } - - impl core::ops::BitXorAssign for $name { - #[inline] - fn bitxor_assign(&mut self, rhs: Self) { - self.0 ^= rhs.0; - } - } - - impl core::ops::BitXorAssign for $name { - #[inline] - fn bitxor_assign(&mut self, rhs: bool) { - *self ^= Self::splat(rhs); - } - } }; - { new [$width:ty; $lanes:tt] $($var:ident)* } => { - /// Construct a vector by setting each lane to the given values. - #[allow(clippy::too_many_arguments)] - #[inline] - pub const fn new($($var: bool),*) -> Self { - Self(<[$width; $lanes] as crate::masks::MaskImpl>::Mask::new_from_bool($($var),*)) - } +} + +define_opaque_mask! { + /// Mask for vectors with `LANES` 8-bit elements. + /// + /// The layout of this type is unspecified. + struct Mask8(full_masks::SimdI8Mask); +} + +define_opaque_mask! { + /// Mask for vectors with `LANES` 16-bit elements. + /// + /// The layout of this type is unspecified. + struct Mask16(full_masks::SimdI16Mask); +} + +define_opaque_mask! { + /// Mask for vectors with `LANES` 32-bit elements. + /// + /// The layout of this type is unspecified. + struct Mask32(full_masks::SimdI32Mask); +} + +define_opaque_mask! { + /// Mask for vectors with `LANES` 64-bit elements. + /// + /// The layout of this type is unspecified. + struct Mask64(full_masks::SimdI64Mask); +} + +define_opaque_mask! { + /// Mask for vectors with `LANES` 128-bit elements. + /// + /// The layout of this type is unspecified. + struct Mask128(full_masks::SimdI128Mask); +} + +define_opaque_mask! { + /// Mask for vectors with `LANES` pointer-width elements. + /// + /// The layout of this type is unspecified. + struct MaskSize(full_masks::SimdIsizeMask); +} + +/// Mask-related operations using a particular mask layout. +pub trait MaskExt { + /// Test if each lane is equal to the corresponding lane in `other`. + fn lanes_eq(&self, other: &Self) -> Mask; + + /// Test if each lane is not equal to the corresponding lane in `other`. + fn lanes_ne(&self, other: &Self) -> Mask; + + /// Test if each lane is less than the corresponding lane in `other`. + fn lanes_lt(&self, other: &Self) -> Mask; + + /// Test if each lane is greater than the corresponding lane in `other`. + fn lanes_gt(&self, other: &Self) -> Mask; + + /// Test if each lane is less than or equal to the corresponding lane in `other`. + fn lanes_le(&self, other: &Self) -> Mask; + + /// Test if each lane is greater than or equal to the corresponding lane in `other`. + fn lanes_ge(&self, other: &Self) -> Mask; +} + +macro_rules! implement_mask_ops { + { $($vector:ident => $mask:ident,)* } => { + $( + impl crate::$vector { + /// Test if each lane is equal to the corresponding lane in `other`. + #[inline] + pub fn lanes_eq(&self, other: &Self) -> $mask { + $mask(MaskExt::lanes_eq(self, other)) + } + + /// Test if each lane is not equal to the corresponding lane in `other`. + #[inline] + pub fn lanes_ne(&self, other: &Self) -> $mask { + $mask(MaskExt::lanes_ne(self, other)) + } + + /// Test if each lane is less than the corresponding lane in `other`. + #[inline] + pub fn lanes_lt(&self, other: &Self) -> $mask { + $mask(MaskExt::lanes_lt(self, other)) + } + + /// Test if each lane is greater than the corresponding lane in `other`. + #[inline] + pub fn lanes_gt(&self, other: &Self) -> $mask { + $mask(MaskExt::lanes_gt(self, other)) + } + + /// Test if each lane is less than or equal to the corresponding lane in `other`. + #[inline] + pub fn lanes_le(&self, other: &Self) -> $mask { + $mask(MaskExt::lanes_le(self, other)) + } + + /// Test if each lane is greater than or equal to the corresponding lane in `other`. + #[inline] + pub fn lanes_ge(&self, other: &Self) -> $mask { + $mask(MaskExt::lanes_ge(self, other)) + } + } + )* } } -pub(crate) mod opaque { - define_opaque_mask! { - /// Mask for 8 8-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask8x8([u8; 8]); - } +implement_mask_ops! { + SimdI8 => Mask8, + SimdI16 => Mask16, + SimdI32 => Mask32, + SimdI64 => Mask64, + SimdI128 => Mask128, + SimdIsize => MaskSize, - define_opaque_mask! { - /// Mask for 16 8-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask8x16([u8; 16]); - } + SimdU8 => Mask8, + SimdU16 => Mask16, + SimdU32 => Mask32, + SimdU64 => Mask64, + SimdU128 => Mask128, + SimdUsize => MaskSize, - define_opaque_mask! { - /// Mask for 32 8-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask8x32([u8; 32]); - } - - define_opaque_mask! { - /// Mask for 64 8-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask8x64([u8; 64]); - } - - define_opaque_mask! { - /// Mask for 4 16-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask16x4([u16; 4]); - } - - define_opaque_mask! { - /// Mask for 8 16-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask16x8([u16; 8]); - } - - define_opaque_mask! { - /// Mask for 16 16-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask16x16([u16; 16]); - } - - define_opaque_mask! { - /// Mask for 32 16-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask16x32([u16; 32]); - } - - define_opaque_mask! { - /// Mask for 2 32-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask32x2([u32; 2]); - } - - define_opaque_mask! { - /// Mask for 4 32-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask32x4([u32; 4]); - } - - define_opaque_mask! { - /// Mask for 8 32-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask32x8([u32; 8]); - } - - define_opaque_mask! { - /// Mask for 16 32-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask32x16([u32; 16]); - } - - define_opaque_mask! { - /// Mask for 2 64-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask64x2([u64; 2]); - } - - define_opaque_mask! { - /// Mask for 4 64-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask64x4([u64; 4]); - } - - define_opaque_mask! { - /// Mask for 8 64-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask64x8([u64; 8]); - } - - define_opaque_mask! { - /// Mask for 2 128-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask128x2([u128; 2]); - } - - define_opaque_mask! { - /// Mask for 4 128-bit lanes. - /// - /// The layout of this type is unspecified. - struct mask128x4([u128; 4]); - } - - define_opaque_mask! { - /// Mask for 2 `isize`-wide lanes. - /// - /// The layout of this type is unspecified. - struct masksizex2([usize; 2]); - } - - define_opaque_mask! { - /// Mask for 4 `isize`-wide lanes. - /// - /// The layout of this type is unspecified. - struct masksizex4([usize; 4]); - } - - define_opaque_mask! { - /// Mask for 8 `isize`-wide lanes. - /// - /// The layout of this type is unspecified. - struct masksizex8([usize; 8]); - } + SimdF32 => Mask32, + SimdF64 => Mask64, } + +/// Vector of eight 8-bit masks +pub type mask8x8 = Mask8<8>; + +/// Vector of 16 8-bit masks +pub type mask8x16 = Mask8<16>; + +/// Vector of 32 8-bit masks +pub type mask8x32 = Mask8<32>; + +/// Vector of 16 8-bit masks +pub type mask8x64 = Mask8<64>; + +/// Vector of four 16-bit masks +pub type mask16x4 = Mask16<4>; + +/// Vector of eight 16-bit masks +pub type mask16x8 = Mask16<8>; + +/// Vector of 16 16-bit masks +pub type mask16x16 = Mask16<16>; + +/// Vector of 32 16-bit masks +pub type mask16x32 = Mask32<32>; + +/// Vector of two 32-bit masks +pub type mask32x2 = Mask32<2>; + +/// Vector of four 32-bit masks +pub type mask32x4 = Mask32<4>; + +/// Vector of eight 32-bit masks +pub type mask32x8 = Mask32<8>; + +/// Vector of 16 32-bit masks +pub type mask32x16 = Mask32<16>; + +/// Vector of two 64-bit masks +pub type mask64x2 = Mask64<2>; + +/// Vector of four 64-bit masks +pub type mask64x4 = Mask64<4>; + +/// Vector of eight 64-bit masks +pub type mask64x8 = Mask64<8>; + +/// Vector of two 128-bit masks +pub type mask128x2 = Mask128<2>; + +/// Vector of four 128-bit masks +pub type mask128x4 = Mask128<4>; + +/// Vector of two pointer-width masks +pub type masksizex2 = MaskSize<2>; + +/// Vector of four pointer-width masks +pub type masksizex4 = MaskSize<4>; + +/// Vector of eight pointer-width masks +pub type masksizex8 = MaskSize<8>; diff --git a/crates/core_simd/src/masks/ops.rs b/crates/core_simd/src/masks/ops.rs deleted file mode 100644 index 85ce955459a..00000000000 --- a/crates/core_simd/src/masks/ops.rs +++ /dev/null @@ -1,208 +0,0 @@ -/// Mask-related operations using a particular mask layout. -pub trait MaskExt { - /// Test if each lane is equal to the corresponding lane in `other`. - fn lanes_eq(self, other: Self) -> Mask; - - /// Test if each lane is not equal to the corresponding lane in `other`. - fn lanes_ne(self, other: Self) -> Mask; - - /// Test if each lane is less than the corresponding lane in `other`. - fn lanes_lt(self, other: Self) -> Mask; - - /// Test if each lane is greater than the corresponding lane in `other`. - fn lanes_gt(self, other: Self) -> Mask; - - /// Test if each lane is less than or equal to the corresponding lane in `other`. - fn lanes_le(self, other: Self) -> Mask; - - /// Test if each lane is greater than or equal to the corresponding lane in `other`. - fn lanes_ge(self, other: Self) -> Mask; -} - -macro_rules! implement_mask_ext { - { $($vector:ty => $($mask:ty),*;)* } => { - $( // vector - $( // mask - impl MaskExt<$mask> for $vector { - #[inline] - fn lanes_eq(self, other: Self) -> $mask { - unsafe { crate::intrinsics::simd_eq(self, other) } - } - - #[inline] - fn lanes_ne(self, other: Self) -> $mask { - unsafe { crate::intrinsics::simd_ne(self, other) } - } - - #[inline] - fn lanes_lt(self, other: Self) -> $mask { - unsafe { crate::intrinsics::simd_lt(self, other) } - } - - #[inline] - fn lanes_gt(self, other: Self) -> $mask { - unsafe { crate::intrinsics::simd_gt(self, other) } - } - - #[inline] - fn lanes_le(self, other: Self) -> $mask { - unsafe { crate::intrinsics::simd_le(self, other) } - } - - #[inline] - fn lanes_ge(self, other: Self) -> $mask { - unsafe { crate::intrinsics::simd_ge(self, other) } - } - } - )* - )* - } -} - -implement_mask_ext! { - crate::u8x8 => crate::masks::wide::m8x8; - crate::u8x16 => crate::masks::wide::m8x16; - crate::u8x32 => crate::masks::wide::m8x32; - crate::u8x64 => crate::masks::wide::m8x64; - crate::u16x4 => crate::masks::wide::m16x4; - crate::u16x8 => crate::masks::wide::m16x8; - crate::u16x16 => crate::masks::wide::m16x16; - crate::u16x32 => crate::masks::wide::m16x32; - crate::u32x2 => crate::masks::wide::m32x2; - crate::u32x4 => crate::masks::wide::m32x4; - crate::u32x8 => crate::masks::wide::m32x8; - crate::u32x16 => crate::masks::wide::m32x16; - crate::u64x2 => crate::masks::wide::m64x2; - crate::u64x4 => crate::masks::wide::m64x4; - crate::u64x8 => crate::masks::wide::m64x8; - crate::u128x2 => crate::masks::wide::m128x2; - crate::u128x4 => crate::masks::wide::m128x4; - crate::usizex2 => crate::masks::wide::msizex2; - crate::usizex4 => crate::masks::wide::msizex4; - crate::usizex8 => crate::masks::wide::msizex8; - - crate::i8x8 => crate::masks::wide::m8x8; - crate::i8x16 => crate::masks::wide::m8x16; - crate::i8x32 => crate::masks::wide::m8x32; - crate::i8x64 => crate::masks::wide::m8x64; - crate::i16x4 => crate::masks::wide::m16x4; - crate::i16x8 => crate::masks::wide::m16x8; - crate::i16x16 => crate::masks::wide::m16x16; - crate::i16x32 => crate::masks::wide::m16x32; - crate::i32x2 => crate::masks::wide::m32x2; - crate::i32x4 => crate::masks::wide::m32x4; - crate::i32x8 => crate::masks::wide::m32x8; - crate::i32x16 => crate::masks::wide::m32x16; - crate::i64x2 => crate::masks::wide::m64x2; - crate::i64x4 => crate::masks::wide::m64x4; - crate::i64x8 => crate::masks::wide::m64x8; - crate::i128x2 => crate::masks::wide::m128x2; - crate::i128x4 => crate::masks::wide::m128x4; - crate::isizex2 => crate::masks::wide::msizex2; - crate::isizex4 => crate::masks::wide::msizex4; - crate::isizex8 => crate::masks::wide::msizex8; - - crate::f32x2 => crate::masks::wide::m32x2; - crate::f32x4 => crate::masks::wide::m32x4; - crate::f32x8 => crate::masks::wide::m32x8; - crate::f32x16 => crate::masks::wide::m32x16; - crate::f64x2 => crate::masks::wide::m64x2; - crate::f64x4 => crate::masks::wide::m64x4; - crate::f64x8 => crate::masks::wide::m64x8; -} - -macro_rules! implement_mask_ops { - { $($vector:ty => $mask:ty,)* } => { - $( // vector - impl $vector { - /// Test if each lane is equal to the corresponding lane in `other`. - #[inline] - pub fn lanes_eq(self, other: Self) -> $mask { - <$mask>::new_from_inner(MaskExt::lanes_eq(self, other)) - } - - /// Test if each lane is not equal to the corresponding lane in `other`. - #[inline] - pub fn lanes_ne(self, other: Self) -> $mask { - <$mask>::new_from_inner(MaskExt::lanes_ne(self, other)) - } - - /// Test if each lane is less than the corresponding lane in `other`. - #[inline] - pub fn lanes_lt(self, other: Self) -> $mask { - <$mask>::new_from_inner(MaskExt::lanes_lt(self, other)) - } - - /// Test if each lane is greater than the corresponding lane in `other`. - #[inline] - pub fn lanes_gt(self, other: Self) -> $mask { - <$mask>::new_from_inner(MaskExt::lanes_gt(self, other)) - } - - /// Test if each lane is less than or equal to the corresponding lane in `other`. - #[inline] - pub fn lanes_le(self, other: Self) -> $mask { - <$mask>::new_from_inner(MaskExt::lanes_le(self, other)) - } - - /// Test if each lane is greater than or equal to the corresponding lane in `other`. - #[inline] - pub fn lanes_ge(self, other: Self) -> $mask { - <$mask>::new_from_inner(MaskExt::lanes_ge(self, other)) - } - } - )* - } -} - -implement_mask_ops! { - crate::u8x8 => crate::mask8x8, - crate::u8x16 => crate::mask8x16, - crate::u8x32 => crate::mask8x32, - crate::u8x64 => crate::mask8x64, - crate::u16x4 => crate::mask16x4, - crate::u16x8 => crate::mask16x8, - crate::u16x16 => crate::mask16x16, - crate::u16x32 => crate::mask16x32, - crate::u32x2 => crate::mask32x2, - crate::u32x4 => crate::mask32x4, - crate::u32x8 => crate::mask32x8, - crate::u32x16 => crate::mask32x16, - crate::u64x2 => crate::mask64x2, - crate::u64x4 => crate::mask64x4, - crate::u64x8 => crate::mask64x8, - crate::u128x2 => crate::mask128x2, - crate::u128x4 => crate::mask128x4, - crate::usizex2 => crate::masksizex2, - crate::usizex4 => crate::masksizex4, - crate::usizex8 => crate::masksizex8, - - crate::i8x8 => crate::mask8x8, - crate::i8x16 => crate::mask8x16, - crate::i8x32 => crate::mask8x32, - crate::i8x64 => crate::mask8x64, - crate::i16x4 => crate::mask16x4, - crate::i16x8 => crate::mask16x8, - crate::i16x16 => crate::mask16x16, - crate::i16x32 => crate::mask16x32, - crate::i32x2 => crate::mask32x2, - crate::i32x4 => crate::mask32x4, - crate::i32x8 => crate::mask32x8, - crate::i32x16 => crate::mask32x16, - crate::i64x2 => crate::mask64x2, - crate::i64x4 => crate::mask64x4, - crate::i64x8 => crate::mask64x8, - crate::i128x2 => crate::mask128x2, - crate::i128x4 => crate::mask128x4, - crate::isizex2 => crate::masksizex2, - crate::isizex4 => crate::masksizex4, - crate::isizex8 => crate::masksizex8, - - crate::f32x2 => crate::mask32x2, - crate::f32x4 => crate::mask32x4, - crate::f32x8 => crate::mask32x8, - crate::f32x16 => crate::mask32x16, - crate::f64x2 => crate::mask64x2, - crate::f64x4 => crate::mask64x4, - crate::f64x8 => crate::mask64x8, -} diff --git a/crates/core_simd/src/masks/wide/mod.rs b/crates/core_simd/src/masks/wide/mod.rs deleted file mode 100644 index 7df8ca7e53d..00000000000 --- a/crates/core_simd/src/masks/wide/mod.rs +++ /dev/null @@ -1,139 +0,0 @@ -//! Masks that take up full vector registers. - -mod vectors_m8; -pub use vectors_m8::*; -mod vectors_m16; -pub use vectors_m16::*; -mod vectors_m32; -pub use vectors_m32::*; -mod vectors_m64; -pub use vectors_m64::*; -mod vectors_m128; -pub use vectors_m128::*; -mod vectors_msize; -pub use vectors_msize::*; - -/// The error type returned when converting an integer to a mask fails. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct TryFromMaskError(()); - -impl core::fmt::Display for TryFromMaskError { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - write!(f, "mask must have all bits set or unset") - } -} - -macro_rules! define_mask { - { $(#[$attr:meta])* struct $name:ident($type:ty); } => { - $(#[$attr])* - #[allow(non_camel_case_types)] - #[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash)] - #[repr(transparent)] - pub struct $name(pub(crate) $type); - - impl $name { - /// Construct a mask from the given value. - pub const fn new(value: bool) -> Self { - if value { - Self(!0) - } else { - Self(0) - } - } - - /// Test if the mask is set. - pub const fn test(&self) -> bool { - self.0 != 0 - } - } - - impl core::convert::From for $name { - fn from(value: bool) -> Self { - Self::new(value) - } - } - - impl core::convert::From<$name> for bool { - fn from(mask: $name) -> Self { - mask.test() - } - } - - impl core::convert::TryFrom<$type> for $name { - type Error = TryFromMaskError; - fn try_from(value: $type) -> Result { - if value == 0 || !value == 0 { - Ok(Self(value)) - } else { - Err(TryFromMaskError(())) - } - } - } - - impl core::convert::From<$name> for $type { - fn from(value: $name) -> Self { - value.0 - } - } - - impl core::fmt::Debug for $name { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - self.test().fmt(f) - } - } - - impl core::fmt::Binary for $name { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - core::fmt::Binary::fmt(&self.0, f) - } - } - - impl core::fmt::Octal for $name { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - core::fmt::Octal::fmt(&self.0, f) - } - } - - impl core::fmt::LowerHex for $name { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - core::fmt::LowerHex::fmt(&self.0, f) - } - } - - impl core::fmt::UpperHex for $name { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - core::fmt::UpperHex::fmt(&self.0, f) - } - } - } -} - -define_mask! { - /// 8-bit mask - struct m8(i8); -} - -define_mask! { - /// 16-bit mask - struct m16(i16); -} - -define_mask! { - /// 32-bit mask - struct m32(i32); -} - -define_mask! { - /// 64-bit mask - struct m64(i64); -} - -define_mask! { - /// 128-bit mask - struct m128(i128); -} - -define_mask! { - /// `isize`-wide mask - struct msize(isize); -} diff --git a/crates/core_simd/src/vectors_f32.rs b/crates/core_simd/src/vectors_f32.rs index b1e13408cc9..0b5d8c6ec49 100644 --- a/crates/core_simd/src/vectors_f32.rs +++ b/crates/core_simd/src/vectors_f32.rs @@ -1,14 +1,21 @@ #![allow(non_camel_case_types)] -/// A SIMD vector of containing `LANES` lanes of `f32`. +/// A SIMD vector of containing `LANES` `f32` values. #[repr(simd)] pub struct SimdF32([f32; LANES]); impl_float_vector! { SimdF32, f32, SimdU32 } +/// Vector of two `f32` values pub type f32x2 = SimdF32<2>; + +/// Vector of four `f32` values pub type f32x4 = SimdF32<4>; + +/// Vector of eight `f32` values pub type f32x8 = SimdF32<8>; + +/// Vector of 16 `f32` values pub type f32x16 = SimdF32<16>; from_transmute_x86! { unsafe f32x4 => __m128 } diff --git a/crates/core_simd/src/vectors_f64.rs b/crates/core_simd/src/vectors_f64.rs index 4297c9d636c..307f8a4acac 100644 --- a/crates/core_simd/src/vectors_f64.rs +++ b/crates/core_simd/src/vectors_f64.rs @@ -1,13 +1,18 @@ #![allow(non_camel_case_types)] -/// A SIMD vector of containing `LANES` lanes of `f64`. +/// A SIMD vector of containing `LANES` `f64` values. #[repr(simd)] pub struct SimdF64([f64; LANES]); impl_float_vector! { SimdF64, f64, SimdU64 } +/// Vector of two `f64` values pub type f64x2 = SimdF64<2>; + +/// Vector of four `f64` values pub type f64x4 = SimdF64<4>; + +/// Vector of eight `f64` values pub type f64x8 = SimdF64<8>; from_transmute_x86! { unsafe f64x2 => __m128d } diff --git a/crates/core_simd/src/vectors_i128.rs b/crates/core_simd/src/vectors_i128.rs index a48c823cbd6..16e6162be55 100644 --- a/crates/core_simd/src/vectors_i128.rs +++ b/crates/core_simd/src/vectors_i128.rs @@ -1,12 +1,15 @@ #![allow(non_camel_case_types)] -/// A SIMD vector of containing `LANES` lanes of `i128`. +/// A SIMD vector of containing `LANES` `i128` values. #[repr(simd)] pub struct SimdI128([i128; LANES]); impl_integer_vector! { SimdI128, i128 } +/// Vector of two `i128` values pub type i128x2 = SimdI128<2>; + +/// Vector of four `i128` values pub type i128x4 = SimdI128<4>; from_transmute_x86! { unsafe i128x2 => __m256i } diff --git a/crates/core_simd/src/vectors_i16.rs b/crates/core_simd/src/vectors_i16.rs index 7bc522287a3..08cc4af2a5e 100644 --- a/crates/core_simd/src/vectors_i16.rs +++ b/crates/core_simd/src/vectors_i16.rs @@ -1,14 +1,21 @@ #![allow(non_camel_case_types)] -/// A SIMD vector of containing `LANES` lanes of `i16`. +/// A SIMD vector of containing `LANES` `i16` values. #[repr(simd)] pub struct SimdI16([i16; LANES]); impl_integer_vector! { SimdI16, i16 } +/// Vector of four `i16` values pub type i16x4 = SimdI16<4>; + +/// Vector of eight `i16` values pub type i16x8 = SimdI16<8>; + +/// Vector of 16 `i16` values pub type i16x16 = SimdI16<16>; + +/// Vector of 32 `i16` values pub type i16x32 = SimdI16<32>; from_transmute_x86! { unsafe i16x8 => __m128i } diff --git a/crates/core_simd/src/vectors_i32.rs b/crates/core_simd/src/vectors_i32.rs index 05533bb0b6d..116f2abaeee 100644 --- a/crates/core_simd/src/vectors_i32.rs +++ b/crates/core_simd/src/vectors_i32.rs @@ -1,14 +1,21 @@ #![allow(non_camel_case_types)] -/// A SIMD vector of containing `LANES` lanes of `i32`. +/// A SIMD vector of containing `LANES` `i32` values. #[repr(simd)] pub struct SimdI32([i32; LANES]); impl_integer_vector! { SimdI32, i32 } +/// Vector of two `i32` values pub type i32x2 = SimdI32<2>; + +/// Vector of four `i32` values pub type i32x4 = SimdI32<4>; + +/// Vector of eight `i32` values pub type i32x8 = SimdI32<8>; + +/// Vector of 16 `i32` values pub type i32x16 = SimdI32<16>; from_transmute_x86! { unsafe i32x4 => __m128i } diff --git a/crates/core_simd/src/vectors_i64.rs b/crates/core_simd/src/vectors_i64.rs index e669e8a367c..6a1e2094179 100644 --- a/crates/core_simd/src/vectors_i64.rs +++ b/crates/core_simd/src/vectors_i64.rs @@ -1,13 +1,18 @@ #![allow(non_camel_case_types)] -/// A SIMD vector of containing `LANES` lanes of `i64`. +/// A SIMD vector of containing `LANES` `i64` values. #[repr(simd)] pub struct SimdI64([i64; LANES]); impl_integer_vector! { SimdI64, i64 } +/// Vector of two `i64` values pub type i64x2 = SimdI64<2>; + +/// Vector of four `i64` values pub type i64x4 = SimdI64<4>; + +/// Vector of eight `i64` values pub type i64x8 = SimdI64<8>; from_transmute_x86! { unsafe i64x2 => __m128i } diff --git a/crates/core_simd/src/vectors_i8.rs b/crates/core_simd/src/vectors_i8.rs index 55a440cc92f..0ac5ba9efee 100644 --- a/crates/core_simd/src/vectors_i8.rs +++ b/crates/core_simd/src/vectors_i8.rs @@ -1,14 +1,21 @@ #![allow(non_camel_case_types)] -/// A SIMD vector of containing `LANES` lanes of `i8`. +/// A SIMD vector of containing `LANES` `i8` values. #[repr(simd)] pub struct SimdI8([i8; LANES]); impl_integer_vector! { SimdI8, i8 } +/// Vector of eight `i8` values pub type i8x8 = SimdI8<8>; + +/// Vector of 16 `i8` values pub type i8x16 = SimdI8<16>; + +/// Vector of 32 `i8` values pub type i8x32 = SimdI8<32>; + +/// Vector of 64 `i8` values pub type i8x64 = SimdI8<64>; from_transmute_x86! { unsafe i8x16 => __m128i } diff --git a/crates/core_simd/src/vectors_isize.rs b/crates/core_simd/src/vectors_isize.rs index 6d9b2061532..6856f305092 100644 --- a/crates/core_simd/src/vectors_isize.rs +++ b/crates/core_simd/src/vectors_isize.rs @@ -1,13 +1,18 @@ #![allow(non_camel_case_types)] -/// A SIMD vector of containing `LANES` lanes of `isize`. +/// A SIMD vector of containing `LANES` `isize` values. #[repr(simd)] pub struct SimdIsize([isize; LANES]); impl_integer_vector! { SimdIsize, isize } +/// Vector of two `isize` values pub type isizex2 = SimdIsize<2>; + +/// Vector of four `isize` values pub type isizex4 = SimdIsize<4>; + +/// Vector of eight `isize` values pub type isizex8 = SimdIsize<8>; #[cfg(target_pointer_width = "32")] diff --git a/crates/core_simd/src/vectors_u128.rs b/crates/core_simd/src/vectors_u128.rs index 54ad6e191f7..522404f133e 100644 --- a/crates/core_simd/src/vectors_u128.rs +++ b/crates/core_simd/src/vectors_u128.rs @@ -1,12 +1,15 @@ #![allow(non_camel_case_types)] -/// A SIMD vector of containing `LANES` lanes of `u128`. +/// A SIMD vector of containing `LANES` `u128` values. #[repr(simd)] pub struct SimdU128([u128; LANES]); impl_integer_vector! { SimdU128, u128 } +/// Vector of two `u128` values pub type u128x2 = SimdU128<2>; + +/// Vector of four `u128` values pub type u128x4 = SimdU128<4>; from_transmute_x86! { unsafe u128x2 => __m256i } diff --git a/crates/core_simd/src/vectors_u16.rs b/crates/core_simd/src/vectors_u16.rs index 7b0e345ef15..efe7dea58dc 100644 --- a/crates/core_simd/src/vectors_u16.rs +++ b/crates/core_simd/src/vectors_u16.rs @@ -1,14 +1,21 @@ #![allow(non_camel_case_types)] -/// A SIMD vector of containing `LANES` lanes of `u16`. +/// A SIMD vector of containing `LANES` `u16` values. #[repr(simd)] pub struct SimdU16([u16; LANES]); impl_integer_vector! { SimdU16, u16 } +/// Vector of four `u16` values pub type u16x4 = SimdU16<4>; + +/// Vector of eight `u16` values pub type u16x8 = SimdU16<8>; + +/// Vector of 16 `u16` values pub type u16x16 = SimdU16<16>; + +/// Vector of 32 `u16` values pub type u16x32 = SimdU16<32>; from_transmute_x86! { unsafe u16x8 => __m128i } diff --git a/crates/core_simd/src/vectors_u32.rs b/crates/core_simd/src/vectors_u32.rs index f80efbc59eb..a6cef5baeb7 100644 --- a/crates/core_simd/src/vectors_u32.rs +++ b/crates/core_simd/src/vectors_u32.rs @@ -1,14 +1,21 @@ #![allow(non_camel_case_types)] -/// A SIMD vector of containing `LANES` lanes of `u32`. +/// A SIMD vector of containing `LANES` `u32` values. #[repr(simd)] pub struct SimdU32([u32; LANES]); impl_integer_vector! { SimdU32, u32 } +/// Vector of two `u32` values pub type u32x2 = SimdU32<2>; + +/// Vector of four `u32` values pub type u32x4 = SimdU32<4>; + +/// Vector of eight `u32` values pub type u32x8 = SimdU32<8>; + +/// Vector of 16 `u32` values pub type u32x16 = SimdU32<16>; from_transmute_x86! { unsafe u32x4 => __m128i } diff --git a/crates/core_simd/src/vectors_u64.rs b/crates/core_simd/src/vectors_u64.rs index 848d90faaa7..3982e30f570 100644 --- a/crates/core_simd/src/vectors_u64.rs +++ b/crates/core_simd/src/vectors_u64.rs @@ -1,13 +1,18 @@ #![allow(non_camel_case_types)] -/// A SIMD vector of containing `LANES` lanes of `u64`. +/// A SIMD vector of containing `LANES` `u64` values. #[repr(simd)] pub struct SimdU64([u64; LANES]); impl_integer_vector! { SimdU64, u64 } +/// Vector of two `u64` values pub type u64x2 = SimdU64<2>; + +/// Vector of four `u64` values pub type u64x4 = SimdU64<4>; + +/// Vector of eight `u64` values pub type u64x8 = SimdU64<8>; from_transmute_x86! { unsafe u64x2 => __m128i } diff --git a/crates/core_simd/src/vectors_u8.rs b/crates/core_simd/src/vectors_u8.rs index b172801aa99..9cc4eaca47a 100644 --- a/crates/core_simd/src/vectors_u8.rs +++ b/crates/core_simd/src/vectors_u8.rs @@ -1,14 +1,21 @@ #![allow(non_camel_case_types)] -/// A SIMD vector of containing `LANES` lanes of `u8`. +/// A SIMD vector of containing `LANES` `u8` values. #[repr(simd)] pub struct SimdU8([u8; LANES]); impl_integer_vector! { SimdU8, u8 } +/// Vector of eight `u8` values pub type u8x8 = SimdU8<8>; + +/// Vector of 16 `u8` values pub type u8x16 = SimdU8<16>; + +/// Vector of 32 `u8` values pub type u8x32 = SimdU8<32>; + +/// Vector of 64 `u8` values pub type u8x64 = SimdU8<64>; from_transmute_x86! { unsafe u8x16 => __m128i } diff --git a/crates/core_simd/src/vectors_usize.rs b/crates/core_simd/src/vectors_usize.rs index b0655ab311b..c882898f9fb 100644 --- a/crates/core_simd/src/vectors_usize.rs +++ b/crates/core_simd/src/vectors_usize.rs @@ -1,13 +1,18 @@ #![allow(non_camel_case_types)] -/// A SIMD vector of containing `LANES` lanes of `usize`. +/// A SIMD vector of containing `LANES` `usize` values. #[repr(simd)] pub struct SimdUsize([usize; LANES]); impl_integer_vector! { SimdUsize, usize } +/// Vector of two `usize` values pub type usizex2 = SimdUsize<2>; + +/// Vector of four `usize` values pub type usizex4 = SimdUsize<4>; + +/// Vector of eight `usize` values pub type usizex8 = SimdUsize<8>; #[cfg(target_pointer_width = "32")] diff --git a/crates/core_simd/tests/ops_impl/mask_macros.rs b/crates/core_simd/tests/ops_impl/mask_macros.rs index 3aaa036b994..795f9e27c44 100644 --- a/crates/core_simd/tests/ops_impl/mask_macros.rs +++ b/crates/core_simd/tests/ops_impl/mask_macros.rs @@ -1,6 +1,5 @@ macro_rules! mask_tests { { $vector:ident, $lanes:literal } => { - /* #[cfg(test)] mod $vector { use core_simd::$vector as Vector; @@ -222,6 +221,5 @@ macro_rules! mask_tests { assert_eq!(!v, expected); } } - */ } }