about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJubilee Young <workingjubilee@gmail.com>2021-04-25 15:03:17 -0700
committerJubilee Young <workingjubilee@gmail.com>2021-04-25 18:31:49 -0700
commit6ea08d8d5fd207bdd6ebd8b26b1a552a708f36b5 (patch)
tree908e4b2323461cb70740457d0298dfaf076e64a6
parentb4fda6ef06be190aa655bb23a9c66e46589daff4 (diff)
downloadrust-6ea08d8d5fd207bdd6ebd8b26b1a552a708f36b5.tar.gz
rust-6ea08d8d5fd207bdd6ebd8b26b1a552a708f36b5.zip
Add SIMD round, trunc, fract
-rw-r--r--crates/core_simd/src/intrinsics.rs6
-rw-r--r--crates/core_simd/src/round.rs29
-rw-r--r--crates/core_simd/tests/round.rs24
3 files changed, 55 insertions, 4 deletions
diff --git a/crates/core_simd/src/intrinsics.rs b/crates/core_simd/src/intrinsics.rs
index e8bcca22f68..665dc1a51d7 100644
--- a/crates/core_simd/src/intrinsics.rs
+++ b/crates/core_simd/src/intrinsics.rs
@@ -86,6 +86,12 @@ mod std {
 
         // floor
         pub(crate) fn simd_floor<T>(x: T) -> T;
+
+        // round
+        pub(crate) fn simd_round<T>(x: T) -> T;
+
+        // trunc
+        pub(crate) fn simd_trunc<T>(x: T) -> T;
     }
 }
 
diff --git a/crates/core_simd/src/round.rs b/crates/core_simd/src/round.rs
index 1855c1480d2..281851c68ac 100644
--- a/crates/core_simd/src/round.rs
+++ b/crates/core_simd/src/round.rs
@@ -7,18 +7,39 @@ macro_rules! implement {
         where
             Self: crate::LanesAtMost32,
         {
-            /// Returns the largest integer less than or equal to each lane.
+            /// Returns the smallest integer greater than or equal to each lane.
+            #[must_use = "method returns a new vector and does not mutate the original value"]
+            #[inline]
+            pub fn ceil(self) -> Self {
+                unsafe { crate::intrinsics::simd_ceil(self) }
+            }
+
+            /// Returns the largest integer value less than or equal to each lane.
             #[must_use = "method returns a new vector and does not mutate the original value"]
             #[inline]
             pub fn floor(self) -> Self {
                 unsafe { crate::intrinsics::simd_floor(self) }
             }
 
-            /// Returns the smallest integer greater than or equal to each lane.
+            /// Rounds to the nearest integer value. Ties round toward zero.
             #[must_use = "method returns a new vector and does not mutate the original value"]
             #[inline]
-            pub fn ceil(self) -> Self {
-                unsafe { crate::intrinsics::simd_ceil(self) }
+            pub fn round(self) -> Self {
+                unsafe { crate::intrinsics::simd_round(self) }
+            }
+
+            /// Returns the floating point's integer value, with its fractional part removed.
+            #[must_use = "method returns a new vector and does not mutate the original value"]
+            #[inline]
+            pub fn trunc(self) -> Self {
+                unsafe { crate::intrinsics::simd_trunc(self) }
+            }
+
+            /// Returns the floating point's fractional value, with its integer part removed.
+            #[must_use = "method returns a new vector and does not mutate the original value"]
+            #[inline]
+            pub fn fract(self) -> Self {
+                self - self.trunc()
             }
         }
 
diff --git a/crates/core_simd/tests/round.rs b/crates/core_simd/tests/round.rs
index dc9c8ad4ad2..85853c0e877 100644
--- a/crates/core_simd/tests/round.rs
+++ b/crates/core_simd/tests/round.rs
@@ -22,6 +22,30 @@ macro_rules! float_rounding_test {
                         &|_| true,
                     )
                 }
+
+                fn round<const LANES: usize>() {
+                    test_helpers::test_unary_elementwise(
+                        &Vector::<LANES>::round,
+                        &Scalar::round,
+                        &|_| true,
+                    )
+                }
+
+                fn trunc<const LANES: usize>() {
+                    test_helpers::test_unary_elementwise(
+                        &Vector::<LANES>::trunc,
+                        &Scalar::trunc,
+                        &|_| true,
+                    )
+                }
+
+                fn fract<const LANES: usize>() {
+                    test_helpers::test_unary_elementwise(
+                        &Vector::<LANES>::fract,
+                        &Scalar::fract,
+                        &|_| true,
+                    )
+                }
             }
 
             test_helpers::test_lanes! {