about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCaleb Zulawski <caleb.zulawski@gmail.com>2024-03-03 09:22:05 -0500
committerGitHub <noreply@github.com>2024-03-03 09:22:05 -0500
commiteea6f7799cef4cdccbcb6c379d37758fc5e4b2ac (patch)
tree7172290e196b51e00c785a26c6f3c35d4cbd3235
parentfbc9efa364db3cc17fa8c395dff06a3d704dad9c (diff)
parent499a53dd71aecfff2bf5863d509b8c21a6541841 (diff)
downloadrust-eea6f7799cef4cdccbcb6c379d37758fc5e4b2ac.tar.gz
rust-eea6f7799cef4cdccbcb6c379d37758fc5e4b2ac.zip
Merge pull request #400 from avhz/master
feat: add SIMD float math functions (exp, exp2, log, log2, log10, sin…
-rw-r--r--crates/std_float/src/lib.rs93
1 files changed, 90 insertions, 3 deletions
diff --git a/crates/std_float/src/lib.rs b/crates/std_float/src/lib.rs
index 4c547777fde..98f10e94a30 100644
--- a/crates/std_float/src/lib.rs
+++ b/crates/std_float/src/lib.rs
@@ -65,6 +65,62 @@ pub trait StdFloat: Sealed + Sized {
         unsafe { intrinsics::simd_fsqrt(self) }
     }
 
+    /// Produces a vector where every lane has the sine of the value
+    /// in the equivalently-indexed lane in `self`.
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original value"]
+    fn sin(self) -> Self {
+        unsafe { intrinsics::simd_fsin(self) }
+    }
+
+    /// Produces a vector where every lane has the cosine of the value
+    /// in the equivalently-indexed lane in `self`.
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original value"]
+    fn cos(self) -> Self {
+        unsafe { intrinsics::simd_fcos(self) }
+    }
+
+    /// Produces a vector where every lane has the exponential (base e) of the value
+    /// in the equivalently-indexed lane in `self`.
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original value"]
+    fn exp(self) -> Self {
+        unsafe { intrinsics::simd_fexp(self) }
+    }
+
+    /// Produces a vector where every lane has the exponential (base 2) of the value
+    /// in the equivalently-indexed lane in `self`.
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original value"]
+    fn exp2(self) -> Self {
+        unsafe { intrinsics::simd_fexp2(self) }
+    }
+
+    /// Produces a vector where every lane has the natural logarithm of the value
+    /// in the equivalently-indexed lane in `self`.
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original value"]
+    fn log(self) -> Self {
+        unsafe { intrinsics::simd_flog(self) }
+    }
+
+    /// Produces a vector where every lane has the base-2 logarithm of the value
+    /// in the equivalently-indexed lane in `self`.
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original value"]
+    fn log2(self) -> Self {
+        unsafe { intrinsics::simd_flog2(self) }
+    }
+
+    /// Produces a vector where every lane has the base-10 logarithm of the value
+    /// in the equivalently-indexed lane in `self`.
+    #[inline]
+    #[must_use = "method returns a new vector and does not mutate the original value"]
+    fn log10(self) -> Self {
+        unsafe { intrinsics::simd_flog10(self) }
+    }
+
     /// 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]
@@ -127,13 +183,36 @@ where
 }
 
 #[cfg(test)]
-mod tests {
+mod tests_simd_floats {
     use super::*;
     use simd::prelude::*;
 
     #[test]
-    fn everything_works() {
+    fn everything_works_f32() {
         let x = f32x4::from_array([0.1, 0.5, 0.6, -1.5]);
+
+        let x2 = x + x;
+        let _xc = x.ceil();
+        let _xf = x.floor();
+        let _xr = x.round();
+        let _xt = x.trunc();
+        let _xfma = x.mul_add(x, x);
+        let _xsqrt = x.sqrt();
+        let _abs_mul = x2.abs() * x2;
+
+        let _fexp = x.exp();
+        let _fexp2 = x.exp2();
+        let _flog = x.log();
+        let _flog2 = x.log2();
+        let _flog10 = x.log10();
+        let _fsin = x.sin();
+        let _fcos = x.cos();
+    }
+
+    #[test]
+    fn everything_works_f64() {
+        let x = f64x4::from_array([0.1, 0.5, 0.6, -1.5]);
+
         let x2 = x + x;
         let _xc = x.ceil();
         let _xf = x.floor();
@@ -141,6 +220,14 @@ mod tests {
         let _xt = x.trunc();
         let _xfma = x.mul_add(x, x);
         let _xsqrt = x.sqrt();
-        let _ = x2.abs() * x2;
+        let _abs_mul = x2.abs() * x2;
+
+        let _fexp = x.exp();
+        let _fexp2 = x.exp2();
+        let _flog = x.log();
+        let _flog2 = x.log2();
+        let _flog10 = x.log10();
+        let _fsin = x.sin();
+        let _fcos = x.cos();
     }
 }