From dd1a5e41ad0763cf8f57eba2a92528b895dc9378 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Fri, 2 Apr 2021 08:28:48 -0700 Subject: [PATCH 1/2] Add saturating abs/neg --- crates/core_simd/src/math.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/crates/core_simd/src/math.rs b/crates/core_simd/src/math.rs index 6fabf35e3da3..0d9d62353568 100644 --- a/crates/core_simd/src/math.rs +++ b/crates/core_simd/src/math.rs @@ -78,6 +78,41 @@ macro_rules! impl_int_arith { pub fn saturating_sub(self, second: Self) -> Self { unsafe { crate::intrinsics::simd_saturating_sub(self, second) } } + + /// Lanewise saturating absolute value, implemented in Rust. + /// + /// # Examples + /// # use core_simd::*; + #[doc = concat!("# use core::", stringify!($n), "::{MIN, MAX};")] + #[doc = concat!("let x = ", stringify!($name), "::splat([MIN, -2, 0, 3]);")] + /// let unsat = x.abs(); + /// let sat = x.saturating_abs(); + #[doc = concat!("assert_eq!(unsat, ", stringify!($name), "::from_array([MIN, 2, 0, 3]);")] + #[doc = concat!("assert_eq!(sat, ", stringify!($name), "::from_array([MAX, 2, 0, 3]));")] + /// ``` + #[inline] + pub fn saturating_abs(self) -> Self { + // arith shift for -1 or 0 mask based on sign bit, giving 2s complement + const SHR: $n = <$n>::BITS as $n - 1; + let m = self >> SHR; + (self^m).saturating_sub(m) + } + + /// Lanewise saturating negation, implemented in Rust. + /// + /// # Examples + /// # use core_simd::*; + #[doc = concat!("# use core::", stringify!($n), "::{MIN, MAX};")] + #[doc = concat!("let x = ", stringify!($name), "::splat([MIN, -2, 3, MAX]);")] + /// let unsat = -x; + /// let sat = x.saturating_neg(); + #[doc = concat!("assert_eq!(unsat, ", stringify!($name), "::from_array([MIN, 2, -3, MIN + 1]);")] + #[doc = concat!("assert_eq!(sat, ", stringify!($name), "::from_array([MAX, 2, -3, MIN + 1]));")] + /// ``` + #[inline] + pub fn saturating_neg(self) -> Self { + Self::splat(0).saturating_sub(self) + } })+ } } From 331230fabff28d2c883967e2ac4ef02eaea4db5c Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Fri, 2 Apr 2021 09:11:24 -0700 Subject: [PATCH 2/2] Explain why to use saturation --- crates/core_simd/src/math.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/core_simd/src/math.rs b/crates/core_simd/src/math.rs index 0d9d62353568..eb46feb5c4b4 100644 --- a/crates/core_simd/src/math.rs +++ b/crates/core_simd/src/math.rs @@ -80,6 +80,7 @@ macro_rules! impl_int_arith { } /// Lanewise saturating absolute value, implemented in Rust. + /// As abs(), except the MIN value becomes MAX instead of itself. /// /// # Examples /// # use core_simd::*; @@ -99,6 +100,7 @@ macro_rules! impl_int_arith { } /// Lanewise saturating negation, implemented in Rust. + /// As neg(), except the MIN value becomes MAX instead of itself. /// /// # Examples /// # use core_simd::*;