From dc81c87aaa0e0c90f736be22b97994f0c2c88b62 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Tue, 13 Oct 2020 01:28:03 -0400 Subject: [PATCH 1/4] Add opaque masks --- crates/core_simd/src/fmt.rs | 20 +- crates/core_simd/src/lib.rs | 16 +- crates/core_simd/src/macros.rs | 11 +- crates/core_simd/src/masks/mod.rs | 215 ++++++++++++++++++ .../src/{masks.rs => masks/wide/mod.rs} | 27 ++- .../core_simd/src/masks/wide/vectors_m128.rs | 11 + .../core_simd/src/masks/wide/vectors_m16.rs | 21 ++ .../core_simd/src/masks/wide/vectors_m32.rs | 21 ++ .../core_simd/src/masks/wide/vectors_m64.rs | 16 ++ crates/core_simd/src/masks/wide/vectors_m8.rs | 21 ++ .../core_simd/src/masks/wide/vectors_msize.rs | 16 ++ crates/core_simd/src/ops.rs | 24 +- crates/core_simd/src/vectors_mask128.rs | 11 - crates/core_simd/src/vectors_mask16.rs | 21 -- crates/core_simd/src/vectors_mask32.rs | 21 -- crates/core_simd/src/vectors_mask64.rs | 16 -- crates/core_simd/src/vectors_mask8.rs | 21 -- crates/core_simd/src/vectors_masksize.rs | 16 -- 18 files changed, 379 insertions(+), 146 deletions(-) create mode 100644 crates/core_simd/src/masks/mod.rs rename crates/core_simd/src/{masks.rs => masks/wide/mod.rs} (87%) create mode 100644 crates/core_simd/src/masks/wide/vectors_m128.rs create mode 100644 crates/core_simd/src/masks/wide/vectors_m16.rs create mode 100644 crates/core_simd/src/masks/wide/vectors_m32.rs create mode 100644 crates/core_simd/src/masks/wide/vectors_m64.rs create mode 100644 crates/core_simd/src/masks/wide/vectors_m8.rs create mode 100644 crates/core_simd/src/masks/wide/vectors_msize.rs delete mode 100644 crates/core_simd/src/vectors_mask128.rs delete mode 100644 crates/core_simd/src/vectors_mask16.rs delete mode 100644 crates/core_simd/src/vectors_mask32.rs delete mode 100644 crates/core_simd/src/vectors_mask64.rs delete mode 100644 crates/core_simd/src/vectors_mask8.rs delete mode 100644 crates/core_simd/src/vectors_masksize.rs diff --git a/crates/core_simd/src/fmt.rs b/crates/core_simd/src/fmt.rs index c634e0546bc..07332c1ccc8 100644 --- a/crates/core_simd/src/fmt.rs +++ b/crates/core_simd/src/fmt.rs @@ -74,10 +74,10 @@ macro_rules! impl_fmt_trait { impl_fmt_trait! { integers: - crate::u8x8, crate::u8x16, crate::u8x32, crate::u8x64, - crate::i8x8, crate::i8x16, crate::i8x32, crate::i8x64, - crate::u16x4, crate::u16x8, crate::u16x16, crate::u16x32, - crate::i16x4, crate::i16x8, crate::i16x16, crate::i16x32, + crate::u8x8, crate::u8x16, crate::u8x32, crate::u8x64, + crate::i8x8, crate::i8x16, crate::i8x32, crate::i8x64, + crate::u16x4, crate::u16x8, crate::u16x16, crate::u16x32, + crate::i16x4, crate::i16x8, crate::i16x16, crate::i16x32, crate::u32x2, crate::u32x4, crate::u32x8, crate::u32x16, crate::i32x2, crate::i32x4, crate::i32x8, crate::i32x16, crate::u64x2, crate::u64x4, crate::u64x8, @@ -96,10 +96,10 @@ impl_fmt_trait! { impl_fmt_trait! { masks: - crate::mask8x8, crate::mask8x16, crate::mask8x32, crate::mask8x64, - crate::mask16x4, crate::mask16x8, crate::mask16x16, crate::mask16x32, - crate::mask32x2, crate::mask32x4, crate::mask32x8, crate::mask32x16, - crate::mask64x2, crate::mask64x4, crate::mask64x8, - crate::mask128x2, crate::mask128x4, - crate::masksizex2, crate::masksizex4, crate::masksizex8, + crate::masks::wide::m8x8, crate::masks::wide::m8x16, crate::masks::wide::m8x32, crate::masks::wide::m8x64, + crate::masks::wide::m16x4, crate::masks::wide::m16x8, crate::masks::wide::m16x16, crate::masks::wide::m16x32, + crate::masks::wide::m32x2, crate::masks::wide::m32x4, crate::masks::wide::m32x8, crate::masks::wide::m32x16, + crate::masks::wide::m64x2, crate::masks::wide::m64x4, crate::masks::wide::m64x8, + crate::masks::wide::m128x2, crate::masks::wide::m128x4, + crate::masks::wide::msizex2, crate::masks::wide::msizex4, crate::masks::wide::msizex8, } diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs index cea39e6f3f3..fd4f9dd16fd 100644 --- a/crates/core_simd/src/lib.rs +++ b/crates/core_simd/src/lib.rs @@ -10,8 +10,7 @@ mod fmt; mod intrinsics; mod ops; -mod masks; -pub use masks::*; +pub mod masks; mod vectors_u8; pub use vectors_u8::*; @@ -44,17 +43,4 @@ pub use vectors_f32::*; mod vectors_f64; pub use vectors_f64::*; -mod vectors_mask8; -pub use vectors_mask8::*; -mod vectors_mask16; -pub use vectors_mask16::*; -mod vectors_mask32; -pub use vectors_mask32::*; -mod vectors_mask64; -pub use vectors_mask64::*; -mod vectors_mask128; -pub use vectors_mask128::*; -mod vectors_masksize; -pub use vectors_masksize::*; - mod round; diff --git a/crates/core_simd/src/macros.rs b/crates/core_simd/src/macros.rs index f37d13c3ca3..b8324ffdb92 100644 --- a/crates/core_simd/src/macros.rs +++ b/crates/core_simd/src/macros.rs @@ -314,7 +314,6 @@ macro_rules! define_float_vector { } } - /// Defines an integer vector `$name` containing multiple `$lanes` of integer `$type`. macro_rules! define_integer_vector { { $(#[$attr:meta])* struct $name:ident([$type:ty; $lanes:tt]); } => { @@ -336,6 +335,7 @@ macro_rules! define_mask_vector { impl $name { call_repeat! { $lanes => define_mask_vector [$impl_type] splat $type | } call_counting_args! { $lanes => define_mask_vector => new $type | } + call_counting_args! { $lanes => define_mask_vector => new_from_bool $type | } } base_vector_traits! { $name => [$type; $lanes] } @@ -361,5 +361,14 @@ macro_rules! define_mask_vector { pub const fn new($($var: $type),*) -> Self { Self($($var.0),*) } + }; + { new_from_bool $type:ty | $($var:ident)* } => { + /// Used internally (since we can't use the Into trait in `const fn`s) + #[allow(clippy::too_many_arguments)] + #[allow(unused)] + #[inline] + pub(crate) const fn new_from_bool($($var: bool),*) -> Self { + Self($(<$type>::new($var).0),*) + } } } diff --git a/crates/core_simd/src/masks/mod.rs b/crates/core_simd/src/masks/mod.rs new file mode 100644 index 00000000000..e138a1b4dd8 --- /dev/null +++ b/crates/core_simd/src/masks/mod.rs @@ -0,0 +1,215 @@ +//! Types and traits associated with masking lanes of vectors. + +pub mod wide; + +trait MaskImpl { + type Mask; +} + +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; +} + +macro_rules! define_opaque_mask { + { + $(#[$attr:meta])* + struct $name:ident([$width:ty; $lanes:tt]); + } => { + $(#[$attr])* + #[allow(non_camel_case_types)] + pub struct $name(<[$width; $lanes] as MaskImpl>::Mask); + + impl $name { + /// Construct a mask by setting all lanes to the given value. + pub fn splat(value: bool) -> Self { + Self(<[$width; $lanes] as MaskImpl>::Mask::splat(value.into())) + } + + call_counting_args! { $lanes => define_opaque_mask => new [$width; $lanes] } + } + }; + { 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 MaskImpl>::Mask::new_from_bool($($var),*)) + } + } +} + +define_opaque_mask! { + /// Mask for 8 8-bit lanes + struct mask8x8([u8; 8]); +} + +define_opaque_mask! { + /// Mask for 16 8-bit lanes + struct mask8x16([u8; 16]); +} + +define_opaque_mask! { + /// Mask for 32 8-bit lanes + struct mask8x32([u8; 32]); +} + +define_opaque_mask! { + /// Mask for 64 8-bit lanes + struct mask8x64([u8; 64]); +} + +define_opaque_mask! { + /// Mask for 4 16-bit lanes + struct mask16x4([u16; 4]); +} + +define_opaque_mask! { + /// Mask for 8 16-bit lanes + struct mask16x8([u16; 8]); +} + +define_opaque_mask! { + /// Mask for 16 16-bit lanes + struct mask16x16([u16; 16]); +} + +define_opaque_mask! { + /// Mask for 32 16-bit lanes + struct mask16x32([u16; 32]); +} + +define_opaque_mask! { + /// Mask for 2 32-bit lanes + struct mask32x2([u32; 2]); +} + +define_opaque_mask! { + /// Mask for 4 32-bit lanes + struct mask32x4([u32; 4]); +} + +define_opaque_mask! { + /// Mask for 8 32-bit lanes + struct mask32x8([u32; 8]); +} + +define_opaque_mask! { + /// Mask for 16 32-bit lanes + struct mask32x16([u32; 16]); +} + +define_opaque_mask! { + /// Mask for 2 64-bit lanes + struct mask64x2([u64; 2]); +} + +define_opaque_mask! { + /// Mask for 4 64-bit lanes + struct mask64x4([u64; 4]); +} + +define_opaque_mask! { + /// Mask for 8 64-bit lanes + struct mask64x8([u64; 8]); +} + +define_opaque_mask! { + /// Mask for 2 128-bit lanes + struct mask128x2([u128; 2]); +} + +define_opaque_mask! { + /// Mask for 4 128-bit lanes + struct mask128x4([u128; 4]); +} + +define_opaque_mask! { + /// Mask for 2 `isize`-wide lanes + struct masksizex2([usize; 2]); +} + +define_opaque_mask! { + /// Mask for 4 `isize`-wide lanes + struct masksizex4([usize; 4]); +} + +define_opaque_mask! { + /// Mask for 8 `isize`-wide lanes + struct masksizex8([usize; 8]); +} diff --git a/crates/core_simd/src/masks.rs b/crates/core_simd/src/masks/wide/mod.rs similarity index 87% rename from crates/core_simd/src/masks.rs rename to crates/core_simd/src/masks/wide/mod.rs index cba76b6a2a3..1462992197d 100644 --- a/crates/core_simd/src/masks.rs +++ b/crates/core_simd/src/masks/wide/mod.rs @@ -1,3 +1,18 @@ +//! 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(()); @@ -95,30 +110,30 @@ macro_rules! define_mask { define_mask! { /// 8-bit mask - struct mask8(i8); + struct m8(i8); } define_mask! { /// 16-bit mask - struct mask16(i16); + struct m16(i16); } define_mask! { /// 32-bit mask - struct mask32(i32); + struct m32(i32); } define_mask! { /// 64-bit mask - struct mask64(i64); + struct m64(i64); } define_mask! { /// 128-bit mask - struct mask128(i128); + struct m128(i128); } define_mask! { /// `isize`-wide mask - struct masksize(isize); + struct msize(isize); } diff --git a/crates/core_simd/src/masks/wide/vectors_m128.rs b/crates/core_simd/src/masks/wide/vectors_m128.rs new file mode 100644 index 00000000000..fddddac5fc4 --- /dev/null +++ b/crates/core_simd/src/masks/wide/vectors_m128.rs @@ -0,0 +1,11 @@ +use super::m128; + +define_mask_vector! { + /// Vector of two `m128` values + struct m128x2([i128 as m128; 2]); +} + +define_mask_vector! { + /// Vector of four `m128` values + struct m128x4([i128 as m128; 4]); +} diff --git a/crates/core_simd/src/masks/wide/vectors_m16.rs b/crates/core_simd/src/masks/wide/vectors_m16.rs new file mode 100644 index 00000000000..3b05e83f673 --- /dev/null +++ b/crates/core_simd/src/masks/wide/vectors_m16.rs @@ -0,0 +1,21 @@ +use super::m16; + +define_mask_vector! { + /// Vector of four `m16` values + struct m16x4([i16 as m16; 4]); +} + +define_mask_vector! { + /// Vector of eight `m16` values + struct m16x8([i16 as m16; 8]); +} + +define_mask_vector! { + /// Vector of 16 `m16` values + struct m16x16([i16 as m16; 16]); +} + +define_mask_vector! { + /// Vector of 32 `m16` values + struct m16x32([i16 as m16; 32]); +} diff --git a/crates/core_simd/src/masks/wide/vectors_m32.rs b/crates/core_simd/src/masks/wide/vectors_m32.rs new file mode 100644 index 00000000000..de5745fb283 --- /dev/null +++ b/crates/core_simd/src/masks/wide/vectors_m32.rs @@ -0,0 +1,21 @@ +use super::m32; + +define_mask_vector! { + /// Vector of two `m32` values + struct m32x2([i32 as m32; 2]); +} + +define_mask_vector! { + /// Vector of four `m32` values + struct m32x4([i32 as m32; 4]); +} + +define_mask_vector! { + /// Vector of eight `m32` values + struct m32x8([i32 as m32; 8]); +} + +define_mask_vector! { + /// Vector of 16 `m32` values + struct m32x16([i32 as m32; 16]); +} diff --git a/crates/core_simd/src/masks/wide/vectors_m64.rs b/crates/core_simd/src/masks/wide/vectors_m64.rs new file mode 100644 index 00000000000..55c8687fcfc --- /dev/null +++ b/crates/core_simd/src/masks/wide/vectors_m64.rs @@ -0,0 +1,16 @@ +use super::m64; + +define_mask_vector! { + /// Vector of two `m64` values + struct m64x2([i64 as m64; 2]); +} + +define_mask_vector! { + /// Vector of four `m64` values + struct m64x4([i64 as m64; 4]); +} + +define_mask_vector! { + /// Vector of eight `m64` values + struct m64x8([i64 as m64; 8]); +} diff --git a/crates/core_simd/src/masks/wide/vectors_m8.rs b/crates/core_simd/src/masks/wide/vectors_m8.rs new file mode 100644 index 00000000000..149e138739d --- /dev/null +++ b/crates/core_simd/src/masks/wide/vectors_m8.rs @@ -0,0 +1,21 @@ +use super::m8; + +define_mask_vector! { + /// Vector of eight `m8` values + struct m8x8([i8 as m8; 8]); +} + +define_mask_vector! { + /// Vector of 16 `m8` values + struct m8x16([i8 as m8; 16]); +} + +define_mask_vector! { + /// Vector of 32 `m8` values + struct m8x32([i8 as m8; 32]); +} + +define_mask_vector! { + /// Vector of 64 `m8` values + struct m8x64([i8 as m8; 64]); +} diff --git a/crates/core_simd/src/masks/wide/vectors_msize.rs b/crates/core_simd/src/masks/wide/vectors_msize.rs new file mode 100644 index 00000000000..497aba8ddbb --- /dev/null +++ b/crates/core_simd/src/masks/wide/vectors_msize.rs @@ -0,0 +1,16 @@ +use super::msize; + +define_mask_vector! { + /// Vector of two `msize` values + struct msizex2([isize as msize; 2]); +} + +define_mask_vector! { + /// Vector of four `msize` values + struct msizex4([isize as msize; 4]); +} + +define_mask_vector! { + /// Vector of eight `msize` values + struct msizex8([isize as msize; 8]); +} diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs index 5a186649821..ac89feca9d6 100644 --- a/crates/core_simd/src/ops.rs +++ b/crates/core_simd/src/ops.rs @@ -96,7 +96,7 @@ macro_rules! impl_ref_ops { } /// Implements op traits for masks -macro_rules! impl_mask_ops { +macro_rules! impl_mask_element_ops { { $($mask:ty),* } => { $( impl_ref_ops! { @@ -161,7 +161,15 @@ macro_rules! impl_mask_ops { )* } } -impl_mask_ops! { crate::mask8, crate::mask16, crate::mask32, crate::mask64, crate::mask128, crate::masksize } + +impl_mask_element_ops! { + crate::masks::wide::m8, + crate::masks::wide::m16, + crate::masks::wide::m32, + crate::masks::wide::m64, + crate::masks::wide::m128, + crate::masks::wide::msize +} /// Automatically implements operators over vectors and scalars for a particular vector. macro_rules! impl_op { @@ -632,10 +640,10 @@ impl_float_ops! { } impl_mask_ops! { - crate::mask8 => crate::mask8x8, crate::mask8x16, crate::mask8x32, crate::mask8x64; - crate::mask16 => crate::mask16x4, crate::mask16x8, crate::mask16x16, crate::mask16x32; - crate::mask32 => crate::mask32x2, crate::mask32x4, crate::mask32x8, crate::mask32x16; - crate::mask64 => crate::mask64x2, crate::mask64x4, crate::mask64x8; - crate::mask128 => crate::mask128x2, crate::mask128x4; - crate::masksize => crate::masksizex2, crate::masksizex4, crate::masksizex8; + crate::masks::wide::m8 => crate::masks::wide::m8x8, crate::masks::wide::m8x16, crate::masks::wide::m8x32, crate::masks::wide::m8x64; + crate::masks::wide::m16 => crate::masks::wide::m16x4, crate::masks::wide::m16x8, crate::masks::wide::m16x16, crate::masks::wide::m16x32; + crate::masks::wide::m32 => crate::masks::wide::m32x2, crate::masks::wide::m32x4, crate::masks::wide::m32x8, crate::masks::wide::m32x16; + crate::masks::wide::m64 => crate::masks::wide::m64x2, crate::masks::wide::m64x4, crate::masks::wide::m64x8; + crate::masks::wide::m128 => crate::masks::wide::m128x2, crate::masks::wide::m128x4; + crate::masks::wide::msize => crate::masks::wide::msizex2, crate::masks::wide::msizex4, crate::masks::wide::msizex8; } diff --git a/crates/core_simd/src/vectors_mask128.rs b/crates/core_simd/src/vectors_mask128.rs deleted file mode 100644 index adf56a3684b..00000000000 --- a/crates/core_simd/src/vectors_mask128.rs +++ /dev/null @@ -1,11 +0,0 @@ -use crate::mask128; - -define_mask_vector! { - /// Vector of two `mask128` values - struct mask128x2([i128 as mask128; 2]); -} - -define_mask_vector! { - /// Vector of four `mask128` values - struct mask128x4([i128 as mask128; 4]); -} diff --git a/crates/core_simd/src/vectors_mask16.rs b/crates/core_simd/src/vectors_mask16.rs deleted file mode 100644 index 406d7255a11..00000000000 --- a/crates/core_simd/src/vectors_mask16.rs +++ /dev/null @@ -1,21 +0,0 @@ -use crate::mask16; - -define_mask_vector! { - /// Vector of four `mask16` values - struct mask16x4([i16 as mask16; 4]); -} - -define_mask_vector! { - /// Vector of eight `mask16` values - struct mask16x8([i16 as mask16; 8]); -} - -define_mask_vector! { - /// Vector of 16 `mask16` values - struct mask16x16([i16 as mask16; 16]); -} - -define_mask_vector! { - /// Vector of 32 `mask16` values - struct mask16x32([i16 as mask16; 32]); -} diff --git a/crates/core_simd/src/vectors_mask32.rs b/crates/core_simd/src/vectors_mask32.rs deleted file mode 100644 index fad191421f3..00000000000 --- a/crates/core_simd/src/vectors_mask32.rs +++ /dev/null @@ -1,21 +0,0 @@ -use crate::mask32; - -define_mask_vector! { - /// Vector of two `mask32` values - struct mask32x2([i32 as mask32; 2]); -} - -define_mask_vector! { - /// Vector of four `mask32` values - struct mask32x4([i32 as mask32; 4]); -} - -define_mask_vector! { - /// Vector of eight `mask32` values - struct mask32x8([i32 as mask32; 8]); -} - -define_mask_vector! { - /// Vector of 16 `mask32` values - struct mask32x16([i32 as mask32; 16]); -} diff --git a/crates/core_simd/src/vectors_mask64.rs b/crates/core_simd/src/vectors_mask64.rs deleted file mode 100644 index 554e731ccf2..00000000000 --- a/crates/core_simd/src/vectors_mask64.rs +++ /dev/null @@ -1,16 +0,0 @@ -use crate::mask64; - -define_mask_vector! { - /// Vector of two `mask64` values - struct mask64x2([i64 as mask64; 2]); -} - -define_mask_vector! { - /// Vector of four `mask64` values - struct mask64x4([i64 as mask64; 4]); -} - -define_mask_vector! { - /// Vector of eight `mask64` values - struct mask64x8([i64 as mask64; 8]); -} diff --git a/crates/core_simd/src/vectors_mask8.rs b/crates/core_simd/src/vectors_mask8.rs deleted file mode 100644 index d038b336104..00000000000 --- a/crates/core_simd/src/vectors_mask8.rs +++ /dev/null @@ -1,21 +0,0 @@ -use crate::mask8; - -define_mask_vector! { - /// Vector of eight `mask8` values - struct mask8x8([i8 as mask8; 8]); -} - -define_mask_vector! { - /// Vector of 16 `mask8` values - struct mask8x16([i8 as mask8; 16]); -} - -define_mask_vector! { - /// Vector of 32 `mask8` values - struct mask8x32([i8 as mask8; 32]); -} - -define_mask_vector! { - /// Vector of 64 `mask8` values - struct mask8x64([i8 as mask8; 64]); -} diff --git a/crates/core_simd/src/vectors_masksize.rs b/crates/core_simd/src/vectors_masksize.rs deleted file mode 100644 index a838aee5198..00000000000 --- a/crates/core_simd/src/vectors_masksize.rs +++ /dev/null @@ -1,16 +0,0 @@ -use crate::masksize; - -define_mask_vector! { - /// Vector of two `masksize` values - struct masksizex2([isize as masksize; 2]); -} - -define_mask_vector! { - /// Vector of four `masksize` values - struct masksizex4([isize as masksize; 4]); -} - -define_mask_vector! { - /// Vector of eight `masksize` values - struct masksizex8([isize as masksize; 8]); -} From 60d8e21f53f23a936fda3230ba3fc1655a2ef37e Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Wed, 28 Oct 2020 16:27:15 -0400 Subject: [PATCH 2/4] Add comparison ops --- crates/core_simd/src/intrinsics.rs | 7 + crates/core_simd/src/lib.rs | 1 + crates/core_simd/src/macros.rs | 18 ++ crates/core_simd/src/masks/mod.rs | 263 ++++++++++++++++++++--------- crates/core_simd/src/masks/ops.rs | 208 +++++++++++++++++++++++ 5 files changed, 414 insertions(+), 83 deletions(-) create mode 100644 crates/core_simd/src/masks/ops.rs diff --git a/crates/core_simd/src/intrinsics.rs b/crates/core_simd/src/intrinsics.rs index acf85983a98..c9461d092aa 100644 --- a/crates/core_simd/src/intrinsics.rs +++ b/crates/core_simd/src/intrinsics.rs @@ -39,4 +39,11 @@ extern "platform-intrinsic" { /// fptoui/fptosi/uitofp/sitofp pub(crate) fn simd_cast(x: T) -> U; + + pub(crate) fn simd_eq(x: T, y: T) -> U; + pub(crate) fn simd_ne(x: T, y: T) -> U; + pub(crate) fn simd_lt(x: T, y: T) -> U; + pub(crate) fn simd_le(x: T, y: T) -> U; + pub(crate) fn simd_gt(x: T, y: T) -> U; + pub(crate) fn simd_ge(x: T, y: T) -> U; } diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs index fd4f9dd16fd..3c581ad659b 100644 --- a/crates/core_simd/src/lib.rs +++ b/crates/core_simd/src/lib.rs @@ -11,6 +11,7 @@ mod intrinsics; mod ops; pub mod masks; +pub use masks::opaque::*; mod vectors_u8; pub use vectors_u8::*; diff --git a/crates/core_simd/src/macros.rs b/crates/core_simd/src/macros.rs index b8324ffdb92..75584f58b78 100644 --- a/crates/core_simd/src/macros.rs +++ b/crates/core_simd/src/macros.rs @@ -336,6 +336,24 @@ macro_rules! define_mask_vector { call_repeat! { $lanes => define_mask_vector [$impl_type] splat $type | } call_counting_args! { $lanes => define_mask_vector => new $type | } call_counting_args! { $lanes => define_mask_vector => new_from_bool $type | } + + /// 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[lane].test() + } + + /// 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[lane] = value.into(); + } } base_vector_traits! { $name => [$type; $lanes] } diff --git a/crates/core_simd/src/masks/mod.rs b/crates/core_simd/src/masks/mod.rs index e138a1b4dd8..6688db290e2 100644 --- a/crates/core_simd/src/masks/mod.rs +++ b/crates/core_simd/src/masks/mod.rs @@ -2,7 +2,10 @@ pub mod wide; -trait MaskImpl { +mod ops; +pub use ops::*; + +pub(crate) trait MaskImpl { type Mask; } @@ -93,15 +96,67 @@ macro_rules! define_opaque_mask { } => { $(#[$attr])* #[allow(non_camel_case_types)] - pub struct $name(<[$width; $lanes] as MaskImpl>::Mask); + pub struct $name(<[$width; $lanes] as crate::masks::MaskImpl>::Mask); impl $name { + pub(crate) fn new_from_inner(inner: <[$width; $lanes] as crate::masks::MaskImpl>::Mask) -> Self { + Self(inner) + } + /// Construct a mask by setting all lanes to the given value. pub fn splat(value: bool) -> Self { - Self(<[$width; $lanes] as MaskImpl>::Mask::splat(value.into())) + Self(<[$width; $lanes] as crate::masks::MaskImpl>::Mask::splat(value.into())) } call_counting_args! { $lanes => define_opaque_mask => new [$width; $lanes] } + + /// 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.test(lane) + } + + /// 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.set(lane, value); + } + } + + impl Copy for $name {} + + impl Clone for $name { + #[inline] + fn clone(&self) -> Self { + *self + } + } + + impl Default for $name { + #[inline] + fn default() -> Self { + Self::splat(false) + } + } + + impl PartialEq for $name { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } + } + + impl PartialOrd for $name { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option { + self.0.partial_cmp(&other.0) + } } }; { new [$width:ty; $lanes:tt] $($var:ident)* } => { @@ -109,107 +164,149 @@ macro_rules! define_opaque_mask { #[allow(clippy::too_many_arguments)] #[inline] pub const fn new($($var: bool),*) -> Self { - Self(<[$width; $lanes] as MaskImpl>::Mask::new_from_bool($($var),*)) + Self(<[$width; $lanes] as crate::masks::MaskImpl>::Mask::new_from_bool($($var),*)) } } } -define_opaque_mask! { - /// Mask for 8 8-bit lanes - struct mask8x8([u8; 8]); -} +pub(crate) mod opaque { + define_opaque_mask! { + /// Mask for 8 8-bit lanes. + /// + /// The layout of this type is unspecified. + struct mask8x8([u8; 8]); + } -define_opaque_mask! { - /// Mask for 16 8-bit lanes - struct mask8x16([u8; 16]); -} + define_opaque_mask! { + /// Mask for 16 8-bit lanes. + /// + /// The layout of this type is unspecified. + struct mask8x16([u8; 16]); + } -define_opaque_mask! { - /// Mask for 32 8-bit lanes - struct mask8x32([u8; 32]); -} + 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 - struct mask8x64([u8; 64]); -} + 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 - struct mask16x4([u16; 4]); -} + 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 - struct mask16x8([u16; 8]); -} + 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 - struct mask16x16([u16; 16]); -} + 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 - struct mask16x32([u16; 32]); -} + 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 - struct mask32x2([u32; 2]); -} + 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 - struct mask32x4([u32; 4]); -} + 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 - struct mask32x8([u32; 8]); -} + 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 - struct mask32x16([u32; 16]); -} + 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 - struct mask64x2([u64; 2]); -} + 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 - struct mask64x4([u64; 4]); -} + 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 - struct mask64x8([u64; 8]); -} + 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 - struct mask128x2([u128; 2]); -} + 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 - struct mask128x4([u128; 4]); -} + 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 - struct masksizex2([usize; 2]); -} + 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 - struct masksizex4([usize; 4]); -} + 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 - struct masksizex8([usize; 8]); + define_opaque_mask! { + /// Mask for 8 `isize`-wide lanes. + /// + /// The layout of this type is unspecified. + struct masksizex8([usize; 8]); + } } diff --git a/crates/core_simd/src/masks/ops.rs b/crates/core_simd/src/masks/ops.rs new file mode 100644 index 00000000000..85ce955459a --- /dev/null +++ b/crates/core_simd/src/masks/ops.rs @@ -0,0 +1,208 @@ +/// 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, +} From 203317e5758f0663600974f0f02cc8b081b28888 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sun, 22 Nov 2020 15:18:31 -0500 Subject: [PATCH 3/4] Implement missing traits on opaque masks, fix tests --- crates/core_simd/src/masks/mod.rs | 130 ++++++++++++++++++ crates/core_simd/tests/helpers/biteq.rs | 19 ++- crates/core_simd/tests/ops_impl/mask128.rs | 6 +- crates/core_simd/tests/ops_impl/mask16.rs | 10 +- crates/core_simd/tests/ops_impl/mask32.rs | 10 +- crates/core_simd/tests/ops_impl/mask64.rs | 8 +- crates/core_simd/tests/ops_impl/mask8.rs | 10 +- .../core_simd/tests/ops_impl/mask_macros.rs | 118 +++++++++------- crates/core_simd/tests/ops_impl/masksize.rs | 8 +- 9 files changed, 233 insertions(+), 86 deletions(-) diff --git a/crates/core_simd/src/masks/mod.rs b/crates/core_simd/src/masks/mod.rs index 6688db290e2..676a5560d2f 100644 --- a/crates/core_simd/src/masks/mod.rs +++ b/crates/core_simd/src/masks/mod.rs @@ -158,6 +158,136 @@ macro_rules! define_opaque_mask { self.0.partial_cmp(&other.0) } } + + impl core::fmt::Debug for $name { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + f.debug_list() + .entries((0..$lanes).map(|i| self.test(i))) + .finish() + } + } + + 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. diff --git a/crates/core_simd/tests/helpers/biteq.rs b/crates/core_simd/tests/helpers/biteq.rs index f932eba907c..00fc31f3d05 100644 --- a/crates/core_simd/tests/helpers/biteq.rs +++ b/crates/core_simd/tests/helpers/biteq.rs @@ -70,7 +70,12 @@ impl_biteq! { integer impl BitEq for u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, - core_simd::mask8, core_simd::mask16, core_simd::mask32, core_simd::mask64, core_simd::mask128, core_simd::masksize, + core_simd::masks::wide::m8, + core_simd::masks::wide::m16, + core_simd::masks::wide::m32, + core_simd::masks::wide::m64, + core_simd::masks::wide::m128, + core_simd::masks::wide::msize, } impl_biteq! { @@ -93,12 +98,12 @@ impl_biteq! { core_simd::isizex2, core_simd::isizex4, core_simd::isizex8, core_simd::f32x2, core_simd::f32x4, core_simd::f32x8, core_simd::f32x16, core_simd::f64x2, core_simd::f64x4, core_simd::f64x8, - core_simd::mask8x8, core_simd::mask8x16, core_simd::mask8x32, core_simd::mask8x64, - core_simd::mask16x4, core_simd::mask16x8, core_simd::mask16x16, core_simd::mask16x32, - core_simd::mask32x2, core_simd::mask32x4, core_simd::mask32x8, core_simd::mask32x16, - core_simd::mask64x2, core_simd::mask64x4, core_simd::mask64x8, - core_simd::mask128x2, core_simd::mask128x4, - core_simd::masksizex2, core_simd::masksizex4, core_simd::masksizex8, + core_simd::masks::wide::m8x8, core_simd::masks::wide::m8x16, core_simd::masks::wide::m8x32, core_simd::masks::wide::m8x64, + core_simd::masks::wide::m16x4, core_simd::masks::wide::m16x8, core_simd::masks::wide::m16x16, core_simd::masks::wide::m16x32, + core_simd::masks::wide::m32x2, core_simd::masks::wide::m32x4, core_simd::masks::wide::m32x8, core_simd::masks::wide::m32x16, + core_simd::masks::wide::m64x2, core_simd::masks::wide::m64x4, core_simd::masks::wide::m64x8, + core_simd::masks::wide::m128x2, core_simd::masks::wide::m128x4, + core_simd::masks::wide::msizex2, core_simd::masks::wide::msizex4, core_simd::masks::wide::msizex8, } pub(crate) struct BitEqWrapper<'a, T>(pub(crate) &'a T); diff --git a/crates/core_simd/tests/ops_impl/mask128.rs b/crates/core_simd/tests/ops_impl/mask128.rs index f0bcdb4d4df..27ba4e2d29f 100644 --- a/crates/core_simd/tests/ops_impl/mask128.rs +++ b/crates/core_simd/tests/ops_impl/mask128.rs @@ -1,4 +1,2 @@ -use super::helpers; - -mask_tests! { mask128x2, mask128 } -mask_tests! { mask128x4, mask128 } +mask_tests! { mask128x2, 2 } +mask_tests! { mask128x4, 4 } diff --git a/crates/core_simd/tests/ops_impl/mask16.rs b/crates/core_simd/tests/ops_impl/mask16.rs index 6f3f8e0ee02..0fe82fa6804 100644 --- a/crates/core_simd/tests/ops_impl/mask16.rs +++ b/crates/core_simd/tests/ops_impl/mask16.rs @@ -1,6 +1,4 @@ -use super::helpers; - -mask_tests! { mask16x4, mask16 } -mask_tests! { mask16x8, mask16 } -mask_tests! { mask16x16, mask16 } -mask_tests! { mask16x32, mask16 } +mask_tests! { mask16x4, 4 } +mask_tests! { mask16x8, 8 } +mask_tests! { mask16x16, 16 } +mask_tests! { mask16x32, 32 } diff --git a/crates/core_simd/tests/ops_impl/mask32.rs b/crates/core_simd/tests/ops_impl/mask32.rs index 5c35885a2f5..66d987a43ce 100644 --- a/crates/core_simd/tests/ops_impl/mask32.rs +++ b/crates/core_simd/tests/ops_impl/mask32.rs @@ -1,6 +1,4 @@ -use super::helpers; - -mask_tests! { mask32x2, mask32 } -mask_tests! { mask32x4, mask32 } -mask_tests! { mask32x8, mask32 } -mask_tests! { mask32x16, mask32 } +mask_tests! { mask32x2, 2 } +mask_tests! { mask32x4, 4 } +mask_tests! { mask32x8, 8 } +mask_tests! { mask32x16, 16 } diff --git a/crates/core_simd/tests/ops_impl/mask64.rs b/crates/core_simd/tests/ops_impl/mask64.rs index 88d3211465c..a1f1f67b238 100644 --- a/crates/core_simd/tests/ops_impl/mask64.rs +++ b/crates/core_simd/tests/ops_impl/mask64.rs @@ -1,5 +1,3 @@ -use super::helpers; - -mask_tests! { mask64x2, mask64 } -mask_tests! { mask64x4, mask64 } -mask_tests! { mask64x8, mask64 } +mask_tests! { mask64x2, 2 } +mask_tests! { mask64x4, 4 } +mask_tests! { mask64x8, 8 } diff --git a/crates/core_simd/tests/ops_impl/mask8.rs b/crates/core_simd/tests/ops_impl/mask8.rs index fa4bcf09f36..218fa9fe895 100644 --- a/crates/core_simd/tests/ops_impl/mask8.rs +++ b/crates/core_simd/tests/ops_impl/mask8.rs @@ -1,6 +1,4 @@ -use super::helpers; - -mask_tests! { mask8x8, mask8 } -mask_tests! { mask8x16, mask8 } -mask_tests! { mask8x32, mask8 } -mask_tests! { mask8x64, mask8 } +mask_tests! { mask8x8, 8 } +mask_tests! { mask8x16, 16 } +mask_tests! { mask8x32, 32 } +mask_tests! { mask8x64, 64 } diff --git a/crates/core_simd/tests/ops_impl/mask_macros.rs b/crates/core_simd/tests/ops_impl/mask_macros.rs index e6aee4c1d30..795f9e27c44 100644 --- a/crates/core_simd/tests/ops_impl/mask_macros.rs +++ b/crates/core_simd/tests/ops_impl/mask_macros.rs @@ -1,9 +1,9 @@ macro_rules! mask_tests { - { $vector:ident, $scalar:ident } => { + { $vector:ident, $lanes:literal } => { #[cfg(test)] mod $vector { - use super::*; - use helpers::lanewise::*; + use core_simd::$vector as Vector; + const LANES: usize = $lanes; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; @@ -11,15 +11,44 @@ macro_rules! mask_tests { #[cfg(target_arch = "wasm32")] wasm_bindgen_test_configure!(run_in_browser); - fn from_slice(slice: &[bool]) -> core_simd::$vector { - let mut value = core_simd::$vector::default(); - let value_slice: &mut [_] = value.as_mut(); - for (m, b) in value_slice.iter_mut().zip(slice.iter()) { - *m = (*b).into(); + fn from_slice(slice: &[bool]) -> Vector { + let mut value = Vector::default(); + for (i, b) in slice.iter().take(LANES).enumerate() { + value.set(i, *b); } value } + fn apply_unary_lanewise(x: Vector, f: impl Fn(bool) -> bool) -> Vector { + let mut value = Vector::default(); + for i in 0..LANES { + value.set(i, f(x.test(i))); + } + value + } + + fn apply_binary_lanewise(x: Vector, y: Vector, f: impl Fn(bool, bool) -> bool) -> Vector { + let mut value = Vector::default(); + for i in 0..LANES { + value.set(i, f(x.test(i), y.test(i))); + } + value + } + + fn apply_binary_scalar_lhs_lanewise(x: bool, mut y: Vector, f: impl Fn(bool, bool) -> bool) -> Vector { + for i in 0..LANES { + y.set(i, f(x, y.test(i))); + } + y + } + + fn apply_binary_scalar_rhs_lanewise(mut x: Vector, y: bool, f: impl Fn(bool, bool) -> bool) -> Vector { + for i in 0..LANES { + x.set(i, f(x.test(i), y)); + } + x + } + const A: [bool; 64] = [ false, true, false, true, false, false, true, true, false, true, false, true, false, false, true, true, @@ -41,18 +70,13 @@ macro_rules! mask_tests { false, false, true, true, false, true, false, true, ]; - const SET_SCALAR: core_simd::$scalar = core_simd::$scalar::new(true); - const UNSET_SCALAR: core_simd::$scalar = core_simd::$scalar::new(false); - const SET_VECTOR: core_simd::$vector = core_simd::$vector::splat(SET_SCALAR); - const UNSET_VECTOR: core_simd::$vector = core_simd::$vector::splat(UNSET_SCALAR); - #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn bitand() { let a = from_slice(&A); let b = from_slice(&B); let expected = apply_binary_lanewise(a, b, core::ops::BitAnd::bitand); - assert_biteq!(a & b, expected); + assert_eq!(a & b, expected); } #[test] @@ -62,7 +86,7 @@ macro_rules! mask_tests { let b = from_slice(&B); let expected = apply_binary_lanewise(a, b, core::ops::BitAnd::bitand); a &= b; - assert_biteq!(a, expected); + assert_eq!(a, expected); } #[test] @@ -70,8 +94,8 @@ macro_rules! mask_tests { fn bitand_scalar_rhs() { let a = from_slice(&A); let expected = a; - assert_biteq!(a & SET_SCALAR, expected); - assert_biteq!(a & UNSET_SCALAR, UNSET_VECTOR); + assert_eq!(a & true, expected); + assert_eq!(a & false, Vector::splat(false)); } #[test] @@ -79,8 +103,8 @@ macro_rules! mask_tests { fn bitand_scalar_lhs() { let a = from_slice(&A); let expected = a; - assert_biteq!(SET_SCALAR & a, expected); - assert_biteq!(UNSET_SCALAR & a, UNSET_VECTOR); + assert_eq!(true & a, expected); + assert_eq!(false & a, Vector::splat(false)); } #[test] @@ -88,10 +112,10 @@ macro_rules! mask_tests { fn bitand_assign_scalar() { let mut a = from_slice(&A); let expected = a; - a &= SET_SCALAR; - assert_biteq!(a, expected); - a &= UNSET_SCALAR; - assert_biteq!(a, UNSET_VECTOR); + a &= true; + assert_eq!(a, expected); + a &= false; + assert_eq!(a, Vector::splat(false)); } #[test] @@ -100,7 +124,7 @@ macro_rules! mask_tests { let a = from_slice(&A); let b = from_slice(&B); let expected = apply_binary_lanewise(a, b, core::ops::BitOr::bitor); - assert_biteq!(a | b, expected); + assert_eq!(a | b, expected); } #[test] @@ -110,23 +134,23 @@ macro_rules! mask_tests { let b = from_slice(&B); let expected = apply_binary_lanewise(a, b, core::ops::BitOr::bitor); a |= b; - assert_biteq!(a, expected); + assert_eq!(a, expected); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn bitor_scalar_rhs() { let a = from_slice(&A); - assert_biteq!(a | UNSET_SCALAR, a); - assert_biteq!(a | SET_SCALAR, SET_VECTOR); + assert_eq!(a | false, a); + assert_eq!(a | true, Vector::splat(true)); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn bitor_scalar_lhs() { let a = from_slice(&A); - assert_biteq!(UNSET_SCALAR | a, a); - assert_biteq!(SET_SCALAR | a, SET_VECTOR); + assert_eq!(false | a, a); + assert_eq!(true | a, Vector::splat(true)); } #[test] @@ -134,10 +158,10 @@ macro_rules! mask_tests { fn bitor_assign_scalar() { let mut a = from_slice(&A); let expected = a; - a |= UNSET_SCALAR; - assert_biteq!(a, expected); - a |= SET_SCALAR; - assert_biteq!(a, SET_VECTOR); + a |= false; + assert_eq!(a, expected); + a |= true; + assert_eq!(a, Vector::splat(true)); } #[test] @@ -146,7 +170,7 @@ macro_rules! mask_tests { let a = from_slice(&A); let b = from_slice(&B); let expected = apply_binary_lanewise(a, b, core::ops::BitXor::bitxor); - assert_biteq!(a ^ b, expected); + assert_eq!(a ^ b, expected); } #[test] @@ -156,25 +180,25 @@ macro_rules! mask_tests { let b = from_slice(&B); let expected = apply_binary_lanewise(a, b, core::ops::BitXor::bitxor); a ^= b; - assert_biteq!(a, expected); + assert_eq!(a, expected); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn bitxor_scalar_rhs() { let a = from_slice(&A); - let expected = apply_binary_scalar_rhs_lanewise(a, SET_SCALAR, core::ops::BitXor::bitxor); - assert_biteq!(a ^ UNSET_SCALAR, a); - assert_biteq!(a ^ SET_SCALAR, expected); + let expected = apply_binary_scalar_rhs_lanewise(a, true, core::ops::BitXor::bitxor); + assert_eq!(a ^ false, a); + assert_eq!(a ^ true, expected); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn bitxor_scalar_lhs() { let a = from_slice(&A); - let expected = apply_binary_scalar_lhs_lanewise(SET_SCALAR, a, core::ops::BitXor::bitxor); - assert_biteq!(UNSET_SCALAR ^ a, a); - assert_biteq!(SET_SCALAR ^ a, expected); + let expected = apply_binary_scalar_lhs_lanewise(true, a, core::ops::BitXor::bitxor); + assert_eq!(false ^ a, a); + assert_eq!(true ^ a, expected); } #[test] @@ -182,11 +206,11 @@ macro_rules! mask_tests { fn bitxor_assign_scalar() { let mut a = from_slice(&A); let expected_unset = a; - let expected_set = apply_binary_scalar_rhs_lanewise(a, SET_SCALAR, core::ops::BitXor::bitxor); - a ^= UNSET_SCALAR; - assert_biteq!(a, expected_unset); - a ^= SET_SCALAR; - assert_biteq!(a, expected_set); + let expected_set = apply_binary_scalar_rhs_lanewise(a, true, core::ops::BitXor::bitxor); + a ^= false; + assert_eq!(a, expected_unset); + a ^= true; + assert_eq!(a, expected_set); } #[test] @@ -194,7 +218,7 @@ macro_rules! mask_tests { fn not() { let v = from_slice(&A); let expected = apply_unary_lanewise(v, core::ops::Not::not); - assert_biteq!(!v, expected); + assert_eq!(!v, expected); } } } diff --git a/crates/core_simd/tests/ops_impl/masksize.rs b/crates/core_simd/tests/ops_impl/masksize.rs index 76e333f3c15..e0a44d870ca 100644 --- a/crates/core_simd/tests/ops_impl/masksize.rs +++ b/crates/core_simd/tests/ops_impl/masksize.rs @@ -1,5 +1,3 @@ -use super::helpers; - -mask_tests! { masksizex2, masksize } -mask_tests! { masksizex4, masksize } -mask_tests! { masksizex8, masksize } +mask_tests! { masksizex2, 2 } +mask_tests! { masksizex4, 4 } +mask_tests! { masksizex8, 8 } From 37c07468f49f9089c6c75fef3c9f2b288d85e036 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Fri, 27 Nov 2020 00:23:49 -0500 Subject: [PATCH 4/4] Simplify some formatting --- crates/core_simd/src/masks/mod.rs | 4 +--- crates/core_simd/src/masks/wide/mod.rs | 8 ++++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/crates/core_simd/src/masks/mod.rs b/crates/core_simd/src/masks/mod.rs index 676a5560d2f..9fb3da00604 100644 --- a/crates/core_simd/src/masks/mod.rs +++ b/crates/core_simd/src/masks/mod.rs @@ -161,9 +161,7 @@ macro_rules! define_opaque_mask { impl core::fmt::Debug for $name { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - f.debug_list() - .entries((0..$lanes).map(|i| self.test(i))) - .finish() + core::fmt::Debug::fmt(&self.0, f) } } diff --git a/crates/core_simd/src/masks/wide/mod.rs b/crates/core_simd/src/masks/wide/mod.rs index 1462992197d..7df8ca7e53d 100644 --- a/crates/core_simd/src/masks/wide/mod.rs +++ b/crates/core_simd/src/masks/wide/mod.rs @@ -84,25 +84,25 @@ macro_rules! define_mask { impl core::fmt::Binary for $name { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - <$type as core::fmt::Binary>::fmt(&self.0, f) + core::fmt::Binary::fmt(&self.0, f) } } impl core::fmt::Octal for $name { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - <$type as core::fmt::Octal>::fmt(&self.0, f) + core::fmt::Octal::fmt(&self.0, f) } } impl core::fmt::LowerHex for $name { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - <$type as core::fmt::LowerHex>::fmt(&self.0, f) + core::fmt::LowerHex::fmt(&self.0, f) } } impl core::fmt::UpperHex for $name { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - <$type as core::fmt::UpperHex>::fmt(&self.0, f) + core::fmt::UpperHex::fmt(&self.0, f) } } }