diff options
| author | Caleb Zulawski <caleb.zulawski@gmail.com> | 2021-04-02 19:41:59 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-04-02 19:41:59 -0400 |
| commit | 4e6d44086cb817cc81b5528d643bab53095773cb (patch) | |
| tree | d833cff6ee3b40352bb76800868d7f420b70d76b | |
| parent | 6620015a779a5391808d16d3e65459bd0bdfb65b (diff) | |
| parent | 331230fabff28d2c883967e2ac4ef02eaea4db5c (diff) | |
| download | rust-4e6d44086cb817cc81b5528d643bab53095773cb.tar.gz rust-4e6d44086cb817cc81b5528d643bab53095773cb.zip | |
Merge pull request #87 from rust-lang/feat/sat-abs-neg
Add saturating abs/neg
| -rw-r--r-- | crates/core_simd/src/math.rs | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/crates/core_simd/src/math.rs b/crates/core_simd/src/math.rs index 6fabf35e3da..eb46feb5c4b 100644 --- a/crates/core_simd/src/math.rs +++ b/crates/core_simd/src/math.rs @@ -78,6 +78,43 @@ 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. + /// As abs(), except the MIN value becomes MAX instead of itself. + /// + /// # 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. + /// As neg(), except the MIN value becomes MAX instead of itself. + /// + /// # 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) + } })+ } } |
