From 5c97c0db2457872ef83a2b30c9d30f24963a1752 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Thu, 27 Jul 2023 16:26:22 -0400 Subject: [PATCH] Add wrapping negation --- crates/core_simd/src/elements/uint.rs | 16 ++++++++++++++-- crates/core_simd/tests/ops_macros.rs | 10 ++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/crates/core_simd/src/elements/uint.rs b/crates/core_simd/src/elements/uint.rs index 3926c395ec9..c8bf24998dd 100644 --- a/crates/core_simd/src/elements/uint.rs +++ b/crates/core_simd/src/elements/uint.rs @@ -16,6 +16,12 @@ pub trait SimdUint: Copy + Sealed { #[must_use] fn cast(self) -> Self::Cast; + /// Wrapping negation. + /// + /// Like [`u32::wrapping_neg`], all applications of this function will wrap, with the exception + /// of `-0`. + fn wrapping_neg(self) -> Self; + /// Lanewise saturating add. /// /// # Examples @@ -74,7 +80,7 @@ pub trait SimdUint: Copy + Sealed { } macro_rules! impl_trait { - { $($ty:ty),* } => { + { $($ty:ident ($signed:ident)),* } => { $( impl Sealed for Simd<$ty, LANES> where @@ -95,6 +101,12 @@ fn cast(self) -> Self::Cast { unsafe { intrinsics::simd_as(self) } } + #[inline] + fn wrapping_neg(self) -> Self { + use crate::simd::SimdInt; + (-self.cast::<$signed>()).cast() + } + #[inline] fn saturating_add(self, second: Self) -> Self { // Safety: `self` is a vector @@ -153,4 +165,4 @@ fn reduce_xor(self) -> Self::Scalar { } } -impl_trait! { u8, u16, u32, u64, usize } +impl_trait! { u8 (i8), u16 (i16), u32 (i32), u64 (i64), usize (isize) } diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs index 3a02f3f01e1..ee0d3ce2f5a 100644 --- a/crates/core_simd/tests/ops_macros.rs +++ b/crates/core_simd/tests/ops_macros.rs @@ -327,6 +327,16 @@ fn rem_zero_panic() { } } + test_helpers::test_lanes! { + fn wrapping_neg() { + test_helpers::test_unary_elementwise( + &Vector::::wrapping_neg, + &Scalar::wrapping_neg, + &|_| true, + ); + } + } + impl_binary_op_test!(Scalar, Add::add, AddAssign::add_assign, Scalar::wrapping_add); impl_binary_op_test!(Scalar, Sub::sub, SubAssign::sub_assign, Scalar::wrapping_sub); impl_binary_op_test!(Scalar, Mul::mul, MulAssign::mul_assign, Scalar::wrapping_mul);