about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCaleb Zulawski <caleb.zulawski@gmail.com>2023-07-27 16:26:22 -0400
committerCaleb Zulawski <caleb.zulawski@gmail.com>2023-07-27 16:26:22 -0400
commit5c97c0db2457872ef83a2b30c9d30f24963a1752 (patch)
tree7cd917f0d71e63561b136ef79e376d316779d003
parent7c7dbe0c505ccbc02ff30c1e37381ab1d47bf46f (diff)
downloadrust-5c97c0db2457872ef83a2b30c9d30f24963a1752.tar.gz
rust-5c97c0db2457872ef83a2b30c9d30f24963a1752.zip
Add wrapping negation
-rw-r--r--crates/core_simd/src/elements/uint.rs16
-rw-r--r--crates/core_simd/tests/ops_macros.rs10
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<T: SimdCast>(self) -> Self::Cast<T>;
 
+    /// 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<const LANES: usize> Sealed for Simd<$ty, LANES>
         where
@@ -96,6 +102,12 @@ macro_rules! impl_trait {
             }
 
             #[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
                 unsafe { intrinsics::simd_saturating_add(self, second) }
@@ -153,4 +165,4 @@ macro_rules! impl_trait {
     }
 }
 
-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 @@ macro_rules! impl_unsigned_tests {
                 }
             }
 
+            test_helpers::test_lanes! {
+                fn wrapping_neg<const LANES: usize>() {
+                    test_helpers::test_unary_elementwise(
+                        &Vector::<LANES>::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);